2012-02-27 50 views
0

比方說,我有一個ProductProductType表。我想要一個表格,可以爲每種產品類型存儲特殊列。特殊列(屬性)可以是任何類型。Sql Table dynamic cell typ

現在我們有一個表,每ProductTypeProduct_%ProductTypeId%這是我真的不喜歡的解決方案 - 有什麼建議嗎?

我的想法是有一個表ProductTypeColumns用的cols:

Id | ProductTypeId | ColumnName | Value | ColumnType 

什麼,我不喜歡這個就是我失去的類型安全,列Value將是一個字符串類型,這意味着我必須始終轉換爲和從。

此表格將用於生成報告..具有「動態」列可能是一個問題。

+1

EAV通常是這樣做的一種方式,特別是如果這些屬性對於很多產品可能會有所不同,並且它們可以頻繁地添加到新產品中。我在這裏發佈了關於EAV的博客:http://sqlblog.com/blogs/aaron_bertrand/archive/2009/11/19/what-is-so-bad-about-eav-anyway.aspx – 2012-02-27 20:06:35

回答

1

這就是所謂的EAV
您可以找到有關EAV和SQL Server的一些問題在這裏SO:

這是一個主題,其中很多不同的人會有不同的看法。
有人會說,你應該Product_%ProductTypeId%表貼,有的會說,你ProductTypeColumns表是更好的辦法。

基本上,我在ProductTypeColumns陣營。
我們在工作中也使用類似的東西:
我們的表格包含訂單商品的屬性(超過一百萬個訂單商品和超過2.5億個屬性),我們現在使用它近十年。
缺點:無類型安全(因爲你已經提到)和querying can be a bit complicated

但對於我們來說,這是唯一可能的方式,因爲我們擁有超過1000個屬性,超過100個產品,每個產品可以具有100到300個屬性。像這樣的維度,屬性表是唯一可行的方法。
但它可能不是每個人的最佳解決方案,我不知道它是否是最適合您的解決方案。

如果您的產品數量和特殊屬性不是那麼大,也許您可​​以跳過您的第一個建議(Product_%ProductTypeId%表)。
這肯定會更容易查詢,但如果產品和屬性的可能組合太多,也許這不是一個選項。

通常情況下,這取決於。

+0

或者組合 - 可能有一些更重要的屬性是許多產品(尺寸,顏色,價格等),可以在一個相關的表中,其餘的在EAV中。 – HLGEM 2012-02-27 22:26:12

+0

我也擔心會有多難查詢..查詢將是非常複雜的正常情況下,增加這個額外的層..可能是矯枉過正 – Zapacila 2012-02-28 09:33:27

+0

@Zapacila:只要你習慣了它並不複雜。關於查詢,請務必查看[我的答案中的此鏈接](http://stackoverflow.com/a/231681/6884)和[Aaron Bertrand的優秀文章](http://sqlblog.com/blogs/aaron_bertrand/ archive/2009/11/19/what-is-so-bad-about-eav-anyway.aspx),他在上面的評論中將其鏈接起來。 – 2012-02-28 10:19:53

1

類別層次結構(又名「繼承」,「子類型」,「子類」)如何?

enter image description here

我會親自去同一個名稱/值對溶液(在你的問題中所述)只有在列預先確定的。

如果您事先知道所有列並且它們不太可能發生變化,那麼實施類別層次結構while not without complications將保持類型安全性,並更好地實現DBMS聲明性完整性(例如,您可以具有特定產品一個唯一的,FOREIGN KEY或CHECK約束)。

+0

我希望你不是暗示EAV中不能有安全類型。 – 2012-02-27 20:57:07

+0

@AaronBertrand我暗示你不能通過聲明性完整性約束在DBMS級別強制執行類型安全。如果我錯了,那麼我不會介意在這個話題上受到啓發;) – 2012-02-27 21:14:11

+1

那麼,EAV並不一定意味着'SQL_VARIANT'。如果您閱讀了我的文章(鏈接上面),我將展示如何獲取不同數據類型的值,您可以在其中放置隨機字符串,並在其中預期日期時間屬性值。檢查約束也可能用於特定屬性,例如'CHECK(AttributeID = x AND ISDATE(y)= 1)或(AttributeID <> x)'。 – 2012-02-27 21:33:26