假設我需要將T恤和牛仔褲放在我的產品表中。他們分享成本,價格,數量等欄目,但腰圍(僅適用於牛仔褲)和尺寸(僅適用於T恤)。我應該把它們放在一張桌子還是分開的桌子上?如果我把它們放在一起,我會有很多空值,但是如果我將它們分開,鏈接它們的最佳方式是什麼?需要數據庫設計幫助
非常感謝。
假設我需要將T恤和牛仔褲放在我的產品表中。他們分享成本,價格,數量等欄目,但腰圍(僅適用於牛仔褲)和尺寸(僅適用於T恤)。我應該把它們放在一張桌子還是分開的桌子上?如果我把它們放在一起,我會有很多空值,但是如果我將它們分開,鏈接它們的最佳方式是什麼?需要數據庫設計幫助
非常感謝。
你可以有一個products_attributes
表,其中腰可能5
和大小可能是8
(取決於它如何設置)。這也使您可以在將來輕鬆添加新屬性(或者甚至可以讓最終用戶添加新屬性)。
然後你可以有像列
| attribute_id | value | product_id |
=====================================
| 5 | "30cm"| 28 |
=====================================
你可以添加一個產品屬性表,這將是一個產品的許多屬性。
每個屬性都將有一個類型的和值,這將解決您的問題:)
看到我下面的評論@ alex的答案。它會工作,但只會在所有'屬性'是相同數據類型時纔有效。 – RPM1984 2010-09-20 01:49:53
我會去用下面的:
產品
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
這也是我腦海中的想法。只是想確保這是最好的解決方案。謝謝。 – Dreteh 2010-09-20 01:36:02
這是「泛化專業化關係建模」的標準答案。我看起來很好。 – 2010-09-20 10:25:46
有幾種方法可以解決這個問題。
您已經描述了一個,single-table inheritence(其中有一堆空列用於不相關的屬性)。
RPM1984的回答暗示class-table inhertience,其中共享數據放在主表中,每個「類型」都會爲其他屬性獲取自己的表。
或者,您可以有Entity/Attribute/Value,正如亞歷克斯和郵遞員所建議的那樣。
每種方法都有優點和缺點。最大的問題是,RDMBSes很難對它們中的任何一個強制執行參照完整性。
在作出決定之前,請務必仔細考慮您的問題。 EAV提供了最大的靈活性(您可以分配任意屬性,並且不需要更改模式),但最終會在應用程序層中執行大量處理。而且,您無法輕鬆獲得具有所有屬性的單個結果行。
如果我確定我知道我需要建模的每一個「類型」,並且我將來可能不需要創建更多類型,那麼我會使用類表繼承。
對於類表繼承,例如,可以使用簡單的內連接(select * from products inner join pants
)僅按類型進行篩選。
感謝您的詳細解釋。我更喜歡類表繼承。 – Dreteh 2010-09-20 03:48:48
擊敗我1秒!該死的快速證明閱讀! :) – PostMan 2010-09-20 01:27:42
@PostMan哈哈,這一直髮生在我身上! – alex 2010-09-20 01:28:56
但是,所有的值將被存儲在字符串中。你不覺得在搜索和排序方面效率不高嗎? – Dreteh 2010-09-20 01:33:58