数据库设计(自定义属性取决于另一个属性) - MySQL或其他

时间:2017-08-01 19:38:51

标签: mysql database oracle database-design relational-database

我对我的数据库建模有疑问。

我有一个包含项目/系统的简单数据库(参见下面的例子)

有一个主表,其中包含系统ID,名称,描述以及每个系统的其他几个字段/属性。

每个系统都可以是某种“系统类型”(例如服务器,路由器,加密器等)。

我将这些“类型”放在一个带代码的单独表格中(下例中的systemtype_code)。

我想要实现的目标(它已经有效但不灵活)是:

  • 我想为每种系统类型定制“值/属性”。

例如,如果系统类型是“SSR”,我希望有“机架”,“机架位置”等字段。 如果系统类型是“RTR”,我想拥有诸如“端口数”,“系统日志服务器(包含其他项目的列表框)”等字段,等等。

我认为你得到了它。

我设法使用类似于下面示例的内容(某些字段可以用于很多系统类型),但它非常简单。 它工作得很好,但它有限,因为该字段只能是一种类型(TEXT,VARCHAR或其他类似的东西)。

所以我的问题是:

  • 我的方法好吗? (最后会做巨大的链接表)
  • 如何改进它以便它允许某些自定义字段具有不同类型(例如,列表框等)

感谢

这是我目前拥有的一个例子:

--------------------
table : systems
--------------------
sid
name
description
building_code
responsible_user
systemtype_code

--------------------
table : systemtypes
--------------------
systemtype_code
systemtype_name

--------------------
table : systemattrs
--------------------
systemattr_id
systemattr_name

--------------------
table : systemattrvalues
--------------------
sid
systemattr_id
systemattr_name

--------------------
table : l_systemattrs_systemtypes
--------------------
systemattr_id
systemtype_code

要获取与系统相关的属性,我可以简单地进行如下查询:

                   SELECT   a.systemattr_name,
                                v.systemattr_value
                       FROM     systemattrs a, 
                                systemattrvalues v,
                                systemtypes t,
                                l_systemattrs_systemtypes l
                       WHERE    v.sid = 'MY_DESIRED_SYSTEM_ID'
                       AND      l.systemattr_id = a.systemattr_id
                       AND      l.systemtype_code = t.systemtype_code
                       AND      v.systemattr_id = a.systemattr_id

它很好用,但不完全是我想要的

如果您希望数据库设计架构更好地理解我的问题,请告诉我

4 个答案:

答案 0 :(得分:1)

您处于传统的规范化数据设计和基于实体 - attiribute-value的结构之间(其中对象属性不是表中的列,而是命名行)。

后者(如NoSQL daabase)允许轻松容纳不同的属性集,但难以强制执行有关数据结构的规则和编写复杂查询(例如运行CentOS 6.7的设备的机架位置是什么) )

答案 1 :(得分:1)

正如其他人所评论的那样,您已经彻底改造了一种名为“实体 - 属性 - 价值”和“EAV”的设计。 Stack Overflow上有很多conversations个关于此问题的内容。总的来说,建议不要使用它。

您遇到的第二个问题是在关系数据库中存储多态数据类型。 Stack Overflow上也是discussed

如果您知道要为每个子类型存储的属性,则有三种常用方法可以在关系数据库中存储多态数据(请参阅上面的链接);如果您不了解所有属性,则可以使用数据库对JSON或XML文档的支持来存储扩展属性。

在大多数情况下,两个选项都比EAV更好 - 想象一下,在过去3个月中安装的所有RTR都有超过8个端口的查询,而不是用作系统日志服务器。

答案 2 :(得分:1)

您在评论中澄清说,您已经在大多数其他应用程序代码中使用了关系数据库。这很常见。当您需要由模式强制执行的一致数据结构时,关系数据库非常有用。典型的是,只有一小部分应用程序需要灵活的"数据结构。

因此,您可以继续使用关系数据库,只需选择支持半结构化数据类型的数据库。换句话说,将常规列用于所有类型的公共属性,并使用JSON列作为可选的特定于类型的属性。

参见例如MySQL对JSON的支持:

这应该可以在同一个数据库中使用关系和半结构,为您提供两全其美的优势。

我还在对How to design a product table for many kinds of product where each product has many parameters或我的演示Extensible Data Modeling with MySQL的回答中发布了其他选项的摘要。

EAV(你的设计类似)应该是最后的选择。 可能使用它,但它本质上是非关系型的,并且您最终会编写大量复杂的SQL和应用程序代码来解决它。阅读https://www.red-gate.com/simple-talk/opinion/opinion-pieces/bad-carma/

答案 3 :(得分:0)

对于这类用例,最好使用NoSql数据库。我的建议是使用MongoDB轻松管理不同类型的属性和不同的属性名称。

MongoDB将数据存储为json格式,因此不存在属性名称和类型的限制。