If you know most of the attributes your products will have ahead of time, you could hard-code them into the tables for different product types, such as:
books
-----
id
price
title
author
isbn
etc....
mobile_device
-------------
id
price
size
colour
model
etc...
You could also try something like this:
base_product
------------
id
base_price
product_type
book_product_attributes
-----------------------
base_product_id (FK to base_product)
title
author
mobile_dev_product_attributes
-----------------------------
base_product_id (FK to base_product)
model
colour
This way, you can group your common attributes in a base product table, and more specific attributes are stored in other tables when necessary.
This will work if your product types are mostly static. On the other hand, if you have no idea what product types or attributes you'll need in the future, and entity-attribute-value based system might work better. The idea behind that model is that you have a table for the different attributes you might have, a table for the different entities in your system, and a table for the attribute values that an entity has. Example:
entities
--------
id
attributes
----------
id
name
values
------
id
entity_id
attribute_id
value
The data might look like this:
entities
ID
----
1
attributes
ID | name
----------
1 | title
2 | author
values
ID | attribute_id | entity_id | value
---------------------------------------------------------
1 | 1 | 1 | "Great Expectations"
2 | 2 | 1 | "Charles Dickens"
This data very briefly describes a product which has two attributes: title, and author, with the valus "Great Expectations" and "Charles Dickens", respectively.
Be aware that using an EAV database can make queries very awkward. With enough data and the wrong model design, it's also possible to run into performance problems. The example I gave was very simple but more realistic designs tend to be more complicated than that. It can take time to get this kind of database correct and it's not always the best solution.
I'd recommend creating a table which encompasses subnets, VLANs and VPLSs; you can then have a simple self-join table. If these three concepts each have a significant number of unique fields, you can use vertical partitioning and create a sister table for each of the three. Using pseudo-code:
* Networks
NetworkID PK
* Locations
LocationID PK
* SubNetworks -- This concept encompasses SubNets, VLANs, and VPLSs
SubNetworkID PK,
NetworkID NOT NULL REFERENCES Networks
* SubNetworkLocations
SubNetworkID NOT NULL REFERENCES SubNetworks,
LocationID NOT NULL REFERENCES Locations,
PRIMARY KEY (SubNetworkID, LocationID)
* SubNets
SubNetworkID PK REFERENCES SubNetworks
-- Additional fields specific for this type of sub-network
* VLANs
SubNetworkID PK REFERENCES SubNetworks
-- Additional fields specific for this type of sub-network
* VPLSs
SubNetworkID PK REFERENCES SubNetworks
-- Additional fields specific for this type of sub-network
* SubNetworkRelationships
SubNetworkA NOT NULL REFERENCES SubNetworks,
SubNetworkB NOT NULL REFERENCES SubNetworks,
PRIMARY KEY (SubNetworkA, SubNetworkB),
UNIQUE (SubNetworkB, SubNetworkA) -- For efficient querying from the other direction
As with any many-to-many table, be sure your sproc for inserting into SubNetworkRelationships
checks for the existence of both { A, B } and { B, A } before inserting a new row. You can use check constraints to prevent a sub-network from relating to itself.
In this model, there's no RDBMS-level enforcement of the rule "if two sub-networks are related, they must have all of the same locations." I'm going to go out on a limb and assume that all such tied-together sub-networks must belong to the same Network
, too. If you really want this:
* Networks
* Locations
* SubNetworkGroups
SubNetworkGroupID PK,
NetworkID NOT NULL REFERENCES Networks
* SubNetworkGroupLocations
SubNetworkGroupID NOT NULL REFERENCES SubNetworkGroups,
LocationID NOT NULL REFERENCES Locations,
PRIMARY KEY (SubNetworkGroupID, LocationID)
* SubNetworks
SubNetworkID PK
* SubNetworkGroupMemberships
SubNetworkGroupID NOT NULL REFERENCES SubNetworkGroups,
SubNetworkID NOT NULL REFERENCES SubNetworks,
PRIMARY KEY (SubNetworkGroupID, SubNetworkID)
* SubNets
* VLANs
* VPLSs
A group of SubNetwork
s belong to one Network
but zero or more Locations
. A SubNetwork
can belong to multiple groups. You'd still need to enforce that the various groups a sub-network belongs to all have the same locations, so I'm not sure this buys you much.
Best Answer
Why have product_inventory at all?
inventory