只是简单介绍一下,这些是我的列标题
TableName:process_detail
id, process_id, item_id, item_category, attribute1,attribute2,attribute3,...,attribute500,user_id1_update_time,user_id2_update_time,user_id1_comments,user_id2_comments
所有属性都是varchar,长度最大为30.但小于30。
我有25个item_categories。
我应该创建一个像'process_detail'这样的单个表,还是应该按类别创建多个表,如category1_process_detail,category2_process_detail,..,category25_process_detail
每个item_category有不同的列数,有些列有200列,有些列只有50列。假设category1将有200列,category2将有50列。
category1中的某些列不属于category2。
process_id1中的item_ids可能位于process_id2中。在良好的表现方面,最好的方法是什么?请adivce。
答案 0 :(得分:1)
不,这不是一个好主意。而是使用多对一关系映射。
例如,按照您的建议创建process_detail
表,但不包含属性列。然后创建另一个表process_detail_attributes
CREATE TABLE `process_detail_attributes`
(`pda_id` INT NOT NULL AUTO_INCREMENT,
`id` INT NOT NULL,
`attribute_key` INT NOT NULL,
`attribute_value` VARCHAR(30) NOT NULL,
PRIMARY KEY(`pda_id`),
FOREIGN KEY (id) REFERENCES process_detail (id)
) ENGINE...
然后对于每个属性(attribute1...attribute500
),只需在属性表中输入一行,并在外键列中插入相应的id。
这样做的好处很多。 Doomenik提到的链接可能是理解其中的一个很好的起点,但简而言之......
- 如果没有使用所有属性,就不会浪费存储空间 - 即使使用了属性,数据也将存储在实际的索引B-Tree节点中,过度膨胀每页数据量并减少能够适应缓冲池(即RAM)的页面数量并减少钥匙的位置。这将随后减慢索引遍历的速度 - 如果这些属性需要索引(通常这些属性),那么这个表的不灵活将是不合情理的。
当然,为了提高性能,你可以考虑去标准化,但这似乎不是其中之一。
然后,您可以从process_detail中选择包含所有属性的数据,如下所示:
SELECT a.process_id,
a.user_id1_update_time,
a.user_id2_update_time,
a.user_id1_comments,
a.user_id2_comments,
b.*
FROM process_detail a INNER JOIN process_detail_attributes b
WHERE a.id = b.id AND whatever_condition_you_want_to_filter_by_here;
答案 1 :(得分:0)
InnoDB不支持500 varchar列,因为存储了行的方式。即使您使用InnoDB的ROW_FORMAT=DYNAMIC
,这将为varchars每行存储500x20字节,这将大于8KB行大小限制。有关InnoDB行存储的详细信息,请参阅https://www.percona.com/blog/2010/02/09/blob-storage-in-innodb/。
拥有如此大量的列无论如何都是有问题的数据库设计的红旗。
如果您为类似属性存储了大量列,则违反了eliminating Repeating Groups of columns的原则,这是使表格满足第一范式的一部分。
如果列不是类似的属性,那么您根本就不是设计关系。在关系中,您必须使用有意义的列名和数据类型定义标题。当您将列命名为attribute1
等时,您并不是以关系方式设计表格。
我不同意使用EAV表设计的建议。我经常在Stack Overflow或我的博客EAV FAIL上发布关于EAV是关系数据库的破坏设计的事实。
请参阅我对https://stackoverflow.com/a/695860/20860或我的演示文稿Extensible Data Modeling的回答,了解为不同流程类型存储不同属性的任务的替代解决方案。
您可能希望了解如何使用MySQL 5.7中的JSON data type来存储特定于每种不同流程类型的半结构化属性集合。