是的!在 EAV 中很可能具有多值属性属性。
事实上,它比传统的关系模型更容易,传统的关系模型需要创建一个额外的列,或者以排序的分隔格式存储多个值;在查询数据库以获取基础字段(属性)的给定值时,这两种方法都会增加复杂性。
拥有多个值的最简单方法就是拥有一个额外的值记录!(如问题所示)
此外,可以更改 EAV 存储结构以显式容纳多值,其中:
- 属性表中一个额外的类似布尔值的字段,用于指示该字段是否可以是多值。(顺便说一句,也可以对属性的类似属性进行编码,例如是否需要该属性等
- 值表可以获得一个额外的列来指示值的序列号(对于所有非多值属性设置为 0 或 1,否则为递增整数)。
如前所述,这些对 EAV 存储的物理模式的更改不是必需的,但它们可用于确保数据符合(逻辑)模式以及可能显示特定的多值属性的多个值订单等
编辑:(有关实现多值和/或复合(“类对象”)属性的详细信息)
如果您绝对肯定构成属性的多个 [“sub”-] 值(或类似地构成属性的多个部分) “对象类型”属性)是完全原子的,即永远不会单独搜索或显示(或...),您可以通过编码将此类属性的值“集合”存储为值表中的单个记录多个值到一个字符串中;为此目的,JSON 或 XML-at-large 浮现在脑海中,并且对于非常可扩展/通用的来说似乎特别有趣,但是您可以以可靠方式解析进出的任何其他格式也可以工作(比如分隔格式)。
存储此类“属性值部分”的一种更“自然”的方式(EAV 方式)是单独存储它们(在值表的多个记录中,可能带有如前所述的序列字段)。这种方法允许在某些情况下处理“子部分”,就好像它们是属性一样。
在这两种情况下,您都需要更改属性表以添加必要的属性和类型代码,以描述此类多部分属性。与存储数据的方法(在值表中)类似,您可以制作属性记录,使得给定 [多部分] 属性的所有信息都存储在单个属性记录中,或者,[这是通常更容易和更灵活] 您可以为每个部分创建一个属性,加上一个属性以“将它们绑定在一起”(例如,使用包含一个字符串的属性,该字符串由子部分的每个属性 ID 值分隔。
例如:
金属管道项目的复合属性可以是直径,由两部分组成:数值和单位代码(毫米,与英寸)。
使用第一种方法:
- 属性表中将有一个记录,其类型指示这是一个多值,以及一个包含各个子部分的[有序]类型列表的扩展属性。
- 值表中将有一条记录,包含编码值,例如“0.75|Inch”(或<diam>0.75</diam><unit>Inch</unit>
)。
使用第二种方法:
- 属性表中将有 3 条记录:一条记录或数字类型并命名为“diamvalue”,一条字符串类型的记录,命名为“unit”,以及一条复合名称类型的记录“Diameter”;最后一条记录会以某种方式引用其他两个属性的 ID(想到一个简单的逗号分隔字符串) - 值表中将有两条记录,一个 diamvalue 和一个单位属性(这样的记录将有一个额外的字段,称为“parent”,包含“Diameter”属性的 AttributeID。可选地,“Diameter”属性也可以有一个值记录[我个人认为这与“parent”属性是多余的。
如前所述,第二种解决方案的主要优点是[在适当的时候]可以根据属性部分的值查询目录中的一组特定项目,例如搜索所有具有公制单位的管道。此类查询在 SQL 级别解决,其中第一种方法是,SQL 必须扫描属性“Diameter”的所有属性值并解析该值以搜索单位代码。
一张图片值一千字;-)
此图显示了“第二种方法”的示例数据的可能布局。
Entity
id | name | description
-- | ---- | ------------
1 | configuration1 | configuration1
Attribute
id | name | type | Required | Repeats | SubAttribIdList
-- | ---- | ---- | -------- | ------- | ---------------
1 | att1 | string | N | N | null (only applicable to composite types)
2 | att2 | int | Y | N | null
3 | att3 | string | Y | Y | null
4 | DiamValue | numeric | Y | N | null
5 | Unit | string | Y | N | null
6 | Diameter | composite| N | N | 4,5
Value
id | entityId| attributeId | ParentAttribId |SeqNr | value
-- | --------| ----------- | -------------- |----- | -----
1 | 1 | 1 | null | 1 | a
2 | 1 | 2 | null | 1 | 1
3 | 1 | 3 | null | 1 | b (this value and next show show a repeating attribute)
4 | 1 | 3 | null | 2 | c
5 | 1 | 3 | null | 3 | d
6 | 1 | 4 | 6 | 1 | 0.75 (this value and next one shows a composite attribute
7 | 1 | 5 | 6 | 1 | Inches
一些注意事项:
- 值 id 6 和 7 的 SeqNr 都是 1,两者都是。它们的顺序隐含在 SubAttribIdList 中。如果属性 id 6 已成为多值(“重复”)属性,则实体可以具有两个值的附加对联,按顺序排列、成对、2、3 等。
- 不可重复属性的序列号设置为 1 ,系统地,也可以是 NULL 这不适用。
- 属性的“必填”属性不在多值或复合问题中;我刚刚添加了它,因为它通常用于帮助应用程序(或实体访问层)执行各种完整性规则。
- 此布局中的一些设计选择意味着组合属性最多包含 1 级(组合不能包含在组合中),并防止组合包含多值属性。这些限制可以通过适当的结构来避免(并在访问层增加一点复杂性),但更简单的模式通常是可以接受的(需要这种花哨结构的属性通常表明逻辑模式存在缺陷) .