2012-03-19 87 views
73

所以這是更多的設計問題。我有一個主鍵說用戶的ID,我有大量的信息與該用戶相關聯。我很關心應該根據信息將多個表分成不同的類別,還是應該只有一個包含許多列的表?MySQL:多個表或一個表與許多列?

我以前做這件事的方式是擁有多個表格,比如說一個表格用於應用程序使用數據,一個表格用於配置文件信息,另一個用於後端令牌表格等,以使事物看起來有組織。最近有人告訴我最好不要這樣做,並且有一張有許多色譜柱的桌子是好的。所有這些列都有相同的主鍵。

我對數據庫設計相當陌生,所以哪種方法更好,有哪些優缺點?傳統的做法是什麼?

+0

爲了清楚起見,糾正我,如果我錯了,但我認爲「多個表」可以理解爲鏈接/關聯表:https://en.wikipedia.org/wiki/Associative_entity – cellepo 2016-09-28 16:10:33

回答

69

任何時間信息都是一對一的(每個用戶都有一個名稱和密碼),那麼最好將它放在一張表中,因爲它減少了數據庫檢索結果所需的連接數。我認爲有些數據庫對每個表的列數有限制,但在正常情況下我不擔心,如果需要的話,您可以隨後再分割它。

如果數據是一對多的(每個用戶有數千行的使用信息),那麼它應該拆分成單獨的表以減少重複數據(重複的數據會浪費存儲空間,緩存空間並使數據庫難以維護)。

您可能會發現在database normalization有趣維基百科的文章,因爲它深入討論了其中的原因:

數據庫標準化是組織一個關係型數據庫的字段和表以減少冗餘和依賴的過程。規範化通常涉及將大型表分成更小(更少冗餘)的表並定義它們之間的關係。其目標是隔離數據,以便可以在一個表中添加,刪除和修改字段,然後通過定義的關係通過數據庫的其餘部分進行傳播。

Denormalization也是一個需要注意的,因爲有這樣的情況重複數據更好(因爲它減少了數據庫需要讀取數據時做的工作量)。我強烈建議儘可能使數據儘可能標準化,並且只有在知道特定查詢中出現性能問題時才進行規範化處理。

+0

感謝你的回答,所以在閱讀之後,我想我所說的是那個當一個用戶有許多一對一的信息欄時, – 2012-03-19 17:29:41

+0

@Xavier_Ex - 是的,如果每個用戶只有一列,那麼只有一個龐大的用戶表將更容易處理(並且DB引擎優化更容易)。 – 2012-03-19 17:34:55

+0

您編輯的文章提供了更多有用的信息!我有一個新的擔心,如果某些列會經常更新,我應該把它們放在一個單獨的表中嗎?例如,用戶的出生日期不會永遠更新,但後端令牌可能會在一段時間後失效並需要頻繁更新。如果我以這種方式分開表格以改善性能,會更好嗎?我現在去讀你提到的維基:) – 2012-03-19 17:45:35

0

這樣做的常規方法是使用與星型模式或雪花模式不同的表格。 Howeevr,我會基於這個策略是兩倍。我相信數據應該只存在於一個地方的理論,因爲我提到的模式會很好。不過,我也相信,對於報表引擎和商務智能套件,列式方法將非常有益,因爲它更加支持報表需求。類似於infobright.org的列式方法具有巨大的性能提升和壓縮,使得使用這兩種方法都非常有用。許多公司開始意識到,組織中只有一個數據庫架構不支持其全部需求。許多公司正在實施具有多個數據庫架構的概念。

+0

感謝您的信息,但對不起,我不太明白你的答案......我會先對你提到的兩個模式進行搜索...... – 2012-03-19 17:39:40

3

問問自己這些問題,如果你把所有東西放在一張表中,你會爲這個用戶多行嗎?如果您必須更新用戶,您是否希望保留審計線索?用戶可以有多個數據元素的實例嗎? (比如電話號碼),您是否會遇到一種情況,您可能希望稍後添加一個元素或一組元素? 如果你回答是,那麼很可能你想要有外鍵關係的子表。

父/子表的優點是數據完整性,通過索引進行性能測試(是的,你也可以在平板上進行測試),如果以後需要添加字段,IMO更容易維護,特別是如果它是必需的領域。

