2010-09-20 178 views
2

假設我需要將T恤和牛仔褲放在我的產品表中。他們分享成本,價格,數量等欄目,但腰圍(僅適用於牛仔褲)和尺寸(僅適用於T恤)。我應該把它們放在一張桌子還是分開的桌子上?如果我把它們放在一起,我會有很多空值,但是如果我將它們分開,鏈接它們的最佳方式是什麼?需要數據庫設計幫助

非常感謝。

回答

2

你可以有一個products_attributes表,其中可能5大小可能是8(取決於它如何設置)。這也使您可以在將來輕鬆添加新屬性(或者甚至可以讓最終用戶添加新屬性)。

然後你可以有像列

| attribute_id | value | product_id | 
===================================== 
| 5   | "30cm"| 28   | 
===================================== 
+0

擊敗我1秒!該死的快速證明閱讀! :) – PostMan 2010-09-20 01:27:42

+0

@PostMan哈哈,這一直髮生在我身上! – alex 2010-09-20 01:28:56

+0

但是,所有的值將被存儲在字符串中。你不覺得在搜索和排序方面效率不高嗎? – Dreteh 2010-09-20 01:33:58

1

你可以添加一個產品屬性表,這將是一個產品的許多屬性。

每個屬性都將有一個類型的和值,這將解決您的問題:)

+0

看到我下面的評論@ alex的答案。它會工作,但只會在所有'屬性'是相同數據類型時纔有效。 – RPM1984 2010-09-20 01:49:53

2

我會去用下面的:

產品

ProductID INT IDENTITY, 
Cost DECIMAL(4,2), 
Price DECIMAL(4,2), 
Quantity INT 

ProductID INT, 
Waist INT 

襯衫

ProductID INT, 
Size INT 

然後,您可以在產品ID吉恩/襯衫表的外鍵上的產品ProductID列。

這樣,你就是延伸的核心產品屬性,以適應更具體的產品。更重要的是,您可以添加更多特定的產品(新表格),而不會影響現有產品或產品表格架構。

我們目前正在實現一個類似的結構,以便我們的應用程序ORM可以支持實體的「繼承」。

爲了讓牛仔褲,您的查詢將是:

SELECT Product.ProductID, Product.Cost, Product.Price, Product.Quantity, Jean.Waist 
FROM Product Product 
INNER JOIN Jean Jean 
ON Product.ProductID = Jean.ProductID 

當然,如果你正在尋找一個簡單的變化,下面的答案將被罰款。

但是,這是'未來證明'你的數據庫未來的產品增加。

HTH

+0

這也是我腦海中的想法。只是想確保這是最好的解決方案。謝謝。 – Dreteh 2010-09-20 01:36:02

+0

這是「泛化專業化關係建模」的標準答案。我看起來很好。 – 2010-09-20 10:25:46

3

有幾種方法可以解決這個問題。

您已經描述了一個,single-table inheritence(其中有一堆空列用於不相關的屬性)。

RPM1984的回答暗示class-table inhertience,其中共享數據放在主表中,每個「類型」都會爲其他屬性獲取自己的表。

或者,您可以有Entity/Attribute/Value,正如亞歷克斯和郵遞員所建議的那樣。

每種方法都有優點和缺點。最大的問題是,RDMBSes很難對它們中的任何一個強制執行參照完整性。

在作出決定之前,請務必仔細考慮您的問題。 EAV提供了最大的靈活性(您可以分配任意屬性,並且不需要更改模式),但最終會在應用程序層中執行大量處理。而且,您無法輕鬆獲得具有所有屬性的單個結果行。

如果我確定我知道我需要建模的每一個「類型」,並且我將來可能不需要創建更多類型,那麼我會使用類表繼承。

對於類表繼承,例如,可以使用簡單的內連接(select * from products inner join pants)僅按類型進行篩選。

+0

感謝您的詳細解釋。我更喜歡類表繼承。 – Dreteh 2010-09-20 03:48:48