【问题标题】:database design (custom attributes depending on a another attribute) - MySQL or other数据库设计(自定义属性取决于另一个属性) - MySQL 或其他
【发布时间】:2017-08-01 19:38:51
【问题描述】:

我有一个关于我的数据库建模的问题。

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

有一个主表,其中包含系统 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

效果很好,但不是我想要的。

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

【问题讨论】:

  • 展开:...but is not exactly what I want?
  • 研究 EAV 的优缺点。阅读有关数据库实体子类型的信息。
  • @PaulT。正如我所说,限制是我只能为该自定义字段使用 1 种数据类型(例如 VARCHAR),但是如果我想要一个列表框而不是自定义字段呢?
  • EAV 架构很可能会让你伤心。

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


【解决方案1】:

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

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

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

在大多数情况下,这两个选项比 EAV 好得多 - 想象一下,查询所有具有 8 个以上端口的 RTR,未用作 syslog 服务器,在过去 3 个月内安装。 p>

【讨论】:

    【解决方案2】:

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

    所以你可以继续使用关系数据库,只需选择一个支持半结构化数据类型的数据库即可。换句话说,对所有类型共有的属性使用常规列,并为可选的、特定于类型的属性使用 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/

    【讨论】:

    • 感谢发帖,我会看看这个 json 数据类型,看看它是否符合我的需要,唯一的问题是数据库变得不可移植(我希望我可以部署我的例如,mysql/oracle/postgres 上的应用程序,不仅是 mySQL),但如果它很好,我可能会坚持使用 MySQL!
    • PostgreSQL 也有JSON typesJSON in Oracle database,但在每种情况下功能和用法都不同。恕我直言,试图让您的数据库“便携”是不值得的。无论如何,您都必须进行大量更改和测试。
    【解决方案3】:

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

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

    【讨论】:

    • 我明白了.. 我想我也可以使用 LDAP 数据库更轻松地做类似的事情,但我的程序已经在许多其他事情上使用 SQL,所以保持相同的后端会很好
    【解决方案4】:

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

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

    【讨论】:

    • 我会看一下 noSQL,但该应用程序正在使用关系数据库中已经存在的许多其他模块,因此现在很难切换
    猜你喜欢
    • 2019-09-02
    • 1970-01-01
    • 2011-09-09
    • 1970-01-01
    • 1970-01-01
    • 2011-02-14
    • 1970-01-01
    • 1970-01-01
    • 2012-07-15
    相关资源
    最近更新 更多