views:

136

answers:

6

I have a doubt regarding a database design, suppose a finance/stock software

in the software, the user will be able to create orders, those orders may contain company products or third-party products

typical product table:

PRIMARY KEY INT productId  
KEY INT productcatId
KEY INT supplierId
VARCHAR(20) name
TEXT description
...

but i also need some more details in the company products like:

INT instock  
DATETIME laststockupdate  
...

The question is, how should i store the data? I'm thinking in 2 options:

1 -
Have both company and third-party, products in a single table,
some columns will not be used by third-party products
identify the company products are identified by a supplier id

2 -
Have the company products and third-party in separated tables

3 - [new, thanks RibaldEddie]
Have a single product table,
company products have additional info in a separated table

Thanks in advance!

A: 

one table for products with a foreign key to the Vendor table; include your own company in the Vendor table

the Stock table can then be used to store information about stock levels for any product, not just yours

Note that you need the Stock table anyway, this just make the DB model more company-agnostic - so if you ever need to store stock level information about third-party products, there's no DB change required

Steven A. Lowe
Thats what i thought, but how to keep track of the company product stocks?
arthurprs
The question doesn't include any requirements for storing information about a Vendor, just that some products have extra information. Don't add domain entities where it isn't necessary!
RibaldEddie
@[RibaldEddie]: interesting viewpoint - so what do you suppose SupplierId means?
Steven A. Lowe
@[arthurprs]: the same way as any other product stock - the fact that your company makes the item rather than company X should be immaterial to the database...
Steven A. Lowe
@[arthurprs]: unless you don't need to keep track of stock for third-party products (which seems...odd; is everything drop-shipped? how do you handle backorders?). A second stock table will suffice in any case, if just may not have any third-party product entries in it. But a product is still a product, regardless of who the supplier is...
Steven A. Lowe
@Steven A. Lowe: I actually missed the use of the supplierId field, so you're right you could have put some information in a Supplier table. But the question wasn't about storing Supplier specific information, it was about storing Product specific information that only applied to some Products.
RibaldEddie
@[RibaldEddie]: see edits
Steven A. Lowe
+1  A: 

To be honest, I think the choice of #1 or #2 are completely dependent upon some other factors (I can only thing of 2 at the moment):

  1. How much data is expected (affecting speed of queries)
  2. Is scalability going to be a concern anywhere in the near future (I'd guess within 5 years)

If you did go with a single table for all inventory, then later decided to split them, you can. You suggested a supplier identifier of some sort. List suppliers in a table (your company included) with keys to your inventory. Then it really won't matter.

As far as UNION goes, it's been a while since I've written raw Sql - so I'm not sure if UNION is the correct syntax. However, I do know that you can pull data from multiple tables. Actually just found this: Retrieving Data from Multiple Tables with Sql Joins

dboarman
I don't expect too much data, so i'm preferring what makes my life easier ^^About the UNION, i just tested, it works:SELECT name FROM t_items WHERE instock > 0UNIONSELECT name FROM t_suplieritems
arthurprs
Excellent...I guess I need to shake the dust off my Sql texts... ;)
dboarman
+2  A: 

You didn't mention anything about needing to store separate bits of Vendor information, just that a type of product has extra information. So, you could have one products table and an InHouseProductDetails table that has a productId foreign key back to the products table that stores the company specific information. Then when you run your queries you can join the products table to the details table.

The benefit is that you don't have to have NULLable columns in the products table, so your data is safer from corruption and you don't have to store the products themselves in two separate tables.

Oooo go with 3! 3 is the best!

RibaldEddie
Great! I can identify the company product by it's supplierId and manipulate the table with additional stock info. Question: null data can hurt my database?
arthurprs
"Null data your database always can hurt. How one handles null data shows the path to true happiness"
MadMurf
Yes null data can hurt your database: http://www.databasedesign-resource.com/null-values-in-a-database.html HOWEVER, I often do find myself creating tables that allow for null values in columns. Sometimes for everyone's sake keeping it simple by being imprecise is more valuable than arguing over how much precision and correctness is needed to solve a particular quibble.
RibaldEddie
Great answer, though I thought I might expand a shred. Ribald arrives at his answer by obeying rules of normalization. http://en.wikipedia.org/wiki/Database_normalization In my opinion, 3NF in database design usually leads to database designs that are both useable and well-designed. Higher order forms just get hairy. See also: http://papers.ssrn.com/sol3/papers.cfm?abstract_id=905060 for why normalization may not be your end-all-be-all for database design
Reed Debaets
A: 

I would advice on using point #1. What happens when another supplier comes along? It's also more easy to extend on one product table/produst class.

Saif Khan
A: 

Take into account the testing of your application also. Having all data in one table raises the possible requirement of testing both the 3rd Party & Company elements of your app for any change to either.

If you're happy that your Unit test would cover this off its not so much of a worry... if you're relying on a human tester then it becomes more of an issue when sizing the impact of changes.

Personally I'd go for the one products table with common details and separate tables for the 3rd party & Company specifics.

MadMurf
+1  A: 

I agree with RibaldEddie. Just one thing to add: put a unique constraint on that foreign key in your InHouseProductDetails table. That'll enforce that it's a one-to-one relationship between the two tables, so you don't accidently end up with two InHouseProductDetails records for one product (maybe from some dataload gone awry or something)

Constraints are like defensive driving; they help prevent the unexpected...

Evan
good suggestion
arthurprs