EAV和数据类型

时间:2013-04-23 08:30:53

标签: mysql entity-attribute-value

我们将使用EAV模式进行szenario,我们将拥有各种不同属性的不同实体。

“基本”EAV模式由3个表组成。因为不同的属性会有不同的DataTypes(date,long,boolean,....)我正在考虑如何解决这个问题。

第一种方法是将所有内容存储为字符串。这需要“解析”,如果这是一个double,boolean或任何东西,那么像'1'这样的数字将不会直接显示。 属性值表看起来像

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

然而,这会产生很多NULL值,这基本上是为什么决定导致EAV模式(减少未使用列中的NULL值)

因此,这导致了第三种可能的解决方案,即创建类型属性表:

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 的经验?每次尝试的瓶颈是什么?

3 个答案:

答案 0 :(得分:1)

使用NULL方法。通常,其他查询需要更多资源。

SQL Server 2008提供了一些稀疏列,可以提供帮助。

此外,我可以看到您错过了实体的Instance_Id列 实体具有属性,然后该实体有许多实例。您需要将其与GUID

链接

答案 1 :(得分:1)

Fwiw,我对您的第一个架构和第二个架构的变体有了不错的体验。 (类型列,单值列和适当表达式上的部分索引,即已转换的数据。使用MySQL最接近的是您的第二个模式:您关注的每种类型的列。)

如果您计划在第二个模式上添加索引,请不要忘记区分value_string(对于您需要索引的短字符串,如枚举等)和value_text(对于不应该获取的长文本片段)索引)。

长期来看,我实际上建议第一个选项,通常的警告和警告:EAV表的唯一合理的长期用例是,如果结构未定义且存储在其中的实际数据是化妆品。这里的操作词是不确定的和美观的。每当您真正想要或需要查询EAV表中的一段数据时,您应该问自己应该如何修改架构以适应新列。不这样做是缓慢查询的一个方法。

答案 2 :(得分:0)

我理解你关于尝试减少Null值的观点,但我相信5 Normal forms总是可以解决这个问题。如果您的客户需要实时或按需添加属性,那么我会同意EAV模型。

在我看到的许多其他问题中:

  1. 很难控制属性名称,并使它们保持一致;
  2. 很难强制实施数据类型完整性和参照完整性;
  3. 很难(并且很慢)将值旋转和/或自联接以形成单行;
  4. 很难强制使用某些属性;
  5. 我一直在和Magento合作,它要求大量缓存和辅助表工作“正常”,当然,保持运行的服务器必须是一个强大的服务器。也许你的应用程序要小得多。

    无论如何,这只是我的观点,你,我认为,还可以查看this other point观点并做出自己的结论