2009-10-29 62 views
1

目前的情況是,主題按3個主要類別排序。有可能增加的不僅僅是3個類別,而是更高層希望實現爲一個主題添加不止1個類別的能力。我應該創建另一個表還是僅使用數組? (規範化或不規範化)

我的原始數據庫設計在主題信息表中具有categoryID作爲外鍵。從一開始,這可能是一個糟糕的主意,但我想他們只設置了3個類別,並且這樣做會減少查詢次數。

因此,從我所看到的我現在有兩個選項: 1)輸入categoryID作爲一個逗號分隔的字符串,我解析的PHP結束。 2)重新構造數據庫並將categoryID拉出到它自己的categoryID和topicID表中。

我想知道每個人都認爲這是什麼。我的第一本能是重組數據庫。但是當我考慮這個問題時,第一個選擇是實現最簡單,並且最不可能通過改變數據庫來打破現有的問題。這也可能導致不規範化,並且會導致數據不一致的可能性。

我已經閱讀了解除歸一化問題,只要您接受以不一致的數據換取性能的風險即可。在您看來,我會因此風險而獲得很多業績嗎?對於我在這種情況下應該做的任何投入將不勝感激。

感謝您的幫助,
列維

回答

3

不要混淆非規範化(一個很好的例子,其中與問題保持在SO問題的表決票數一起,而不是從「票」表中的每個時間計算它)與可憎的是逗號分隔的ID列表。

建立適當的多對多關係;用逗號分隔的方法可能(並且會)出錯的東西太多了。僅舉幾例:

  1. 沒有參照完整性。
  2. 接下來無法在連接中使用。
  3. 不可能充分索引;非可擴展性。
+0

所有的優點,你的第三個關於是不可擴展的是我最初用我的數據庫設計進入這個問題。 – Levi 2009-10-29 03:03:03

+0

+1此外,執行各種聚合查詢更困難,例如對列表中的值進行計數,求和或平均。 – 2009-10-29 03:03:04

0

你最好的選擇就是像你說的那樣有一個類別ID-topicID對的數據庫來查找這些主題屬於哪個類別。

你可以通過以類別ID分解字符串的方式來做到這一點,但是當你搜索某個類別中的任何主題時,你必須遍歷每個字段並在其上運行一個LIKE ...更多的資源密集型。

花時間重組數據庫,最終得到更好的結果。

0

如果您需要在單個項目的DBMS中執行某些操作,請執行而不是以列表形式存儲它們。這會讓你的查詢像狗一樣運行,因爲你的表變得更大。當然,如果你只是將這個列表當作一個單元來對待,那麼以這種方式來存儲它們也是可以的。

但是你最好確定你會一直把列表作爲一個單元來處理,而不是作弊,說他們是一個單元,然後將它們分散到別處 - 最好讓DBMS做到這一點您。

你應該總是先做3NF然後如果,並且只有當你有性能問題時,纔會使速度變得非規範化。

你在這個問題上談論的那些領域並不是你將作爲一個單位來對待的那種領域。您需要對列表中的各個元素執行操作,因此應該將其分解到另一個表格中。

+0

好吧,我打算把它分解成另一張桌子,聽起來像我在路上會有更少的錯誤。 只是好奇,是一個列表視爲一個單元只有當它將被顯示爲是?所以如果我有'蘋果,桔子,香蕉,獼猴桃',我用它輸出'我喜歡蘋果,橘子,香蕉,獼猴桃'。這很好嗎? 1.4.3本, 「我喜歡: -apples -kiwis -bananas -oranges 」 將是一個不錯的主意,但因爲我將不得不採取的字符串,並把它分解開的順序來顯示呢? 有沒有一個真實世界的例子,你可以考慮使用列表作爲一個單元? – Levi 2009-10-29 03:41:16

+0

是的,沒關係。如果您只是按原樣將其拉出,而不是操縱它,則可以像那樣存儲它。這是因爲DBMS或您的程序沒有額外的工作來處理它。在這種情況下,它實際上*更好*這樣做,因爲它比將單個列重新組合爲字符串更快:-) – paxdiablo 2009-10-29 03:56:36

+0

真實世界的例子?如何在約會網站上列出你的興趣(這可能是*任何*因此可能無法用作查找表)。你可能會進入「在海灘散步,Java開發和酷刑設備從16世紀」,這將被展示給未來的候選人(然後,他們會誠實地說,可能會像地獄一樣)。 – paxdiablo 2009-10-29 04:11:12