Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

Loach's avatar
Level 11

Database design

I have three Products that can be purchased. I have a model for each of the products. Product1, Product2, Product3. I realize most people would say that I should have a generalized Product but that is not the way I want to do it. These are the only 3 products I will ever be selling.

People can purchase these products and this is where I am stuck on the database design. I know I should probably have and Orders Table, A Products Table and an Intermediate table. But how should I design this with the three separate Products?

0 likes
8 replies
sr57's avatar

I realize most people would say that I should have a generalized Product

me too :-)

These are the only 3 products I will ever be selling.

Never mind, point 1) always ok

but that is not the way I want to do it

clear

Your order table should have 3 fields each linked to one product table.

Loach's avatar
Level 11

I am gonna do it the right way I think. Create Categories.. then have Order, Products, and Order_Products table.

martinbean's avatar
Level 80

@loach That approach can still lead to problems.

You should have an OrderItem model that represents line items in an order (so a one-to-many relationship). You should then copy the product name and price (at least) to the OrderItem model. You could have a foreign key from the OrderItem model to the Product model, but don’t rely on this foreign key being present. If the product is soft-deleted or force-deleted in the future, then your application is going to break.

Similarly, if the product‘s name or price is updated, you don’t want that propagating through to orders, which is why I said you’ll need to copy the name and price to the OrderItem model. If a customer buys Product A at $9.50 today, but then two days later you change the price of the product to $9.00, then the customer’s order still needs to say they bought their product at $9.50. If you just use a foreign key and update the product’s price, the customer’s order is going to show a different price to what they actually paid.

Loach's avatar
Level 11

Thanks for the tips. I will try to get my head around what you are saying. If it is not too much trouble could you show me the setup for all this?

I am confused as to what all the tables I need are with your approach. Do I still need the intermediate table etc. I was going by a diagram i found online. Getting into many to many relationships is a real weak point for me in database design.

martinbean's avatar

@loach What I explained isn’t too dissimilar to that article. They’ve just called their model OrderDetails instead of OrderItem.

The issue is relying on a product_id column in that table. If you update a product then those changes are going to appear in historical orders. You don’t want that.

Similarly, if you delete the related product at a later date, then your application is going to break when a customer tries to a view an order that contains a now-deleted product, because you’ll be trying to retrieve details like name from a record that no longer exists.

Loach's avatar
Level 11

OK so what you are saying is just copy the Product price and name etc to what they call the OrderDetails table and drop the product_id from that table. Correct?

Thanks

martinbean's avatar

You can still have a foreign key from the order items table to your products table. Just make it nullable and don’t rely on the related product for anything unless you want runtime errors.

Please or to participate in this conversation.