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

Jör*_*örg 19 mysql database rdbms

我有许多不同的对象,具有不同数量的属性.到目前为止,我已将数据保存在XML文件中,这些文件可轻松实现不断变化的属性数量.但我正在尝试将其移至数据库.

存储此数据的首选方法是什么?

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

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

有任何想法吗?

pax*_*blo 24

如果您计划搜索特定的属性,那么将它们序列化为单个列是一个坏主意,因为您必须使用每行函数来获取信息 - 这永远不会很好地扩展.

我会选择你的第二选择.拥有属性表中的属性列表,它们自己的表中的对象以及称为对象属性的多对多关系表.

例如:

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)
Run Code Online (Sandbox Code Playgroud)

您注意到了对性能的关注,但根据我的经验,拆分列总是比组合多列更昂贵.如果事实证明存在性能问题,那么出于性能原因打破3NF是完全可以接受的.

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

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


DVK*_*DVK 6

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

T1:|对象数据列| Object_id |

T2:| Object id | attribute_name | attribute value | (前2列的唯一索引)

当与第三解决方案结合时,这甚至更有效,例如,所有公共字段都进入T1.

不推荐将Sstuffing> 1属性放入同一个blob中 - 您无法按属性进行过滤,无法有效地更新它们