代码之家  ›  专栏  ›  技术社区  ›  Shekhar

在一个eav设计中,我们可以拥有一个具有多个值的属性吗?

  •  4
  • Shekhar  · 技术社区  · 16 年前

    我正在使用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)列表类型是否正确?我想确保当一个属性有多个值时,我会将类型作为列表

    2)当属性与对象对应时,数据库设计将如何更改?例如,用户有address..如何处理复合参数?

    如果你能给我一个粗略的表格或图表就好了

    谢谢

    谢卡尔

    1 回复  |  直到 16 年前
        1
  •  7
  •   mjv    16 年前

    对! 在eav中很可能具有多值属性属性。
    事实上,这比传统的关系模型要简单得多,在传统的关系模型中,需要创建一个额外的列,或者用排序的分隔格式存储多个值;当查询数据库以获取基础字段的给定值时,这两种方法都会增加复杂性(attriBUTE)。

    拥有多个值的最简单方法就是拥有一个额外的值记录!(如问题所示)
    此外,可以更改eav存储结构以显式地容纳多个值,其中:

    • 在 属性 指示字段是否可以为多值的表。(顺便说一下,属性的类似属性也可以编码,例如是否需要属性等)
    • 这个 价值 表可以获得一个额外的列来指示值的序列号(对于所有非多值属性,设置为0或1,否则为递增整数)。

    如前所述,这些对eav存储区的物理模式的更改是不必要的,但是它们可以用于确保数据符合(逻辑)模式,以及可能以特定顺序显示多值属性的多个值等。

    编辑 :(有关实现多值和/或复合(“类对象”)属性的详细信息)
    如果您绝对肯定构成属性的多个[“sub”-]值(或类似地构成“object type”属性的多个部分)是完全原子的,即永远不会单独搜索或显示(或…),则可以存储此类属性的值。“sets”,作为值表中的一条记录,通过将多个值编码成一个字符串;为此,想到了json或xml,对于非常可扩展/通用的格式来说似乎特别有趣,但是任何其他可以以可靠的方式解析的格式都会也可以(比如分隔格式)。

    存储这种“属性值部分”的一种更“自然”的方法(eav-wise)是单独存储它们(在值表的多个记录中,可能有前面暗示的序列字段)。这种方法允许在某些上下文中处理“子部分”,就好像它们是属性一样。

    在这两种情况下,都需要更改属性表以添加必要的属性和类型代码,以描述此类多部分属性。与存储数据(在值表中)的方法类似,您可以将属性记录设置为将给定[多部分]属性的所有信息存储在单个属性记录中,或者[这通常更容易和更灵活]可以为每个部分创建一个属性,再加上一个属性“将它们绑定在一起”(例如,一个属性包含一个与子部分的每个属性id值一起删除的字符串)。

    例如 :
    金属管道项目的复合属性可以是直径,由两部分组成:数值 和 单位代码(毫米对英寸)。
    第一种方法是:
    -属性表中将有一条记录,其中一个类型指示这是一个多值,另一个扩展属性包含单个子部件类型的[有序]列表。
    -值表中只有一条记录,其中包含一个编码值,如“0.75 inch”(或 <diam>0.75</diam><unit>Inch</unit> )
    对于第二种方法:
    -属性表中会有3条记录:一条记录或一个数字类型,并命名为say“diamValue”,一条字符串类型的记录,命名为“unit”,一条复合名称类型的记录“diameter”;最后一条记录会以某种方式引用其他两个属性的id(一个简单的逗号分隔符想到d弦) -值表中有两条记录,diamValue和unit属性各一条(这些记录将有一个额外的字段,称为say“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
    

    几点注意事项
    -值id6和7的seqnr都是1。他们的顺序是隐性的,以亚属性。如果属性id 6被设置为多值(“repeats”)属性,则实体可以有两个值的附加对联,它们是按顺序成对排列的2、3等。
    -不可重复属性的序列号系统地设置为1,也可以为空这不适用。
    -属性的“required”属性在多值或复合问题中不起作用;我只是添加了它,因为它通常用于帮助应用程序(或实体访问层)实施各种完整性规则。
    -此布局中的一些设计选项意味着复合属性最多包含一个级别(复合不能包含在复合中),并防止复合包含多值属性。这些限制可以通过适当的结构(并且在访问层中增加了一些复杂性)来避免,但是更简单的模式通常是可以接受的(需要这种奇特结构的属性通常表示逻辑模式中存在缺陷)。