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.), the
Alternatives 1, 2, and 3 are outlined by Martin Fowler in one of his books, and on his website.
Single Table Inheritance (option 1)
Concrete Table Inheritance (option 2, sort of)
Class Table inheritance (option 3)
My preference is option 3. Each one has its place in the general scheme of things.
EAV accomodates adding new attributes on the fly very well. But when it comes time to turn the data into useful information, an EAV database can be a nightmare.
I have a longer answer, which I will post on demand.
It's hard problem to solve for any SQL database. There is no great answer for MySQL.
1) Works and you can add some views for important equipment types. It reduces the number joins and allows queries and indexes on each field.
2) You can use a union all query in view. PostgreSQL and Informix have table inheritance.
3) This is frequently an implementation choice. 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.
At higher level you could develop a meta model of the equipment in XML. Then you can use this model to generate schema SQL queries and CRUD code.
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. In the case of Option 1 the problem is compounded by the possibility that a new equipment type will be introduced. 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. Option 4, if I understand correctly, is a normal form version of option 1 which solves all its inherent problems (sparseness and brittleness).
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.
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
Database Normalization