2013-01-19 42 views
1

在MySQL中,如果我有一個永遠不會改變的有限數量的categories,我應該將它們創建爲它們分類的表中的bool字段,還是應該使用映射表?如果是這樣,爲什麼?何時使用映射表


例A:

t_stuff

id (int) 
name (string) 
category_a (bool) 
category_b (bool) 
category_c (bool) 
category_d (bool) 
category_e (bool) 
category_f (bool) 

情況B:

t_stuff

id (int) 
name (string) 

t_categories

id (int) 
name (string) 

t_stuff_category

id (int) 
stuff_id (int) 
category_id (int) 

雖然一個看起來並不 「好看」 爲B,它似乎在查詢方面簡單了很多需要?

編輯:我覺得我應該補充一點,我曾經需要做的是:

  • 獲取所有的東西行
  • 取得具有一個特定的類別
  • 得到一個東西的所有東西行具有特定編號的行

回答

3

永不使用案例A。它違反了關係數據庫的原則。瞭解有關normalization

比方說,你想找到idcategory = 1,您需要在情況A檢查每一列:

SELECT id 
FROM t_stuff 
WHERE category_a = 1 
     OR category_b = 1 
     OR category_c = 1 
     OR category_d = 1 
     OR category_e = 1 
     OR category_f = 1 

這種設計不僅使其難以查詢,但它也有聚集的噩夢。如果您想要獲得特定idCOUNT(*)類別,該怎麼辦?

萬一B,你只查詢單個屬性:

SELECT stuff_id 
FROM stuffCategory 
WHERE category_id = 1 

要獲得COUNT(*),您只需更換id

此外,根據t_stuff_category您不需要id。一個複合主鍵(stuff_id, category_id)就足夠了。

+0

您的情況B查詢似乎不符合設計。另外,我從來不想找到你提到的情況A.我要麼需要所有的行,要麼所有的行都有一個特定的類別。 – Ben

+0

@Ben希望有幫助。 – Kermit

+0

關於使用複合主鍵,請確保在創建表時創建唯一索引/約束。如果意外地結束了重複行,並且沒有自動遞增鍵,刪除重複項可能非常煩瑣。 – IMSoP

1

這裏最重要的是「永不說永不」 - 在問題和意見,你的狀態充滿信心地說:

  • 類別的數量(和含蓄,意)將從未變化
  • 你將永遠需要查詢之類的東西「有多少種類是項X在」

需求隨時間變化,並設計一個系統根據預測,有些事情會發生從未可能會導致以後的挫折,因爲你必須解決設計中的限制。當然,只有當你有非常少量的「類別」(我會說< = 3),這樣你才能夠使用非標準化版本(只有布爾列)把它們當作「屬性」,而不是「類別」:

  1. 搜索A類或B類產品全部是稍微容易些,因爲你不必擔心,如果在JOIN條款的效力產品是在兩個。
  2. 有些查詢比較簡單,因爲您不需要擔心JOIN子句。

這裏有一些東西,你可以用一個標準化的設計,而不是一組布爾列做:

  1. 簡單地計算一個產品有多少種類是,使用SQL COUNT()
  2. 將關於類別本身的信息存儲在您的數據庫中,而不是將其隱藏在應用程序代碼中的某處。與您的選項B模式中建議的名稱列一樣,您可能需要更長的描述或標記以顯示該類別的時間等。
  3. 添加,刪除或重命名類別,而不必觸摸你的應用程序的代碼。

同樣,你可能不希望做任何這些東西現在,但除非你打算在一週的時間內丟掉的應用,你無法預測未來的需求。軟件設計的很大一部分是關於使代碼可維護並在簡單性和靈活性之間進行合理折中。

+0

是的,沒錯,我從來不需要做兩點要點。這是提出優化問題的關鍵。如果這可能會發生變化,那麼顯然我將不得不去做案例B.我不需要做1或2或3(即使2會顯得很「好」)。 – Ben

+0

我相信你會同意有些東西不會改變,比如rgb顏色系統中的r,g和b。這些可能是我的「類別」,只給出一個例子(不是最好的)。我認爲你是對的,但是把它們命名爲「屬性」而不是「類別」可能會使它更容易理解。 – Ben

+0

這是迄今爲止唯一的迴應,實際上處理我的問題,所以+1。 – Ben