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

oli*_*erg 1 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
Run Code Online (Sandbox Code Playgroud)

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

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

它工作得很好,但不完全是我想要的。

如果您想要数据库设计模式来更好地理解我的问题,请告诉我。

Nev*_*uyt 5

正如其他人评论的那样,您重新发明了一种称为“实体-属性-值”或 EAV 的设计。Stack Overflow 上有很多很多关于这个问题的讨论;总的来说,建议不要使用这个。

您遇到的第二个问题是在关系数据库中存储多态数据类型。Stack Overflow 上也对此进行了讨论。

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

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