我们将为szenario使用EAV模式,在这里我们将有各种不同的实体,它们具有非常不同的属性。
“基本”EAV-模式由3个表组成。因为不同的属性有不同的DataTypes (日期、长、布尔、.)我正在考虑如何解决这个问题。
第一种方法是将所有内容存储为字符串。这需要“解析”,如果这是一个双布尔值或任何东西,那么像'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然而,这将产生大量的空值,这基本上就是决策导致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。同样,如果所有的人都在使用自己的attribute_ids,那么像这样使用它会导致不同值类型的相同的auto_increment。因此,将一个值转换为另一种类型可能有些棘手,因为它的id无法维护。当然,可以通过添加另一个非类型化的attribute_values表来避免这种情况,该表为auto_increment值提供服务,并且可能包含一些类型信息和/或元数据。(由于我们需要使用版本控制/恢复,所以无论如何我们都不能使用自动生成的attribute_values_ids,因为两个版本仍然需要共享同一个id)
所以,第一个决定就是布局。有人有使用EAV的经验吗?每一次尝试的瓶颈是什么?
发布于 2013-06-01 08:15:30
使用NULL方法。其他查询一般需要更多的资源。
Server 2008提供了一些稀疏列,这些列可能会有所帮助。
我还可以看到,您忽略了实体具有属性的Instance_Id列,然后该实体有许多实例。您需要将它与GUID连接起来。
发布于 2013-06-01 09:23:31
Fwiw,我对您的第一个模式和第二个模式的变体有很好的经验。(类型列、单个值列和适当表达式的部分索引,即已转换的数据)。使用MySQL最接近的是第二个模式:您所关心的每种类型的列。)
如果您计划在第二个模式上添加索引,请不要忘记区分value_string (对于您喜欢索引的短字符串,例如枚举等)和value_text (对于不应该被索引的长文本段)。
但是,从长远来看,我实际上会建议第一种选择,并附带通常的警告和警告: EAV表的唯一合理的长期用例是,如果结构没有定义,并且存储在其中的实际数据只是表面的东西。这里的操作词是未定义的和表面的。当您实际需要或需要查询EAV表中的数据时,您应该问自己应该如何修改模式以容纳新列。不这样做会导致缓慢的查询。
发布于 2013-04-23 08:49:46
我理解你关于试图减少零值的观点,但是我相信5范式总是可以解决这个问题的。如果您的客户需要实时或按需添加属性,我同意EAV模型。
除其他问题外,我看到:
我一直在使用Magento,它需要大量的缓存和辅助表来工作“很好”,当然,保持它运行的服务器必须是一个健壮的服务器。也许您的应用程序要小得多。
不管怎么说,这只是我的观点,你,狗鼻,也可以检查这另一点的观点,并作出自己的结论
https://stackoverflow.com/questions/16164574
复制相似问题