E-Commerce Database Design for Orders Table - mysql

I am designing a schema for E-Commerce app, in which I would have 3 tables i.e Orders, Products, Customers.
So Should we store customer_id and product_id in Orders table straightaway.
The limitation to this is when a product or customer updates their attributes( i.e product price or customer name ), the orders table doesn't reflect them.
For Ex: A Customer bought a product at $10, but later on the product price gets updated to $20.So now when we are referring to this order by product id we would get the result as it was bought at $20 instead of $10.
SOLUTION 1:
One solution would be to insert a new row into products table whenever an updates occur and perform a soft delete to that product so that it can be referenced from orders table.
SOLUTION 2:
Store most of the details in product and customer details in orders table.
SOLUTION 3:
Create a temporary table of customers and products whenever there is an update to these tables.
I am very much open to any other suggestions.

One thing that you seem to be missing is a orderLineItem table for anything other than the most simple solution, where there is one product/order.
Now, that being said, you can do the products table in several ways.
Assuming that price is your only variable in the products table that you want to change, you can have a separate pricePoints table, that would store the price for any item at any given time. You would then use the ID from this table in your orders table and use that to get to the productID from the products table. A slightly more inefficient way to store this (but faster for retrieval) would be to store both the productId and the pricePointId in the orders table.
You could also do this by simply storing the price paid amount in the orders table. This gives you a little more flexibility to add discounts and pricing rules. You do need to be concerned about auditing the price though if you do it this way. Why was this price charged for this line at this time is going to be a common question.
You need to know how much the customer paid for the product at any time. It's not so important to know how much the customer would have paid for the order if they bought it today.
Customers are a slightly different issue. Some of the information in a customer table is transient. Some of it has to be fixed for the order. Lets say that the customer has a name, address, billing address and shipping address. At the time of the order, the shipping and billing addresses have to be absolutely fixed. You don't want to go back in three weeks and discover that the shipping address was changed. But, by the same token, you might like the name to be updated if a customer changes their maiden name, for example.
Now, all that being said, we aren't going to design your schema for you. There are a lot of good resources out there for how to design a simple e-commerce database.

Related

MySQL Database analyze problem in some table

Tables and relations
Orders
Products
OrderItem
Relation between "Orders" and "Products" is many to many, and "OrderItem" table connects them.
The Problem
When a product is ordered, the product has specific in-price, out-price, and discount. For example, Product A is added at in-price 100, out-price 120, and discount 0, and suppose later, admin changes one of these properties. Now, because the order has a reference to product A, there is a difference between the product details when it was ordered and the present.
I want the ability to be able to update product details. How we can solve this in relational databases.
You need both.
In Product, which is the current value, that changes with a whim.
And in OrderItem, which is what the Product was actually sold for.
This is not a duplicate.
Product (
product-code,
name,
in-price, -- current, changing
out-price,
)
OrderItem (
customer-code, -- FK to Customer
datetime,
product-code, -- FK to Product
in-price, -- actual, historic
out-price,
discount,
quantity
)
When you promise a particular price to a customer, that goes with the customer order as, say, promised_price. That is, you must (for business reasons) have a separate, potentially redundant, "price" to indicate this.
Then whatever the admin does to the in- and out-prices or discount does not impact promises already made.
If the price goes down (or up), you could choose to give the new price to a customer, but that must be a separate, deliberate, action to change the promised_price.
The overhead of having lots of prices floating around for each product is small enough not to worry about the space consumed. An approach like this helps you be an honest businessman, with auditable books.

DB design for product pricing history for multiple suppliers

