EAV和数据类型
我们将使用一个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 的经验?每次尝试的瓶颈是什么?
我理解你对减少Null值的观点,但是我相信5 Normal forms总能解决这个问题。如果您的客户需要实时或按需添加属性,那么我认同EAV模型。
在许多其他问题,我看到:
- 是难以控制的属性名称,并使其保持一致;
- 很难执行数据类型完整性和参照完整性;
- 这是很难(和缓慢)枢轴和/或自联接的价值,使一个单一的行;
- 很难使某些属性成为强制性的;
我一直在与Magento合作,它要求大量的缓存和辅助表工作正常,除了服务器保持运行必须是一个强大的服务器。也许你的应用程序要小得多。
无论如何,这只是我的opnion,你,dognose,还可以检查的视图this other point并作出自己的结论
使用空的方法。一般来说,其他查询需要更多资源。
SQL Server 2008提供了一些可以帮助的稀疏列。
另外我可以看到你错过了实体的Instance_Id列 实体有属性,然后该实体有很多实例。你需要链接它与一个GUID
Fwiw,我有你的第一个架构和第二个架构的变体体面的经验。 (类型列,单值列和部分索引在适当的表达式上,即铸造数据。使用MySQL最接近您的第二个模式:您关心的每种类型的列)
如果您计划在第二个模式中添加索引,不要忘记区分value_string(对于您关注索引的短字符串,例如枚举等)和value_text(对于不应该被索引的长文本)。但是,长期来看,我实际上会建议第一个选项,并提供常见的警告和注意事项:对于EAV表唯一合理的长期使用情况是,如果结构未定义并且实际数据存储在其中是化妆品的东西。这里的操作单词是不确定的和美观的。无论何时您真的想要或需要根据EAV表中的一段数据进行查询,您都应该问自己如何修改模式以适应新列。不这样做是缓慢查询的秘诀。
Thx为您的答案。我们意识到EAV模式的“一般”缺陷,但在我们的案例中,好处是占主导地位。因此,我正在寻找实施它的“最佳”解决方案。目前解决方案2似乎是最好的折衷方案。有空值,是的,但为每种类型添加自己的表格将会增加复杂性,并且如上所述,使属性的“类型转换”更难,而不是使用单个值表。组装一个实体并不是什么大问题(即使修改了attributeValues也是如此)。但是,列出几个实体,因为您只需要为一个实体进行大量加入。 – dognose 2013-04-23 18:48:38