【问题标题】:Database design: EAV options?数据库设计:EAV 选项?
【发布时间】:2011-10-24 14:58:51
【问题描述】:

这只是一个数据库概念问题:以下模型对于 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 不包含重复项。

【问题讨论】:

  • 缺点:EAV 真的很难优化。一段时间后,您将陷入无法编写的查询中,因此它们可以快速运行。

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


【解决方案1】:

对于模型 2,您可以在 attribute_id 上施加外键,并确保唯一定义的属性可以进入表。

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

【讨论】:

    【解决方案2】:

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

    即使原样Model2的属性表也构成所有有效属性的存储库(对于model1,需要运行各种聚合查询才能获得这样的列表) .此外,原样,存储库足以引入外键约束,以帮助维护数据集的完整性(对于模型 1,需要外部形式的验证存储在属性列中的值。

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

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

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

    现在...请注意问题本身下方 zerkms 的评论。尽管 EAV 模型具有所有优点,但它也存在一些缺点和挑战,这暗示了查询的复杂性以及性能问题。然而,这些担忧不应该先验地取消 EAV 的资格:在许多用例中 EAV 是更好的方法。
    假设 EAV 是模型 2 的选择,或者甚至稍微更复杂的东西绝对优于模型 1。

    【讨论】:

    • mjv - Model 2 是否仍被视为 EAV?
    • @StackOverflowNewbie - 是的,确实如此。使其成为 EAV 的关键概念是“主”表(所示模型中的“值”表)捆绑了所有 3 个元素:实体(fk_id)、属性(attribute_id)和值。 Attribute 恰好作为 [numeric] id 出现在其中,而不是在 model1 的属性列中看到的一些文本,但这一事实肯定不会消除设计的 EAV-ness。
    【解决方案3】:

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

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

    就优缺点而言,这两种 EAV 实现之间确实没有区别。所有Bill Karwin's points 都适用于两者。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-03-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多