简体   繁体   中英

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图

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)

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.

If you would not use anywhere else the relation between products and price lists but for prices then an alternative design is like this:

-Table products with fields: id, others

-Table pricelists with fields: id, others

-Table prices with fields: id (autoincrement), product_id, pricelist_id, price

and you would define index (not unique) on the pair of fields product_id, pricelist_id

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM