我正在尝试创建一个包含设备列表的数据库。所有设备都具有某些共同属性(例如制造商,型号#,序列号等),然后还有其他特定于某个设备的属性(即,调制解调器将具有访问权限#,而太阳能电池板将具有输出容量)。我不确定如何用良好的数据库设计原则来表示这些不断变化的属性,我尝试过在网上搜索,但我并不完全确定要搜索什么。
我想出了以下可能的解决方案以及我对它们的初步想法:
拥有一个包含所有可能属性的大表,并将null放在不适用的位置。显然这有一些缺陷。
为每种设备类型设置单独的表格。这似乎可能是一个噩梦,如果我想打印所有设备的列表,我怎么知道要查找哪些表?
拥有一个包含公共属性的表,以及使用外键访问的每种设备类型的其他表,以存储额外的属性。我可能会做这个工作,但它会很麻烦,只是感觉不是一个很好的解决方案。
实体 - 属性 - 值类型模型。只是看起来不太适合我想做的事情。
我没有很多数据库的经验,所以我在学习这里,任何与此问题相关的链接或“必读”数据库设计的文章都将受到赞赏。谢谢!
编辑: 首先,我发现我需要谷歌“继承映射”,这可能会帮助其他有类似问题的人。为了解决这个问题,我最终使用了#2和#3的混合体。它实际上非常简单,运行良好,并且解决了在没有EAV复杂性的情况下添加额外设备类型的问题。感谢所有的意见和建议!
答案 0 :(得分:4)
选项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 )
等
答案 1 :(得分: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数据库可能是一场噩梦。
我有更长的答案,我会按要求发布。
答案 2 :(得分:1)
我认为你面临着常规的数据库规范化。 您需要以下表格:
Items -> Id, Name, Model, Brand Id
Brands -> Id, Name
Attribute Names -> id, name
Attribute Mappings -> Id, Names Id, Items Id, Attribute Description
如果有多个Attribue,请在属性表中列出并与产品ID等关联。尝试提出第3个规范化表单
答案 3 :(得分:0)
解决任何SQL数据库都是一个难题。 MySQL没有很好的答案。
1)正常工作,您可以为重要设备类型添加一些视图。它减少了连接数,并允许每个字段上的查询和索引。
2)您可以在视图中使用union all查询。 PostgreSQL和Informix具有表继承。
3)这通常是一种实施选择。同样,您可以使用视图进行连接。
4)PostgreSQL,Informix,Oracle,IBM DB2和MS SQL Server都支持XML数据类型来实现价值对。
在更高级别,您可以使用XML开发设备的元模型。然后,您可以使用此模型生成模式SQL查询和CRUD代码。