缺點的設計是很難,查詢變得稍微複雜

但是,有很多情況下,所以你要看看你的情況來決定一個大的平表將是適當的。

+0

謝謝你提醒我!所以在我的情況下,我只考慮了每個用戶不能有多於一行的情況,因此所有的信息字段都是一對一的。此外,用戶不能擁有同一元素的多個實例,因爲我相信一個元素的概念不能存在於多個地方。對於第三個問題,是的,我可能會添加更多的元素到表中,但他們不會違反我上面提到的要求。當我想將多行關聯到一個用戶時,我認爲父/子表是好的,但在這種情況下,我擔心用戶有許多一對一的列。 – 2012-03-19 17:37:34

+0

,即使所有元素當前都是一對一的,這並不排除需要或希望擁有父/子表IMO。保持更改數據的日誌只有一個用處。延遲加載對象是另一個。雖然單一表格結構有好處,但對父母的孩子佈局也有好處(儘管我也看到人們也對此極爲喜歡)。 – Brian 2012-03-19 18:16:30

10

一張大桌子往往是一個糟糕的選擇。相關的表格是關係數據庫設計用來處理的。如果您正確編制索引並知道如何編寫高性能查詢,它們將會正常工作。

當表格的列數太多時,可能會遇到數據庫存儲信息的實際頁面大小問題。要麼這個記錄最終可能對於頁面來說太大了,你最終可能不能創建或更新一個讓用戶不快樂的特定記錄,或者你可能(至少在SQL Server中)允許某些特定的溢出數據類型(有一組規則,如果你這樣做,你需要查找規則),但是如果很多記錄會溢出頁面大小,你可能會產生性能問題。現在MYSQL如何處理這些頁面,以及在潛在頁面大小變得太大時是否遇到問題,您必須在該數據庫的文檔中查找。

+1

啊不同的聲音!這總是很棒。感謝您的信息!當我製作我的桌子時,我會確保我知道這一點......但我不知道我最初必須意識到這種低級別的東西。 – 2012-03-19 19:45:47

1

我已經完成某種數據庫設計。對我來說,這取決於數據庫管理系統的難度;是的,只有在一個地方纔有獨特的數據是真實的,但是要用大量記錄過度標準化的數據庫進行查詢確實很困難。只要結合這兩種模式;如果您覺得自己會擁有難以維護的大量記錄,就像使用Facebook,Gmail等一樣,請使用一張巨大的表格。並使用不同的表爲一套簡單的系統記錄...以及這只是我的意見..我希望它可以幫助..只是做它..你可以做到這一點... :)

2

我有一個很好的例子。以下一組關係過於規範化的數據庫:

people -> rel_p2staff -> staff 

people -> rel_p2prosp -> prospects 

那裏的人們有姓名和個人信息,工作人員剛剛員工記錄的詳細信息,前景剛剛前景的細節,以及相對錶格是與員工和潛在客戶鏈接的外鍵的關係表。

這種設計爲整個數據庫進行。

現在要查詢這組關係,它每次都是一個多表連接,有時會有8個以上的表連接。到今年中期,它一直工作得很好,現在開始變得非常緩慢,現在我們已經超過了40000人的記錄。

索引和所有低掛水果去年都用完了,所有查詢都進行了優化以達到完美。對於特定的標準化設計和管理來說,這是最終的結果,現在批准在整個6個月的時間內重建依賴於它的整個應用程序以及重新構建數據庫。 $$$$ Ouch。

該解決方案將是對people -> staff和直接關係people -> prospect

+0

想了解重建過程如何?你最終設計了類似於單一表繼承的東西嗎?你的'type'是'staff'還是'prospect'? – Coderama 2017-04-19 00:30:46

+0

與人直接聯繫 - >員工與人 - >展望,發揮魅力,易用,快速查詢。 – Vlad 2017-04-20 01:22:30

-1

我認爲有一個表更有效,但是,你應該確保該表的方式組織,它顯示的關係,趨勢以及同一行變量的差異。 例如,如果表格顯示學生的年齡和成績,您應該以感謝最高得分者的方式與最低得分者區分開來,並且學生的年齡差異是均勻的。