2013-04-23 36 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表中的一段数据进行查询,您都应该问自己如何修改模式以适应新列。不这样做是缓慢查询的秘诀。