She*_*har 4 database-design entity-attribute-value
我正在使用EAV进行数据库设计.当我尝试使用具有多个值的属性建模实体时,我遇到了一个问题?
例如
实体
id | name | description
-- | ---- | ------------
1 | configuration1 | configuration1
Run Code Online (Sandbox Code Playgroud)
属性
id | entityId | name | type
-- | -------- | ---- | ----
1 | 1 | att1 | string
2 | 1 | att2 | int
3 | 1 | att3 | List<String> (How will i model this?)
Run Code Online (Sandbox Code Playgroud)
值
id | attributeId | value
-- | ----------- | -----
1 | 1 | a
2 | 2 | 1
3 | 3 | b
4 | 3 | c
5 | 3 | d
Run Code Online (Sandbox Code Playgroud)
这是处理值列表的正确方法吗?
请提供任何有用的链接来建模吗?
还有两个问题
1)类型列表是否正确?我想确保当一个属性有多个值时,我会将类型赋予List
2)当属性对应于对象时,数据库设计将如何变化?例如,用户有地址..我将如何处理复合参数?
如果你能给我一个粗略的表格表示或图表,那就太棒了
谢谢
谢卡尔
是! 在EAV中很可能有多值属性属性.
事实上,它比传统的关系模型更容易,在传统的关系模型中,人们需要创建一个额外的列,或者以分隔的排序格式存储多个值; 当查询数据库以获得底层字段(属性)的给定值时,这种方法都会增加复杂性.
拥有多个值的最简单方法就是拥有一个额外的值记录!(如问题所示)
此外,可以更改EAV商店结构以明确适应多值,具有:
如上所述,这些对EAV存储的物理模式的更改不是必需的,但它们可用于确保数据符合(逻辑)模式以及可能在特定的多个属性中显示多个值的多个值.订单等
编辑 :(有关实现多值和/或复合("类对象")属性的详细信息)
如果您绝对肯定构成属性的多个["sub" - ]值(或类似构成属性的多个部分) "对象类型"属性),完全是原子的,即永远不会被单独搜索或显示(或...),你可以存储这样一个属性'value'sets",作为值表中的单个记录,通过编码将多个值转换为单个字符串; 为此,我想到了JSON或XML-on-large对于非常可扩展/通用而言似乎特别有趣,但是你可以以可靠的方式解析和解析的任何其他格式也可以工作(比如分隔格式).
存储这种"属性值部分"的更"自然"的方式(EAV方式)是通过单独存储它们(在值表的多个记录中,可能具有前面提到的序列字段).这种方法允许在某些情况下处理"子部分",就好像它们是属性一样.
在这两种情况下,您都需要更改属性表以添加必要的属性和类型代码,以描述此类多部分属性.与存储数据的方法(在值表中)类似,您可以使属性记录使得给定[多部分]属性的所有信息都存储在单个属性记录中,或者[并且这是通常更容易和更灵活]您可以为每个部件创建一个属性,加上一个属性"将它们绑定在一起"(例如,使用包含与子部件的每个属性ID值分隔的字符串的属性.
例如:
金属管道项目的复合属性可以是直径,由两部分组成:数值和单位代码(毫米,与英寸).
使用第一种方法:
- 属性表中将有一条记录,其中一个类型表示这是一个多值,一个扩展属性包含各个子部分的[ordered]类型列表.
- 值表中会有一条记录,包含一个编码值,例如"0.75 |英寸"(或<diam>0.75</diam><unit>Inch</unit>).
使用第二种方法:
- 属性表中将有3条记录:记录或类型数字并命名为"diamvalue",类型字符串的记录,名为"unit",类型记录为复合名称"Diameter"; 这个最后一条记录会以某种方式引用另外两个属性的ID(一个简单的逗号分隔字符串) - 值表中会有两条记录,diamvalue和unit属性各一条(这样的记录会有一个额外的字段,称为"父",包含"Diameter"属性的AttributeID.也可以选择"Diameter"属性的值记录[我个人觉得这个多余的"父"属性.
如前所述,第二种解决方案的主要优点是[在适当的时候]可以根据属性部分的值查询目录中的特定项目集,例如搜索具有度量单位的所有管道.此类查询在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
Run Code Online (Sandbox Code Playgroud)
一些注意事项:
- 值ids 6和7的SeqNr对于两者都是1.它们的顺序隐含在SubAttribIdList中.如果属性ID 6已经取得的多值("重复")属性,一个实体可以具有两个值的附加对联,测序,在一对,2,3等
-用于非可重复的属性的序列号设置为1系统地,也可以是NULL,这不适用.
- 属性的"必需"属性未在多值或复合问题中计算; 我刚添加它,因为它通常用于帮助应用程序(或实体访问层)执行各种完整性规则.
-一些在此布局的设计选择的复合属性的最大的1级夹杂物(复合不能在包含在复合材料)所暗示的,以及防止复合材料包括一个多值属性.这些限制可以用适当的结构(以及与该接入层中的位的增加的复杂性)来避免,但更简单的架构是典型的可接受的(即,则需要这样花式结构属性通常一个指示缺陷的在逻辑模式) .