代码之家  ›  专栏  ›  技术社区  ›  McGovernTheory

EAV数据建模

  •  2
  • McGovernTheory  · 技术社区  · 15 年前

    其他人如何使用关系建模工具将逻辑模型或三分之一正常形式的模型映射到使用EAV的数据库?

    2 回复  |  直到 11 年前
        1
  •  7
  •   Bill Karwin    15 年前

    EAV是一种非关系设计。你做不到 任何 正常形式与EAV,因为它没有成为一个关系。

    EAV是 Inner-Platform Effect 反模式。

    如果您需要许多属性,可以考虑 serializing to a blob 并将该XML存储在 CLOB 列。

        2
  •  1
  •   TomFH    11 年前

    在关系中,可以有一个EAV(也称为属性-值对或名称-值对)。它使用相当抽象的数据模型。在描述它之前,有几个注意事项。很难查询,而且性能不好。EAV通常用于审计表的关系。EAV存储单个列的before映像(在更改之前)。它逐个存储更改的列。如果更改了五个属性,则EAV中将存储五行。此外,由于EAV中的自然主键可能很大,因此通常使用镜像表而不是EAV。

    EAV可以在逻辑数据建模和关系中创建。这可以通过三个相关实体或表来实现:

    • 基本实体(如客户),类似于列族。
    • “类型”实体,描述属性及其特征,如净值,
    • 一个“值”实体,它将属性分配给一个基本实体的实例并给它一个值。

    基本实体是具有不同特征的实体。

    “类型”实体只是由类型代码标识的代码表,包含描述和其他域特征。域是指数据类型、长度、含义和度量单位等,它描述了上下文之外的属性(即未分配)。一个例子可以是净值金额,它是一个数字8位,小数点后2位,右对齐,其描述是“代表客户的总财务价值的值,包括流动和非流动金额”。

    “value”实体是一个关联实体或表,由客户ID和属性类型代码[两个外键]标识,它具有一个value属性,该属性为客户分配净值金额类型,并为其提供一个值,例如“$2000000”。value列通常具有一个通用名称,例如field。

    但是,在SQL中,名称-值对查询起来有点困难,而且通常性能不好。假设“value”实体有一个名为“field”的属性。这是一个字符串。SQL通常使用列名称作为结果集头。假设这个领域有净值。但当它被显示时,标题将被称为“字段”,而不是净值。字段是列的实际名称。需要高级SQL才能获得所需的头。这个问题可以通过将“类型”和“值”实体反规范化为一个实体来解决。您没有三个表,而是有两个——一对多,一个基表和一个值表。实际上,这就是Cassandra所做的:列族中的列是完全扁平的属性-值对。即使在关系中取消规范化,“字段”列仍然称为“字段”。

    您也可以将这三个实体展平(非规范化)为关系中的一个表,但会出现冗余问题:客户ID[FK]、属性类型代码[FK]、客户基属性、属性类型属性、字段(用于值)。我不是建议,我只是说。

    在数据建模的早期,数据建模人员喜欢使用EAV,因为它们看起来是一个优雅、灵活的解决方案——直到DBA掌握了它们。因此,EAV有时用于逻辑模型,但在物理模型中应该完全非规范化。当完全非规范化时,它与卡桑德拉有很强的相似性。我有时在逻辑和物理上都使用EAV,上面已经指出了这些问题。我不知道如何在这些评论中添加图形,否则我将包括一个插图。