I am currently trying to design DB(mysql) structure for my project which is an online shop for wholesale company - I already created everything when it comes to products, it's multiple variants etc but I have problem with following which is price and historic data for multiple suppliers:
Please find below main assumptions for the project:
We are going to have several suppliers for products
Thanks to the above each product will have few different prices
We want to be able to have historic price data for each product with each supplier
Variant 1
At first I thought about adding 2 tables to my DB:
suppliers table: supplier_id, name
prices table: id, product_id, price_supplier1, price_supplier2, price_supplier3, timestamp
However in such example whenever we want to add another supplier we need to add row to the database (I am not a db expert but I guess that's not the best approach)
Variant 2
Another idea was just to have price table with following:
suppliers table: supplier_id, name
prices table: id, product_id, supplier_id, timestamp
However in this case if we have 5 suppliers we get 5 records created for 1 products every single day so let's imagine that we have only 1000 products and want to keep historic data for last 6 months - such table would grow very rapidly
So to summarize - which approach is better or maybe there is a different one that I could implement? Thanks a lot for any suggestions.
You should go with variant 2. It's best practice to avoid frequent table restructure, which you would have to do in variant 1 any time you add or remove a supplier (although MySQL is fairly fast at this in recent versions). Using a single column to identify the distinct supplier values is better. It also promotes query reuse when you don't have to worry about column values changing or being dropped altogether. Also, space shouldn't really be a concern. To give you an idea, if your prices table had 1,000,000 rows (6 months), it would be about 40-50M in size (assuming only a primary key index). MySQL also offers compression and partitioning to reduce storage as well, if that's really a concern.

Database queries for an assignment

I am working on a project and I am a newbie in database. I need help answering the questions below with the scenario and the database tables listed.
Database tables:
Product (pid:integer, timestamp:integer, name: string, price:real, location:string)
Customer (cid:integer, email: string)
Purchases (pid:integer, cid:integer, orderid:integer, amount:integer)
Totals (orderid:integer, cid:integer, totalprice:real, timestamp:integer)
Scenario:
A product ID can occur multiple times in the schema. Each time the location or price is updated, another line is added to the database with a timestamp that indicates the time of change. The name does not get changed, so the same pid will always imply the same name.
Totals is a summary of the purchases table which shows when the purchases were made, and what the combined price of all products were.
Whenever possible, try to do your projections as early as possible.
Use the above database and provide queries for the following problems:
Find the names of products that at some point in time cost more than e20.00 and the names of products that have at some point cost less than e0.10.
Find the email addresses of customers that have spent more than e200 at once.
Find the pids of products that have had at least one price change.
Find the names of products that have both been displayed at location ’5-12’ and ’A3’
Find the cid of customers that have bought each product that at some point cost less than e1.00
Find the cid of customers that are registered with the store but have made no purchases.
Find the cid of the customer(s) that have made the largest total purchase.
Find the most expensive product that has been purchased at least once by each registered customer.
Find the pids of products that have not been sold since timestamp 20150625 but have been sold at least once before that date.
The grocery store wants to improve its database. Write a query that returns a table that is basically the Purchases table plus the price of the product at the time of purchase.
Let's try to provide you a bit of help to start your project ❤
In query one, we need to work exclusively with table Products, and You want to find the name of those products with price above x and less than y.
First, the columns we want to get FROM the table:
SELECT name, price FROM Products
Then, as you need a query that get products more expensive than 20, and producs less expensive than 0.10, you could use the Condition BETWEEN reverted with NOT:
SELECT name, price FROM Products
WHERE price NOT BETWEEN 0.10 and 20
And you can order it to be more readable:
SELECT name, price FROM Products
WHERE price NOT BETWEEN 0.10 and 20
ORDER BY name ASC;
I'm not sure if this is what you need, but I hope it helps a bit!

SQL Database design - three tables: product, sales order, and purchase order - how to store product quantity?

I have three tables: product, sales_order (where I sell products) and purchase_order (where I buy products). Now I can think of two ways of keeping the quantity of each product:
Have a column in the product table called quantity; when inserting into sales_order, I subtract the quantity; when inserting into purchase_order, I add the quantity
Instead of storing the quantity in the product table, I calculate the quantity from the sales_order and the purchase_order table each time I need to get the product table
I am wondering if the second approach is preferable to the first one? I like the second one more because it doesn't store any redundant data; however, I am not so sure if calculating the quantity every time is a bit too much calculation. I am wondering what is the convention and best practice here? Thank you!
I would use the first one. Add a column to the product table in the coding u code -x amount when order and you would then display this in the order table. You could right a script for when the products get to a certain amount it emails you and tells u to replenish stocks. However the second would also work and sql is very powerful so i wouldnt wprry about it being ro demanding as it will prbably work it out faster than we can lol
I prefer the first one because in-memory calculations are faster than issuing select statements to check the sales orders and purchase orders assuming that the number of times the quantity value is retrieved is significantly more than the number of times the quantity value is updated.

How do I use lists in MySQL

How do I represent invoices into an MySQL table structure?
The invoice table has the following fields:
id
customer_id
services
tax
total_price
date
...
Now the services can contain one or more articles and, what makes it complicated, various prices. The actual price of a service is negotiated, there are seldom fixed prices because each customer has individual requirements. These items have to be listed on the invoice and the prices of each have to be listed and summarized + tax.
What is the best practice for this purpose? I want to make it normalized if possible, something more sophisticated than just saving an (serialized) array of service => price into the service field, if this is possible at all. Do I use a second table for each service + price and hold a list of IDs with foreign keys?
I think you should follow Has And Belongs To Many relationship. Fr that you use two more tables for this one is 'services' and other is 'invoice_services'
'services' table contain service info and its price etc.
'invoice_services' table will be the join table for 'invoice' and 'services' tables. 'invoice_services' table will contain 'service_id' and 'invoice_id'.
Then you can remove the column 'services' from 'invoice' table.
If you want to maintain negotiable price for each service, then you can add one more field 'custom_price' in 'invoice_services' table.
Then using joins you can fetch the relative data of any invoice.
Hope this may help :)