13

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

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

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

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

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

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

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

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

4

4 回答 4

5

选项 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 )

等等

于 2012-07-21T04:10:13.933 回答
3

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

单表继承(选项 1)

具体表继承(选项2,排序)

类表继承(选项 3)

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

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

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

于 2012-07-21T08:37:25.930 回答
1

我认为您面临常规的数据库规范化。您需要以下表格:

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

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

数据库规范化

于 2012-07-21T04:13:34.907 回答
0

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

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

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

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

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

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

于 2012-07-21T04:07:45.313 回答