views:

426

answers:

6

I am designing a basic inventory system for a vendor.
They have many different product categories.
Each product category has many different properties.

A - x1, x2, x3, a1, a2, a3;
B - x1, x2, x3, b1, b2, b3, b4;
C - x1, x2, x3, c1, c2;

Laptop - Make, Price, Quantity, Processor, OS, Hard drive, Memory, Video Card etc 
Monitor - Make, Price, Quantity, Size, ContrastRatio, Resolution etc 
Server - Make, Price, Quantity, Processor, OS, Memory, Netowrking etc

Design1: Different tables for each category.
Design2: Common Table, property table.

What is the best approach?

A: 

Going with the second option will require a join for each query, going with the first option will make querying harder because you will have a number of tables and you now have to decide which one to query. I would prefer the second option because in the long run the application development is simpler (but I may be lazy).

Vincent Ramdhanie
+2  A: 

Definitely don't want to multiply schemas unnecessarily (Occam's rule, y'know). The standard way of arranging many-to-many relationships is simply an intermediate table:

Products
--------
ProductID


Categories
----------
CategoryID


ProductCategories
-----------------
ProductID
CategoryID

Its straightforward to query and an industry best practice.

Juliet
Yeah, like he said.. Products can belong to many categories and vice-versa, etc.. Good stuff. [Product]->[ProductCategory]<-[Category]
Tim
A: 

Usual design is common table for the most common properties and then a child table for each category with the special properties for that category.

Alternately you can use entity value structure but it is not generally recommended as it is hard to query and does not scale well.

One thing you will need to do that people often forget is to store the price at purchase in the record for the item in inventory (one of what I would consider the common properties). If you rely on a price in a product table, it will get updated as the price changes, but for accounting purposes that is not what was paid for the item. This can be very bad when you are audited or at tax time!

HLGEM
/me shudders You had to remind me about price points, discounts, tax exemption...
OMG Ponies
I shudder, too, I had to fix an inventory database that incorrectly used the product table to get prices.
HLGEM
+1  A: 

Without knowing more about your domain, I'd be inclined to use design 2. This will limit the number of tables and make queries on the different properties of multiple categories much more readable and efficient.

Design 1 would be worth consideration if you have a small number of categories that are static and each have different properties. If this is the case, you could still use design 2 by creating a property dictionary table. Here you would have a table that contains property property key/property name pairs. Then your category table can contain category id, property id, property value columns. This works well if all the properties have the same data type but can get awkward if they do not.

Matt Wrock
+1  A: 

Go with Design 1, a different table for each category.

Design 2 is going to be a pain if the attributes are not all the same data type. If not, it will force you to store them all as strings and write a lot of casting code. This also prevents easy DB level data type validation.

JohnFx
It really depends on the OPs requirements. If the OP expects categories to have widely different numbers of categories and datatypes, it might actually be a good idea to ditch the relational model entirely and go with CouchDB.
Juliet
+1 for CouchDB, but I'm thinking that probably isn't in the realm of things under his/her control.
JohnFx
A: 

"Design 2 is going to be a pain if the attributes are not all the same data type."

If the attributes are not all the same data type, then the properties such attributes represent cannot possibly be common.

Erwin Smout