数据库设计:EAV选项?

时间:2011-08-11 03:04:05

标签: mysql database database-design entity-attribute-value

这只是一个数据库概念问题:以下EAV模型的优缺点是什么?

模型1:

TABLE: attribute_value
======================================
| id | fk_id | attribute | value     |
======================================
| 1  | 10    | FName     | John      |
| 2  | 10    | Lname     | Doe       |
| 3  | 55    | FName     | Bob       |
| 4  | 55    | Lname     | Smith     |
--------------------------------------

模型2:

TABLE: attribute
==================
| id | attribute |
==================
| 1  | FName     |
| 2  | Lname     |
------------------

TABLE: value
=====================================
| id | attribute_id | fk_id | value |
=====================================
| 1  | 1            | 10    | John  |
| 2  | 2            | 10    | Doe   |
| 3  | 1            | 55    | Bob   |
| 4  | 2            | 55    | Smith |
-------------------------------------

我在模型2中看到的一个好处是attribute不包含重复项。

3 个答案:

答案 0 :(得分:5)

虽然如图所示是极简主义,但Model2的属性表将元数据的概念引入混合中,并带来了所有好处。 Model2还有其他优点,例如与较小行大小(Value表)相关的性能增益,但我想关注元数据概念。

甚至 as-is Model2的属性表构成所有有效属性的存储库(对于model1,需要运行一个聚合查询来获取这样的列表) 。此外, as-is ,存储库足以引入外键约束来帮助维护数据集的完整性(模型1需要外部形式的验证存储在属性列中的值。

通过一些简单的添加,属性表可以成为一个多功能的存储库,可用于各种目的。例如,该表可能包括以下某些内容

  • info,例如每个属性的显示友好名称
  • 一些标志,指示字段类型(数字与字符串与日期等),用于区分处理/处理
  • 存储基础属性的特定值表(模型仅显示一个表,但优化/缩放有时会提示拆分表)
  • 该属性可以作为自己的列存储在“值”表中(再次是一种优化形式,基本上是两全其美:EAV模型的架构灵活性,但传统的性能)所有实体使用最多和/或最常见的属性的关系模型。
  • 能够重命名属性,而不会干扰主表。仅在元数据级别进行更改。
  • 各种面向应用程序的语义。例如,应将特定属性作为基本搜索字段和高级搜索字段之一提供的指示符。

简而言之,属性表成为一种资源,它允许应用程序真正实现数据驱动(或更确切地说,数据驱动)。实际上,您可能也喜欢实体表,即收集与各种实体类型相关的元数据的实体表:不同的实体类型,允许哪些实体类型的属性等。

现在......请注意问题本身下面的 zerkms 的评论。尽管如此,EAV模型还有其缺点和挑战,因为暗示了查询的复杂性以及性能问题。然而,这些问题不应该取消资格,先验,EAV:有很多用例,其中EAV是一种更好的方法。
假设EAV是选择,那么Model2,甚至更复杂的东西明显优于model1。

答案 1 :(得分:1)

在概念层面,这两个模型实际上是相同的。您刚刚用ID号替换了字符串。就是这样。

就外键而言,如果您愿意,可以在模型1中对“属性”施加外键约束。

就利弊而言,这两种EAV实现之间并没有什么区别。所有Bill Karwin's points都适用于两者。

答案 2 :(得分:0)

对于Model 2,您可以在attribute_id上​​施加Foreign-Key,并确保唯一定义的属性可以进入表中。

同样对于模型2,您可以使用更快的查询来获取具有某些属性ID的值,因为如果您创建外键(索引),查询将更快。