4

我正在使用 EAV 进行数据库设计。当我尝试对具有多个值的属性的实体建模时遇到问题?

例如

实体

id         | name           | description
--         | ----           | ------------ 
1          | configuration1 | configuration1

属性

id         | entityId    | name  | type
--         | --------    | ----  | ----
1          | 1           | att1  | string
2          | 1           | att2  | int
3          | 1           | att3  | List<String>  (How will i model this?)

价值

id        | attributeId    | value
--        | -----------    | -----
1         | 1              | a    
2         | 2              | 1
3         | 3              | b
4         | 3              | c    
5         | 3              | d

这是处理值列表的正确方法吗?

请提供任何有用的链接来建模这个?

还有两个问题

1) 类型为 List 是否正确?我想确定当一个属性有多个值时,我会将类型指定为 List

2)当属性对应一个对象时,数据库设计将如何变化?例如用户有地址..我将如何处理复合参数?

如果您能给我提供一个粗略的表格表示或图表,那就太好了

谢谢

谢卡尔

4

1 回答 1

7

是的!在 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 级(组合不能包含在组合中),并防止组合包含多值属性。这些限制可以通过适当的结构来避免(并在访问层增加一点复杂性),但更简单的模式通常是可以接受的(需要这种花哨结构的属性通常表明逻辑模式存在缺陷) .

于 2010-03-16T06:06:50.190 回答