我们将使用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 的经验?每次尝试的瓶颈是什么?
答案 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模型。
在我看到的许多其他问题中:
我一直在和Magento合作,它要求大量缓存和辅助表工作“正常”,当然,保持运行的服务器必须是一个强大的服务器。也许你的应用程序要小得多。
无论如何,这只是我的观点,你,我认为,还可以查看this other point观点并做出自己的结论