views:

73

answers:

4

If I were to have an online shopping website that sold apples and monitors and these were stored in different tables because the distinguishing property of apples is colour and that of monitors is resolution how would I add these both to an invoice table whilst still retaining referential integrity and not unioning these tables?

                        Invoices(InvoiceId)
                                 |
                  InvoiceItems(ItemId, ProductId)
                                 |
                       Products(ProductId)
              |                                            |
Apples(AppleId, ProductId, Colour)   Monitors(MonitorId, ProductId, Resolution)
+2  A: 

In the first place, I would store them in a single Products table, not in two different tables.

In the second place, (unless each invoice was for only one product) I would not add them to a single invoice table - instead, I would set up an Invoice_Products table, to link between the tables.

I suggest you look into Database Normalisation.

Mark Bannister
If I stored them in a single combined products table, wouldn't that mean having a nullable Resolution and Colour columns that would only be populated depending on whether that specific product is a Monitor or an Apple? Normalisation suggests only having columns in a table if they directly relate to the Primary Key.Regarding the link table, good point. I've over-simplified the question and missed this detail. I'll update the question.
Rob
Invoices(InvoiceId) | InvoiceItems(ItemId, ProductId) | Products(ProductId) | |Apples(AppleId, ProductId, Colour) Monitors(MonitorId, ProductId, Resolution)
Rob
A: 

So Invoice table has a ProductID FK, and a ProductID can be either an AppleID (PK color) or MonitorID (PK resolution)?

If so, you can introduce a ProductTypeID with values like 0=apple, 1=monitor, or a isProductTypeApple boolean if there's only ever going to be 2 product types, and include that in the ProductID table PK.

You also need to include the ProductTypeID field in the Apple table and Monitor table PK.

Beth
A: 

I like name-value tables for these...It might be easier to redesign so it goes 'Product' and then 'product details'...product details holds the product id, the detail type and then the value. This would allow you to hold apples and monitors in the same table regardless of identifying attribute (and leave it open for other product to be added later on).

Similiar approach can be taken in the invoice table...have a 'product_type' column that tells you which table to look into (apple or monitor) and then a 'product_id' that references whatever ID column is in the apple/monitor table. Querying on a setup like this is a bit difficult and may force you to use dynamic sql...I'd only take this route if you have no control over doing the redesign above (and other answers posted here refer to)

First solution is preferential I would think...change the design on this db to the name value pair with the products and you'll save headaches writing your queries later.

M.E.
Wouldn't having name-value tables mean only having String (varchar) values? What if some of the attributes were numeric or date values that needed to be comparable / type safe? Obviously the queries / user interfaces here are complex, but the main difficulty I face seems to be the DB structure first and foremost.I thought perhaps I could make 4 different name-value tables, each containing a different type (int, float, datetime, varchar) but that created a new problem of knowing how to link to the correct name-value table!
Rob
Yes you are right with this limitation...varchar or nvarchar are your only data types that could handle pretty much any data type thrown in it. It's possible to have a 'datatype' column to go with the value, though it's forcing you into more dynamic sql later on to do converts to varying data types. Any reason you couldn't store it as varchar and do a convert to whatever data type you need when referencing it in your queries?
M.E.
A: 

A question for your data model is You need a reference scheme will you use to identify products? Maybe SKU ?

Then identify each apple as a product by assigning an SKU. Likewise for monitors. Then use the SKU in the invoice item. Something like this:

product {sku} key {sku};

invoice_item {invoice_id, sku} key {invoice_id, sku} ;

apple {color, sku} key {color} key {sku};

monitor {size, sku} key {size} key {sku};

with appropriate constrains... in particular, the union of apple {sku} and monitor {sku} == product {sku}.

hash1baby