-1

在MySQL中,在一个表中有500列是否很好? 行将每天增加,最大行数将小于或等于100万。,在一个表中有500列是否很好?

只给一个简短的,这些都是我的列标题

表名: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”,或者我应该创建多个表categorywise像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。

+1

我建议你阅读本:http://www.studytonight.com/dbms/database-normalization.php – Doomenik

+0

你应该实现EAV实体附加值像 processDetails(ID,PROCESS_ID,ITEM_ID,item_category) 属性(ID,标题) processToAttributes(ID,PROCESS_ID,attribute_id,ATTRIBUTE_VALUE) 所以在这种方式,将相对于标准化水平得到优化3 –

+0

@NaveedRamzan,谢谢,但属性在application.we编辑字段不能让它们在属性表中预定义。 – davidb

回答

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_u‌​pdate_time, 
a.user_id2_u‌​pdate_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; 
+0

感谢,'process_detail_attributes'表将具有的属性排明智的,与外键(ID),这是该表的主键'process_detail',当我要选择和显示的属性是这样的'PROCESS_ID,ITEM_ID,item_category, ATTRIBUTE1,attribute2,attribute3,...,attribute500,user_id1_update_time,user_id2_update_time,user_id1_comments,user_id2_comments',我该怎么办呢?这就是它在前端应用程序中对用户的看法。 – davidb

+0

为user_id_comments等创建一个类似'process_detail_attributes'的表可能是合适的......我将编辑我的答案,并为您选择的要求提供一个示例,然后可以对user_id_comments或其他任何表进行嘲弄你决定从你最初的单体process_detail表中提取。 – MarCPlusPlus

+0

,如果查询返回'PROCESS_ID,ITEM_ID,item_category,ATTRIBUTE1,attribute500,user_id1_u pdate_time,user_id2_ UPDATE_TIME,user_id1 _comments,user_id2_c omments'然后process_detail_attributes表应该是这样的'CREATE TABLE'process_detail_attributes' ( 'pda_id' INT NOT NULL AUTO_INCREMENT, 'id' INT NOT NULL, 'attribute1' VARCHAR(30)NOT NULL, 'attribute2' VARCHAR(30)NOT NULL, 'attribute3' VARCHAR(30)NOT NULL, (attribute)500' VARCHAR(30)NOT NULL, PRIMARY KEY('pda_id'), FOREIGN KEY(id)REFERENCES process_detail(id) )ENGINE..'? – davidb

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存储特定于每个不同的工艺类型的属性的半结构化集合。

相关问题