I was thinking recently of the best way to tackle the following problem, which is similar if not the same problem as you're facing allspiritseve...
If you have a product, which could have a variable number of attributes, a variable number of values per attribute, with each attribute value potentially decreasing or increasing the price of the overall product, how do you store this in a database? I thought of a couple of solutions straight up, but none of them achieved all the goals I was after. I eventually thought of the following solution which only requires two tables, while at the same time allows a lot of flexibility...
Code:
------------------
Products
------------------
ID
Title
Base_Price
----------------------
Product Attributes
----------------------
ID
Product_ID
Attribute
Value
Price_Diff
Order
ID Title Base_Price
-- ----- ----------
45 T-Shirt $15
ID Product_ID Attribute Value Price_Diff Order
-- ---------- --------- ----- ---------- -----
384 45 colour blue +$0 1
385 45 colour green +$0 0
386 45 colour orange +$0 2
387 45 size small +$0 0
388 45 size medium +$1 1
389 45 size Large +$2 2
390 45 material Velvet +$5 2
391 45 material Cotton +$0 0
392 45 material Polyester -$3 1
As you can see, this allows one to have an unlimited number of attributes, and attribute values per product. It also allows any combination of attributes/value with dynamic pricing. I added the "Order" column just to demonstrate the extensibility. This column defines the display order of the values.
I'm yet to find any flaw with this setup (but please by all means try and find one). Querying the product attributes table should be reasonably quick as long as you have the first 3 columns indexed (or 4 depending on how you plan to use the table). On that note, I'm not sure how you would manage SKU's if every combination needed a unique SKU. I guess in such a circumstance where SKU's are required, you really would need to treat every attribute combination as a completely separate product. I also haven't thought of yet, how you could stop/block certain combinations (maybe an exclude column in the product_attr. table which references different product_attr. ID's?).
EDIT: I just thought of a possible way to handle SKU's without modifying the above solution to the original problem. All it would involve is having a separate SKU lookup table. This table would be relatively simple with only two fields. A side-effect of this also allows blocking of certain attribute value combinations if a matching SKU isn't found.
Code:
-------------------
SKU Lookup
-------------------
SKU
Attributes
SKU Attributes
--- ----------
FH5636 384:387:390
FH5637 384:388:390
FH5638 384:389:390
FH5639 385:387:390
FH5640 385:388:390
FH5641 385:389:390
FH5642 386:387:390
FH5643 386:388:390
FH5644 386:389:390
The important thing to note here is that the order of the concatenated product_attr. ID values are alphabetical. This ensures that lookups are reliable. Alternatively, you can use the values of the attributes (ie. green:large:velvet) to achieve a similar result. Please let me know if there are any major flaws with this solution.
Bookmarks