许多开发人员在定义和分析数据需求时会遇到同样的问题,就是许多不同的属性可用来描述一个对象,但实际上只有很少的属性适用于每个人。一种选择是创建一具有每个属性列的表,这种方法适用于具有固定数量属性的对象,对大多数对象而言,其中全部或大部分属性有值。 然而,在某些情况下,最终得到的记录,其中大部分列将是空的,因为属性可能是未知或不适用的。许多种类的数据必须表现出来,其数量可能出现波动。与此同时,即使不稀疏的属性,然每类数据都非常少。这种情况下,传统的数据模型将使成百的表却只有几行数据。

多种类的数据必须表现出来,其数量可能出现波动。与此同时,即使不稀疏的属性,然每类数据都非常少。这种情况下,传统的数据模型将使成百的表却只有几行数据。

为解决上述问题,可应用EAV(Entity,Attribute,Value)模型。这种模式也有几个可选的称谓,包括“对象-属性-值(object—attribute-value)”模型和“开放架构(open schema)”几种可供选择的名称。在EAV数据模型中,只有非空值才存储在数据库中,每个属性-值(或键-值)对描述一个给定实体的属性。EAV表经常定性为“长瘦(long and skinny)”的,“长”是指描述实体的多个行,而“瘦”则指仅使用少量的列。在本文中将描述EAV模型及其实现,并展示其在现实世界中的应用---包括研究Magento是如何应用这个模式。

对象属性存储在一个有三列的表中:实体,属性和值(entity,attribute,value)。实体(entiry)表示所描述的数据项,例如一个产品或汽车。属性(attribute)表示描述实体的数据,例如一个产品将有价格,重量和许多其他属性。值(value)是属性的值,例如产品可能有一个9.99英镑的价格属性。此外值可以基于数据类型进行分割,所以可将EAV表分为字符串、整数、日期和长文本(long text)表。依据数据类型分割是为了支持索引,使得数据库执行可能的类型检查验证。

稀疏的属性(Sparseness of Attributes)

在数学和计算机科学中,如果一个对象仅包含大量潜在属性中的几个属性,称之为“稀疏矩阵”。在讨论EAV模型时,采用“稀疏”来描述大多数无值的属性。

为说明这一点,来看看超市的收据,超市中有成千上万的库存产品,每日引入新的产品,其它则停止销售。客户购买5个产品的收据只列出实际购买的详细项目,每行一种产品。该收据并没有列出客户可能购买的每一种产品,所以说客户的收据是稀疏的。

按照数据库的术语实体是销售发票,包含如交易ID、日期和时间、存放位置等信息,收据中的每一行对应销售表中的一行记录,存有一个属性及一个或多个值。在这种情况下,属性之一是客户所购买的产品,则为的数量、单价、折扣和总价。

上面的例子说明了属性的稀疏性(一个客户只选购一个可能的产品),引入一个新的术语:行建模(row modelling。基于行模型的表,其描述实体的数据记录为多行,每组新的数据在数据库中存为额外的行而非额外的列。行模型是数据库设计时的标准数据建模技术,它仅适用于满足如下两个条件的情况:

  • 特定实体的数据是稀疏的。
  • 数据时易变的。

行建模是不适用于稀疏且数据非波动的情形,此时,应采用传统的列模型。

行模型示例(Example of Row Modeling

在这个例子中,有三个实体:产品,客户和发票。产品和客户是标准的关系表。

正如本文前面提到的,满足(上文所述的)两个条件时行模型需是一个不错的选择,即特定实体的数据稀疏,且很容易变化。

我们知道,新产品不断推出且被引入销售,而旧的产品撤回。同时,发票表中不能对每种产品以一列来描述,因为这是不切实际的。

该发票表包含有关销售活动的主要信息,客户、日期和时间、发票ID。每张发票,在表中记录为一行。每一行指定了(顾客)购买的产品、单价和数量。