Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Creating a relationship between three tables

There are many ways I can think of to hack this together, but I want to know what the best practice is here:

I have three tables. Products, Pricelists and Prices.

One product can belong to many pricelists.

One pricelist can belong to many products.

This is a many to many relationship and as far as I know requires a Junction table (pricelist_products). Which works well.

Now, one product within a pricelist can have multiple prices. A product is only ever given a price once its within a pricelist.

What I've thought about here is using the ID from the junction table 'pricelist_products' as a foreign key within the prices table, but this feels really.... hacky?

ER Diagram

Fishy example:

Product 1 - Fishing Rod.

Pricelist A - Fishermen.

Pricelist B - Fishingshop.

Pricelist A, Product 1, price 1: (Monthly repayments option 1 (no deposit))

Pricelist A, Product 1, price 2: (Monthly repayments option 2 (with deposit))

Pricelist A, Product 1, price 3: (Quaterly repayments)

Pricelist B, Product 1, price 1: (Quaterly repayments)

like image 320
Mason8r Avatar asked Nov 12 '22 02:11

Mason8r


1 Answers

What I've thought about here is using the ID from the junction table 'pricelist_products' as a foreign key within the prices table, but this feels really.... hacky?

Maybe the issue here is just one of perspective. The purpose of the junction table is to uniquely define each combination within your many-to-many relationship (initially: pricelist to product). This can be achieved in the junction table with the fields product_id and pricelist_id alone, and without the surrogate key id.

Of course, if you defined your junction table with PRIMARY KEY (product_id, pricelist_id), this table would lack the ability to uniquely define combinations when price is considered. So you add a third id to the junction table. It appears you were looking at this field as a necessary surrogate key when defining a relationship between only two tables. However, since the real utility of this field relates to the third table, you might name it price_id instead, name your junction table pricelist_product_price, and define the primary key on all three fields (for example). This more clearly demonstrates the purpose of each field, and so may not feel "hacky" in practice.

I don't know if this is a best practice for database design, but keep in mind that there is no reason you must fully normalize every database. You want good performance with reasonable amount of flexibility and scalability (this can mean one thing for a casual blog, and quite another thing for a small business), and that can often be achieved with some degree of non-normalized design.

Edited to add: Okay, there is one other change I forgot to mention that would fall under "good" design or best practices. In your picture, you have two ID fields in the price table where one would be sufficient. As @Gilbert Le Blanc pointed out, you should try to avoid ambiguous field names like having multiple id fields, even if they are in different tables. This will help you see the utility of your fields, identify natural keys, and eliminate redundancies.

like image 181
Air Avatar answered Nov 15 '22 06:11

Air