简体   繁体   English

良好的数据库设计,可变数量的属性

[英]Good database design, variable number of attributes

I'm trying to create a database that contains a list of equipment. 我正在尝试创建一个包含设备列表的数据库。 All of the equipment will have certain common attributes (such as manufacturer, model #, serial #, etc.), then there are other attributes that are specific to a certain piece of equipment (ie, a modem will have an access #, whereas a solar panel will have an output capacity). 所有设备都具有某些共同属性(例如制造商,型号#,序列号等),然后还有其他特定于某个设备的属性(即,调制解调器将具有访问权限#,而太阳能电池板将具有输出容量)。 I'm not sure how to represent these changing attributes with good database design principles, I've tried searching the web, but I'm not entirely sure what to search for. 我不确定如何用良好的数据库设计原则来表示这些不断变化的属性,我尝试过在网上搜索,但我并不完全确定要搜索什么。

I've come up with the following possible solutions and my initial thoughts on them: 我想出了以下可能的解决方案以及我对它们的初步想法:

  1. Have one big table with every possible attribute and just put null where it's not applicable. 有一个包含每个可能属性的大表,只需将null放在不适用的地方。 Obviously this has some flaws. 显然这有一些缺陷。

  2. Have a separate table for each equipment type. 为每种设备类型单独设置一个表。 This seems like it might be a nightmare to use, if I want to print a list of all the equipment, how do I know which tables to lookup? 这似乎可能是一个噩梦,如果我想打印所有设备的列表,我怎么知道要查找哪些表?

  3. Have a table with the common attributes, and other tables for each equipment type accessed with a foreign key to store the extra attributes. 有一个包含公共属性的表,以及使用外键访问的每个设备类型的其他表来存储额外的属性。 I could probably make this work, but it would be cumbersome and just doesn't feel like a very good solution. 我可能会做这个工作,但它会很麻烦,只是感觉不是一个很好的解决方案。

  4. An entity-attribute-value type model. 实体 - 属性 - 值类型模型。 Just doesn't seem like a very good fit for what I want to do. 只是看起来不太适合我想做的事情。

I don't have a lot of experience with databases so I'm learning as I go here, any links relating to this problem or "must read" articles on database design would be appreciated. 我没有很多数据库的经验,所以我在学习这里,任何与此问题相关的链接或“必读”数据库设计的文章都将受到赞赏。 Thanks! 谢谢!

EDIT: First off, I found out that I needed to Google "Inheritance mapping", that might help anyone else that has a similar question. 编辑:首先,我发现我需要谷歌“继承映射”,这可能会帮助其他有类似问题的人。 To solve the problem I ended up using a hybrid of #2 and #3. 为了解决这个问题,我最终使用了#2和#3的混合体。 It was actually pretty easy, works well, and solves the problem of adding additional equipment types without the complexity of EAV. 它实际上非常简单,运行良好,并且解决了在没有EAV复杂性的情况下添加额外设备类型的问题。 Thanks for all the comments and suggestions! 感谢所有的意见和建议!

Options 1, 2, and 3 share one very serious flaw: you have to modify the underlying table schema when someone dreams up a new attribute. 选项1,2和3共享一个非常严重的缺陷:当有人梦想新属性时,您必须修改基础表模式。 In the case of Option 1 the problem is compounded by the possibility that a new equipment type will be introduced. 在备选方案1的情况下,引入新设备类型的可能性使问题更加复杂。 How sure are you that the set of attributes is fixed for all time? 你有多确定这组属性是否一直都是固定的? How happy will you be to take outages or tell the client that no, you can't have a new attribute? 您是多么高兴能够停电或告诉客户不,您不能拥有新的属性?

If you are very likely to do queries off common attributes, you might try a hybrid of 3 and 4, with a dash of 2 thrown in splitting on attribute type rather than equipment type, which seems much more volatile. 如果您很可能对常见属性进行查询,则可以尝试使用3和4的混合,在属性类型而不是设备类型上分割时会出现短划线2,这似乎更不稳定。 Option 4, if I understand correctly, is a normal form version of option 1 which solves all its inherent problems (sparseness and brittleness). 如果我理解正确,选项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 )

etc. 等等

Alternatives 1, 2, and 3 are outlined by Martin Fowler in one of his books, and on his website. Martin Fowler在他的一本书和他的网站上概述了备选方案1,2和3。

Single Table Inheritance (option 1) 单表继承(选项1)

Concrete Table Inheritance (option 2, sort of) 具体表继承(选项2,排序)

Class Table inheritance (option 3) 类表继承(选项3)

My preference is option 3. Each one has its place in the general scheme of things. 我倾向于选项3.每个人都有其在一般方案中的地位。

EAV accomodates adding new attributes on the fly very well. EAV可以很好地动态添加新属性。 But when it comes time to turn the data into useful information, an EAV database can be a nightmare. 但是,当需要将数据转换为有用的信息时,EAV数据库可能是一场噩梦。

I have a longer answer, which I will post on demand. 我有一个更长的答案,我将按要求发布。

I think that you faced a regular database normalization. 我认为你面临着常规的数据库规范化。 You need tables like: 您需要以下表格:

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

In case if there is more than one Attribue, list then in Attribute Tables and associate with Product Id etc. Try to come up with 3rd normalized form 如果有多个Attribue,请在属性表中列出并与Product Id等关联。尝试提出第3个规范化表单

Database Normalization 数据库规范化

It's hard problem to solve for any SQL database. 解决任何SQL数据库都是一个难题。 There is no great answer for MySQL. MySQL没有很好的答案。

1) Works and you can add some views for important equipment types. 1)工作,您可以为重要的设备类型添加一些视图。 It reduces the number joins and allows queries and indexes on each field. 它减少了连接数,并允许每个字段上的查询和索引。

2) You can use a union all query in view. 2)您可以在视图中使用union all查询。 PostgreSQL and Informix have table inheritance. PostgreSQL和Informix具有表继承。

3) This is frequently an implementation choice. 3)这通常是一种实现选择。 Again, you can use views for the joins. 同样,您可以使用视图进行连接。

4) PostgreSQL, Informix, Oracle, IBM DB2 and MS SQL Server have an XML data type support to implement the value pairs. 4)PostgreSQL,Informix,Oracle,IBM DB2和MS SQL Server都支持XML数据类型来实现值对。

At higher level you could develop a meta model of the equipment in XML. 在更高级别,您可以使用XML开发设备的元模型。 Then you can use this model to generate schema SQL queries and CRUD code. 然后,您可以使用此模型生成模式SQL查询和CRUD代码。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM