2013-04-23 52 views
0

我們將使用一個szenario的EAV模式,其中我們將擁有具有不同屬性的各種不同實體。EAV和數據類型

「基本」EAV模式由3個表格組成。由於不同的屬性會有不同的數據類型(日期,長,布爾,....)我正在考慮如何解決這個問題。

第一種方法是將所有內容存儲爲字符串。這需要「解析」並且有一個像'1'這樣的數字不會直接顯示,如果這是一個double,boolean或任何東西。 屬性值表看起來像

id|attribute_id|entity_id|value 
1 2   3   17.0 
2 4   2   Foobar 

其次的方法是分裂的不同類型分爲不同的列,具有值列空的,像:

id|attribute_id|entity_id|value_string|value_long|value_float|value_date 
1 2   3   NULL   NULL  17.0  NULL 
2 4   2   Foobar  NULL  NULL  NULL 

然而,這會產生大量的空值這基本上是爲什麼決定導致EAV模式的原因(減少空值在未使用的列)

因此,這導致第三種可能的解決方案,創建類型屬性表:

attribute_values_string 
id|attribute_id|entity_id|value 
2 4   2   Foobar 

attribute_values_float 
id|attribute_id|entity_id|value 
1 2   3   17.0 

但是,這將使得查詢更復雜,一如既往n表有蜜蜂檢查的attribute_value的存在。如果全部使用它們自己的auto_increment,那麼對於不同的值類型使用它也會導致相同的attribute_ids。因此,有一個價值被轉換爲另一種類型可能有點棘手,因爲它是id無法維護。當然,可以通過添加另一個非類型attribute_values表來提供auto_increment值並可能包含某些類型信息和/或元數據,從而避免這種情況。 (因爲我們需要使用版本控制/修訂版本,所以我們無法使用自動生成的attribute_values_ids,因爲兩個版本仍然需要共享相同的ID)

所以,第一個決定是佈局。有沒有人有使用EAV 的經驗?每次嘗試的瓶頸是什麼?

回答

0

我理解你對減少Null值的觀點,但是我相信5 Normal forms總能解決這個問題。如果您的客戶需要實時或按需添加屬性,那麼我認同EAV模型。

在許多其他問題,我看到:

  1. 是難以控制的屬性名稱,並使其保持一致;
  2. 很難執行數據類型完整性和參照完整性;
  3. 這是很難(和緩慢)樞軸和/或自聯接的價值,使一個單一的行;
  4. 很難使某些屬性成爲強制性的;

我一直在與Magento合作,它要求大量的緩存和輔助表工作正常,除了服務器保持運行必須是一個強大的服務器。也許你的應用程序要小得多。

無論如何,這只是我的opnion,你,dognose,還可以檢查的視圖this other point並作出自己的結論

+0

Thx爲您的答案。我們意識到EAV模式的「一般」缺陷,但在我們的案例中,好處是占主導地位。因此,我正在尋找實施它的「最佳」解決方案。目前解決方案2似乎是最好的折衷方案。有空值,是的,但爲每種類型添加自己的表格將會增加複雜性,並且如上所述,使屬性的「類型轉換」更難,而不是使用單個值表。組裝一個實體並不是什麼大問題(即使修改了attributeValues也是如此)。但是,列出幾個實體,因爲您只需要爲一個實體進行大量加入。 – dognose 2013-04-23 18:48:38

1

使用空的方法。一般來說,其他查詢需要更多資源。

SQL Server 2008提供了一些可以幫助的稀疏列。

另外我可以看到你錯過了實體的Instance_Id列 實體有屬性,然後該實體有很多實例。你需要鏈接它與一個GUID

1

Fwiw,我有你的第一個架構和第二個架構的變體體面的經驗。 (類型列,單值列和部分索引在適當的表達式上,即鑄造數據。使用MySQL最接近您的第二個模式:您關心的每種類型的列)

如果您計劃在第二個模式中添加索引,不要忘記區分value_string(對於您關注索引的短字符串,例如枚舉等)和value_text(對於不應該被索引的長文本)。但是,長期來看,我實際上會建議第一個選項,並提供常見的警告和注意事項:對於EAV表唯一合理的長期使用情況是,如果結構未定義並且實際數據存儲在其中是化妝品的東西。這裏的操作單詞是不確定的和美觀的。無論何時您真的想要或需要根據EAV表中的一段數據進行查詢,您都應該問自己如何修改模式以適應新列。不這樣做是緩慢查詢的祕訣。