-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存儲特定於每個不同的工藝類型的屬性的半結構化集合。

相關問題