设计用于存储列表的数据库

eiee3dmh  于 2021-06-20  发布在  Mysql
关注(0)|答案(1)|浏览(347)

我为列名和表名的模糊性道歉。我的数据库有两个表a和b。这些表之间存在多对多关系。
表a有大约200条记录

Table A structure
Id.   Definition
12    Def1
42    Def2 .... etc.

表b有大约50亿条记录

Column 1 .   Associated Id(from table A)
eg . abc      12
     abc      21
     pqr      42

我试图优化表b中存储数据的方式,因为它有很多冗余数据。我想的结构如下

Column 1        Associated Ids
abc             12, 21
pqr             42

“associated id”列可以在向表a添加新行时进行更新。
在这个场景中,这是一个好的结构吗?如果是,“关联id”的列类型应该是什么?我正在使用mysql数据库。
创建表语句。

CREATE TABLE `A` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `title` varchar(100) DEFAULT NULL,
  `name` varchar(100) DEFAULT NULL,
  `creat_usr_id` varchar(20) NOT NULL,
  `creat_ts` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  `modfd_usr_id` varchar(20) DEFAULT NULL,
  `modfd_ts` timestamp NULL DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP,
  PRIMARY KEY (`id`),
  UNIQUE KEY `A_ak1` (`name`)
) ENGINE=InnoDB AUTO_INCREMENT=277 DEFAULT CHARSET=utf8;

CREATE TABLE `B`(
  `col1` varchar(128) NOT NULL,
  `id` int(11) NOT NULL,
  `added_dt` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  `creat_usr_id` varchar(20) NOT NULL,
  `creat_ts` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  PRIMARY KEY (`col1`,`id`,`added_dt`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
/*!50100 PARTITION BY RANGE (UNIX_TIMESTAMP(added_dt))
(PARTITION Lessthan_2016 VALUES LESS THAN (1451606400) ENGINE = InnoDB,
 PARTITION L`Ω`essthan_201603 VALUES LESS THAN (1456790400) ENGINE = InnoDB,
 PARTITION Lessthan_201605 VALUES LESS THAN (1462060800) ENGINE = InnoDB,
 PARTITION Lessthan_201607 VALUES LESS THAN (1467331200) ENGINE = InnoDB,
 PARTITION Lessthan_201609 VALUES LESS THAN (1472688000) ENGINE = InnoDB,
 PARTITION Lessthan_201611 VALUES LESS THAN (1477958400) ENGINE = InnoDB,
 PARTITION Lessthan_201701 VALUES LESS THAN (1483228800) ENGINE = InnoDB,
 PARTITION pfuture VALUES LESS THAN MAXVALUE ENGINE = InnoDB) */;

索引。

Table Non_unique  Key_name    Seq_in_index    Column_name Collation   Cardinality Sub_part    Packed  Index_type  Comment Index_comment
    B          0        PRIMARY         1             col1        A        
 2             NULL       NULL      BTREE       
    B          0        PRIMARY         2              id         A        
 6             NULL       NULL      BTREE       
    B          0         PRIMARY        3             added_dt    A        
 6             NULL       NULL      BTREE
wswtfjt7

wswtfjt71#

这里有50亿排。让我来看看: col1 varchar(128)不为空,
这个专栏多长时间重复一次?也就是说,让它正常化值得吗? id int(11)不为空,
将此列的大小减半(4字节->2),因为只有200个不同的ID:

a_id SMALLINT UNSIGNED NOT NULL

取值范围:0..65535 added_dt timestamp not null默认当前\u时间戳,
请解释为什么这是pk的一部分。那是一件很奇怪的事。 creat_usr_id varchar(20)不为空, creat_ts timestamp not null默认当前\u时间戳,
把这些当作杂乱无章的东西扔掉,除非你有理由这样跟踪50亿个行动。
主键( col1 , id , added_dt )
我敢打赌你最终会在同一秒钟内得到两排。pk是“唯一的”。也许你只需要 (col ,一个身份证)?否则,您将允许多次添加col-a\u id对。或者你想添加一个新行而不是更新时间戳? 分区。。。 如果(可能仅当)您打算删除“旧”行,这将非常有用。否则请解释你为什么选择分区。 在没有看到主要内容的情况下审查模式是很困难的SELECTs. 在大表的情况下,我们还应该检查INSERTs,UPDATEs,和DELETEs` ,因为它们都可能带来严重的性能问题。
以每秒插入100行计算,要增加50亿行需要一年多的时间。排得多快?这可能也是一个重要的性能问题。

相关问题