我们将在一个场景中使用 EAV 模式,其中我们将拥有具有非常不同属性的各种不同实体。
“基本” EAV 模式由 3 个表组成。由于不同的属性将具有不同的数据类型(日期、长整数、布尔值......),我目前正在考虑如何解决这个问题。
第一种方法是将所有内容存储为字符串。这需要“解析”,如果这是一个双精度、布尔值或任何东西,则不会直接显示像“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
. attribute_ids
如果所有人都使用自己的auto_increment,那么像这样使用它也会导致不同的值类型相等。因此,将一个值转换为另一种类型可能有些棘手,因为它id
无法维护。当然,这可以通过添加另一个attribute_values
服务于 auto_increment 值并且可能包含一些类型信息和/或元数据的非类型表来避免。(因为我们需要使用版本控制/修订我们不能使用自动生成的属性值_ids,因为两个修订版仍然需要共享相同的 id)
所以,第一个决定是布局。有人有使用 EAV的经验吗?每次尝试的瓶颈是什么?