EAV与行模型比较(EAV vs Row Modelling

实体-属性-值的设计是行模型的泛化(或)推广。这意味着整个数据库所有类型的数据存储在一张表中,其中一个行模型的表的数据时是均匀。此外,这行模型表中值列的数据类型是预先确定的,而在一EAV表中,特定行其值的数据类型由对应的属性确定。

选择数据模型的最佳方法是很难的,但作为一个准则,如满足如下条件时请考虑EAV模型而非行模型:

  • 数据记录中的单个属性的数据类型不同(是/否,数值型;Yes/No,numerical value,string);采用行模型时一张表中很难存储属性的值。
  • 许多种类的数据必须表现出来,其数量可能出现波动。与此同时,即使不稀疏的属性,然每类数据都非常少。这种情况下,传统的数据模型将使成百的表却只有几行数据。
  • 在一定的环境中,其类别/类必须在动态创建,某些类在原型随后的周期中常常会被省略。
  • 某些类归类为混合型的类,这意味着一些类的属性是稀疏的,而其他属性则是非常稀少的。在这种情况下,非稀疏属性存储在传统表中,而稀疏的属性存储在EAV或行建模的格式。这些类通常会满足商业数据库应用的需要,所有产品将共享这些属性,如包装单位和单价。请注意,如果只有一两个混合类,EAV设计可能不值得。

实体、属性和值表示(Representing Entities, Attributes and Values

实体描述(Representing Entities

一个实体可以是任何条目,到目前为止,所看到的例子是销售事件实体、商人和产品实体。EAV管理的实体是通过一个对象表,用以获取每个项目的共同数据,如名称、说明等。对象表中的每一实体必须具有唯一的标识符,而这通常是自动生成的。然后,该标识符在整个数据库作为外键。

采用EAV建模并不阻止使用传统的数据表来存贮单个对象的更多细节信息。这是在同一数据库模式(schema)内应用传统关系数据库模型和EAV模型的常见数据建模方法。

属性描述(Representing Attributes

属性存储在一个专门的属性表。本表的主键是用来作为跨数据库的参考。的属性表通常辅以多个元数据表,更详细地描述了一个属性。此元数据信息通常用于自动化浏览和编辑数据的用户界面生成。元数据表可能包含如下类型的信息部分:

  • 验证:验证元数据包括属性的数据类型、默认值、值数量的可能限制,以及可否为空(null)。
  • 展现:定义属性如何呈现给用户,是否为文本区域、下拉框或单选按钮/检验框(radio button/checkbox)组。
  • 分组:属性大多呈现在用户群体。 分组中的元数据定义了一个属性的显示方式,提出了属性的数量和什么样的字体和颜色类型使用的顺序。
  • 正常值范围:在某些情况下正常的值范围,可能会随性别、年龄有所不同,等等。

值描述(Representing Values

描述EAV模型值的最简单方法就是将其数据存储为一个字符串。但是,这种方法是相对低效的,因为做任何事与该值相关的事情是都需要进行数据类型转换。此外,对存储为字符串的值创建的索引不允许针对数值型和日期型的搜索范围优化,这是采用混合数据类型的键-值对描述数据的公共问题。

为改善这种情况,EAV模型为每一数据类型建立单独的表。属性元数据标识正确的数据类型以及随后存储数据的EAV表。这种方法更有效,因为它允许在访问数据之前,缓存给定属性的元数据。

这种方法的主要缺点在一个属性的数据类型需要改变时是显而易见的,需要将数据从一张表重新分配到另一表中,这很不方便,可以通过存储过程来解决。

一般情况下,空值或不适用于此EAV模型。但某些情况下,存在记录缺失值的必要原因。在这种情况下,解决方法是在表中添加缺失值的编码列,仅在该列的值为空(null)时其值非空。然后,此编码用于查找文字说明清单。