Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/61.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Mysql 如何在数据库中存储具有动态属性数的数据_Mysql_Database_Rdbms - Fatal编程技术网

Mysql 如何在数据库中存储具有动态属性数的数据

Mysql 如何在数据库中存储具有动态属性数的数据,mysql,database,rdbms,Mysql,Database,Rdbms,我有许多不同的对象,它们具有不同的属性。到目前为止,我已经将数据保存在XML文件中,可以方便地允许不断变化的属性数量。但我正试图将其移动到数据库中 您希望以什么方式存储此数据 到目前为止,我已经确定了一些策略: 在对象的表中有一个名为“attributes”的字段,并在其中存储序列化或json的数据 将数据存储在两个表(对象、属性)中,并使用第三个表保存关系,使其成为真正的n:m关系。非常干净的解决方案,但获取整个对象及其所有属性可能非常昂贵 识别所有对象的公共属性,并为这些属性创建对象表的字

我有许多不同的对象,它们具有不同的属性。到目前为止,我已经将数据保存在XML文件中,可以方便地允许不断变化的属性数量。但我正试图将其移动到数据库中

您希望以什么方式存储此数据

到目前为止,我已经确定了一些策略:

  • 在对象的表中有一个名为“attributes”的字段,并在其中存储序列化或json的数据
  • 将数据存储在两个表(对象、属性)中,并使用第三个表保存关系,使其成为真正的n:m关系。非常干净的解决方案,但获取整个对象及其所有属性可能非常昂贵
  • 识别所有对象的公共属性,并为这些属性创建对象表的字段。将其余属性作为序列化数据存储在另一个字段中。这比第一种策略有优势,使搜索更容易

有什么想法吗?

听起来你需要的是舔舐的东西,而不是RDBMS。

2d解决方案的一个变体就是两个表(假设所有属性都是单一类型的):

T1:|对象数据列|对象| id|

T2:|对象id |属性|名称|属性值|(前两列上的唯一索引)

当与第三种解决方案结合使用时,效率更高,例如,所有公共字段都进入T1

Sstuffing>1属性到同一个blob中是不推荐的-您不能按属性筛选,您不能有效地更新它们

如果您计划搜索特定属性,将它们序列化到单个列中是个坏主意,因为您必须使用每行函数来获取信息,所以这很少能很好地扩展

我会选择你的第二选择。在属性表中有一个属性列表,在它们自己的表中有一个对象,还有一个称为对象属性的多对多关系表

例如:

objects:
    object_id    integer
    object_name  varchar(20)
    primary key  (object_id)
attributes:
    attr_id      integer
    attr_name    varchar(20)
    primary key  (attr_id)
object_attributes:
    object_id    integer  references (objects.object_id)
    attr_id      integer  references (attributes.attr_id)
    oa_value     varchar(20)
    primary key (object_id,attr_id)
我们注意到您对性能的担忧,但根据我的经验,拆分一列的成本总是高于合并多个列的成本。如果事实证明存在性能问题,出于性能原因,打破3NF是完全可以接受的

在这种情况下,我将以相同的方式存储它,但也有一个包含原始序列化数据的列。如果使用insert/update触发器使列数据和组合数据保持同步,则不会出现任何问题。但在实际问题出现之前,你不应该担心这一点


通过使用这些触发器,您可以最大限度地减少只在数据发生更改时才执行所需的工作。通过尝试提取子列信息,您可以在每次选择时进行不必要的工作。

如果您打算在稍后编辑/操作/删除属性,那么我会选择一个真正的n:m(第二个选项)。(或者尝试将其设置为2个表,其中重复相同的属性。但数据大小将很高)


如果您没有处理属性(只是捕获和显示数据),那么您可以使用一些分隔符(确保分隔符不会出现在属性值中)

如果您使用的是关系数据库,那么我认为您在列出选项方面做得很好。他们各有利弊。你处于决定什么最适合你的环境的最佳位置

序列化方法可能是最快的(取决于反序列化的代码),但这意味着您将无法使用SQL查询数据。如果您说不需要使用SQL查询数据,那么我同意@longneck,也许您应该使用键/值样式的数据库而不是关系数据库

编辑-阅读更多你的评论,如果你主要关心的是速度,为什么要切换到db。当前的XML实现有什么不好的地方?

我曾经实现:

RAW(16)
Oracle
保存的
GUID
s

如果要选择对象的所有特性,请发出:

SELECT  i.*
FROM    (
        SELECT  id 
        FROM    t_class
        START WITH
                id = (SELECT class FROM t_declaration WHERE id = :object_id)
        CONNECT BY
                parent = PRIOR id
        ) c
JOIN    property p
ON      p.class = c.id
LEFT JOIN
        t_instance i
ON      i.id = :object_id
        AND i.class = p.class
        AND i.property = p.property
t_属性
保存通常不搜索的内容(如文本描述等)

Fast属性实际上是数据库中的普通表,以提高查询效率。它们只保存某个类或其子类的实例的值。这是为了避免额外的连接


您不必使用快速表,也不必将所有数据限制在这四个表中。

让我具体说明一下DVK所说的内容

假设值的类型与表的类型相同(祝您好运,我觉得您需要它):

动态属性表 ------------------------ 身份证号码 钥匙瓦查尔 有什么价值? 示例(汽车):

|id |键|值| --------------------------- |1 |“制造”|“福特”| |1 |“模型”|“边缘”| |1 |“颜色”|“蓝色”| |2 |“制造”|“雪佛兰”| |2 |“模型”|“马里布”| |2 |“最大速度”|“110英里/小时”| 因此,
实体1={('Make','Ford'),('Model','Edge'),('Color','Blue')}
和,

实体2={('Make','Chevrolet'),('Model','Malibu'),('MaxSpeed','110mph')}。

我假设您没有数字属性汤,但您的数据有一定的顺序

否则,RDBMS可能不是最合适的。没有SQL的东西可能工作得更好

如果对象的类型不同,通常每个类型应有一个表

特别是如果您想使用主键连接它们。如果您有产品、订单、客户等表,而不仅仅是一个对象和属性表,那么它还有助于带来秩序和理智

然后看看你的属性。如果存在的对象超过该类型类别中50%的对象,则将其作为对象表中的一列,并在不使用时使用
null

当然,任何必填项都应定义为
notnull

剩下的,你可以
SELECT  i.*
FROM    (
        SELECT  id 
        FROM    t_class
        START WITH
                id = (SELECT class FROM t_declaration WHERE id = :object_id)
        CONNECT BY
                parent = PRIOR id
        ) c
JOIN    property p
ON      p.class = c.id
LEFT JOIN
        t_instance i
ON      i.id = :object_id
        AND i.class = p.class
        AND i.property = p.property
dynamic_attribute_table ------------------------ id NUMBER key VARCHAR value SOMETYPE? |id| key | value | --------------------------- | 1|'Make' |'Ford' | | 1|'Model' |'Edge' | | 1|'Color' |'Blue' | | 2|'Make' |'Chevrolet'| | 2|'Model' |'Malibu' | | 2|'MaxSpeed'|'110mph' |
MainObjectTable:
  mainObjectId: PRIMARY KEY
  columns...
MainObjectVariant1Table:
  mainObjectId: FOREIGN KEY TO MainObjectTable
  variant1Columns...
MainObjectVariant2Table:
  mainObjectId: FOREIGN KEY TO MainObjectTable
  variant2Columns...