【问题标题】:Good database design, variable number of attributes良好的数据库设计,可变数量的属性
【发布时间】:2012-07-21 03:43:36
【问题描述】:

我正在尝试创建一个包含设备列表的数据库。所有的设备都会有某些共同的属性(例如制造商、型号#、序列号等),然后还有特定于某个设备的其他属性(即调制解调器将具有访问权限#,而太阳能电池板将具有输出能力)。我不确定如何用良好的数据库设计原则来表示这些不断变化的属性,我尝试过在网上搜索,但我不完全确定要搜索什么。

我提出了以下可能的解决方案以及我对它们的初步想法:

  1. 拥有一个包含所有可能属性的大表,并在不适用的地方放置 null。显然,这有一些缺陷。

  2. 每个设备类型都有一个单独的表格。这似乎使用起来可能是一场噩梦,如果我想打印所有设备的列表,我怎么知道要查找哪些表?

  3. 拥有一个包含通用属性的表,以及使用外键访问的每种设备类型的其他表,以存储额外的属性。我可能可以完成这项工作,但这会很麻烦,而且感觉不是一个很好的解决方案。

  4. 实体-属性-值类型模型。只是看起来不太适合我想做的事情。

我在数据库方面没有很多经验,所以我在这里边学习边学习,任何与此问题相关的链接或有关数据库设计的“必读”文章将不胜感激。谢谢!

编辑: 首先,我发现我需要谷歌“继承映射”,这可能会帮助其他有类似问题的人。为了解决这个问题,我最终使用了#2 和#3 的混合体。它实际上非常简单,运行良好,并且解决了添加额外设备类型的问题,而没有 EAV 的复杂性。感谢所有cmets和建议!

【问题讨论】:

标签: mysql database database-design


【解决方案1】:

选项 1、2 和 3 有一个非常严重的缺陷:当有人想出一个新属性时,您必须修改基础表架构。在选项 1 的情况下,引入新设备类型的可能性使问题更加复杂。你有多确定这组属性在任何时候都是固定的?如果中断或告诉客户不,您不能拥有新属性,您会有多高兴?

如果您很可能对常用属性进行查询,您可能会尝试混合使用 3 和 4,在拆分属性类型而不是设备类型时会抛出一些 2,这似乎更加不稳定。如果我理解正确,选项 4 是选项 1 的正常形式版本,它解决了其所有固有问题(稀疏性和脆性)。

INVENTORY( id*, model, manufacturer, serial )
ATTRIBUTE( id*, name, type, description )
INVENTORY_FACT_STRING( inv_id*, attr_id*, value )
INVENTORY_FACT_NUMBER( inv_id*, attr_id*, value )
INVENTORY_FACT_LIST_STRING( inv_id*, attr_id*, ordinal*, value )

等等

【讨论】:

  • 新设备的推出是肯定的,想要事后添加属性的可能性不大,但可能。中断不是问题,但说不能添加新属性是不可能的,因为需要能够添加新设备,我不能肯定地说当前属性将涵盖所有未来的情况。
  • 这听起来很像 EAV。不要害怕!
  • 哇,这里的每个人都对 EAV 给予了压倒性的支持。出乎我的意料,令人惊讶的是,在你的研究开始时的一些负面文章真的会让你偏离轨道!我会试一试。谢谢大家!
【解决方案2】:

Martin Fowler 在他的一本书和他的网站上概述了备选方案 1、2 和 3。

Single Table Inheritance (option 1)

Concrete Table Inheritance (option 2, sort of)

Class Table inheritance (option 3)

我的偏好是选项 3。每个选项在总体方案中都有自己的位置。

EAV 非常适合动态添加新属性。但是当需要将数据转化为有用的信息时,EAV 数据库可能是一场噩梦。

我有一个更长的答案,我会按需发布。

【讨论】:

    【解决方案3】:

    我认为您遇到了常规的数据库规范化。 您需要如下表格:

    Items -> Id, Name, Model, Brand Id
    Brands -> Id, Name
    Attribute Names -> id, name
    Attribute Mappings -> Id, Names Id, Items Id, Attribute Description
    

    如果有多个属性,则在属性表中列出并与产品ID等相关联。尝试提出第三种规范化形式

    Database Normalization

    【讨论】:

    • 这是我提到的EAV模型,不是吗?
    • 我不认为这是“常规”。
    【解决方案4】:

    任何 SQL 数据库都很难解决这个问题。 MySQL 没有很好的答案。

    1) 有效,您可以为重要的设备类型添加一些视图。它减少了连接数并允许对每个字段进行查询和索引。

    2) 您可以在视图中使用联合所有查询。 PostgreSQL 和 Informix 具有表继承。

    3) 这通常是一种实现选择。同样,您可以使用视图进行连接。

    4) PostgreSQL、Informix、Oracle、IBM DB2 和 MS SQL Server 支持 XML 数据类型来实现值对。

    在更高级别上,您可以使用 XML 开发设备的元模型。然后您可以使用此模型生成架构 SQL 查询和 CRUD 代码。

    【讨论】:

      猜你喜欢
      • 2015-07-29
      • 2014-04-16
      • 1970-01-01
      • 1970-01-01
      • 2011-02-26
      • 2010-09-05
      • 2010-09-23
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多