How do I use lists in MySQL - 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 :)

Related

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.

MS Access 2010 Issue

Table1 feildes
Product{ID,Product,Quantity(in peices),Cost(per peice)}
table2
Customer{ID, Name, Type(local,sale's man)}
table 3
customer order{ID, date,customer*, product*,quntity,price}
here customer is coming from table 2 named as customer while product is coming from table1 named as products
i just want to show remaining items in order table. any can help me to make this happen?enter image description here
You mean you want to know how much of each product remains after filling orders? This is calculating inventory balance - a common topic. You need a table that records receipt of product, which is apparently your Products table but I think would be better titled ProductReceived. Do an aggregate query on ProductReceived and an aggregate query on Orders then do another query that joins the two and subtracts the latter from the former. Customer table not needed for this. Products table would just be a lookup table for product info - no Quantity or Cost fields as these belong in ProductReceived. Products table should have the selling price you want to charge.
You have misspelled 'piece' in your field names.
Advise no spaces, punctuation, or special characters in field names (underscore is only exception). Better would be Qty_Pieces.

Can I create a table structure with dynamic columns in MySQL?

I've created a stock control database which contains two tables (actually more than two, but these are the two that are relevant to my question): Stock, and Receipts
I would like the link between the stock in the stock table,and the stock in the receipts table to be a little more clearer, this would be fine if a customer could only order one item of stock per receipt, as i'd simply have a StockID column and a Quantity column in the Recipts table, with the StockID column as an FK to the ID in the Stock table, however, the customer can make a receipt with any number of items of stock on it, which would mean i'd have to have a large number of columns in the Receipts table (i.e. StockID_1, Quantity_1, StockID_2, Quantity_2 etc.)
Is there a way around this (can you have like a dynamically expanding set of columns in MySQL) within MySQL, other than what i've done at the moment, which is to have an OrderContents column with the following structure (which isn't enforced by the database or anything) StockID1xQuantity,StockID2xQuantity and so on?
I would post an image of the DB structure, but I don't have enough repuation yet. My lecturer mentioned something about that it could be done, by normalising the database into 4th or 5th normal form?
I'd suggest having 3 tables:
Stock (StockID) + stock specific fields
Receipt (ReceiptID) + receipt specific fields.
StockReceipt (ReceiptID, StockID, Quantity) (could have a StockReceiptID, or use StockID+ReceiptID as Primary Key)
A solution including prices could look like:
Stock (StockID, Price)
PriceHistory (StockID, Price, Date) or (DateFrom, DateTo)
Receipt (ReceiptID, ReceiptDate)
StockReceipt (ReceiptID, StockID, Quantity)
That way you can calculate TotalStockReceiptPrice and TotalReceiptPrice for any receipt in the past.
I suspect this might be what you're looking for:
Stock (StockID, StockPrice)
Receipt (ReceiptID)
StockReceipt (ReceiptID, StockID, Quantity)
SELECT r.ReceiptID, SUM(s.StockPrice * sr.Quantity) AS ReceiptPrice
FROM Receipt r
INNER JOIN StockReceipt sr ON r.ReceiptID = sr.ReceiptID
INNER JOIN Stock s ON sr.StockID = s.StockID
GROUP BY r.ReceiptID
This is all very normalised (again, no idea to what normal form - 3rd?). However it only works if the StockPrice on the Stock record NEVER changes. As soon as it changes your ReceiptPrices would all reflect the new price instead of what the customer actually paid.
If the price can change, you'd need to either keep a price history table (ItemID, Price, DateTo, DateFrom) or record the StockPrice on the StockReceipt record (and then get rid of the JOIN to the Stock record in the above query and make it use sr.StockPrice instead of s.StockPrice)
To do the INSERT you posted below, you'd have to do:
INSERT INTO StockReceipts (ReceiptID, StockID, Quantity, TotalStockPrice)
SELECT 1, 99, 2, s.StockPrice
FROM Stock s
WHERE s.StockID = 99
However it's quite likely that whatever is issuing this receipt (and triggers the INSERT) already knows the price so could just insert the value.
No, relational databases do not allow dynamic columns. The definition of a relational table is that it has a header that name the columns, and every row has the same columns.
Your technique of repeating the groups of stock columns is a violation of First Normal Form, and it also has a lot of practical problems, for instance:
How do you know how many extra columns to create?
How do you search for a given value when you don't know which column it's in?
How do you enforce uniqueness?
The simplest solution is as #OGHaza described, store extra stock/quantity data on rows in another table. That way the problems above are solved.
You don't need to create extra columns, just extra rows, which is easy with INSERT.
You can search for a given value over one column to find it.
You can put constraints on the column.
If you really want to understand relational concepts, a nice book that is easy to read is: SQL and Relational Theory: How to Write Accurate SQL Code by C. J. Date.
There are also situations where you want to expand a table definition with dynamic columns that aren't repeating -- they're just new attributes. This is not relational, but it doesn't mean that we don't need some data modeling techniques to handle the scenario you describe.
For this type of problem, you might like to read my presentation Extensible Data Modeling with MySQL, for an overview of different solutions, and their pros and cons.
PS: Fourth and Fifth normal form have nothing to do with this scenario. Your lecturer obviously doesn't understand them.

E-Commerce Database Design for Orders Table

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.

How should I store types of coupons in my db?

I'm creating a coupon system with many different types of coupons. I'd like to structure it so it can be extended. I'm not sure the best way to store the different types of coupons, for example:
Fixed amount off entire order
Fixed precentage off entire order
Fixed amount off one item (could be by sku of item or could be most expensive item)
Fixed percent off one item (could be by sku of item or could be most expensive item)
Buy x get y
Free product (by sku of item, by price)
x for $y (3 for $2, 10 for $15, etc.)
I'm using mysql, would it best to store as an array? json? Any other ideas or people with similar issues care to share how they did it?
Off of the top of my head you could have tables designed as follows:
Table: Coupon_Summary
Columns: Coupon_ID(primary key), Coupon_Name
This table will hold 'top-level' data about the Coupon.
Table: Coupon_Description
Columns: Coupon_ID(foreign key), Coupon_Description
This table will hold the description of the coupon.
Table: Coupon_Value
Columns: Coupon_ID(foreign key), Coupon_Value, Coupon_Currancy
This table will hold how much discount the coupon offers. Coupon_Value can be a percentage or a hard value(percentage will be appended with a % sign), if this is zero the coupon offers full discount, or the item is free in other words. This also includes the currency to base the discount amount off of, so that you can do conversions between currencies.
Table: Coupon_Target_Order
Columns: Coupon_ID(foreign key), Order_IDs
This table holds data related to which Order the coupon effects. If the Order_ID is null or zero, the coupon is valid for all orders. Otherwise you can have multiple IDs for multiple orders.
I hope this was of some help =).
I would create another table - tblCouponType for instance and populate it with a unique numerical and string for notes of the types I have, and add to it as new types become available. Then add another column to your coupon table that references the numerical value of your coupon type. This helps with the whole -"Relational" part of the database:)
I assume you have some sort of products table that contains all products you can sell. You can create a coupons table that looks something like:
id discount discount_percentage
INT PK DECIMAL(10,2) DECIMAL(3,2)
1 5.00 NULL
2 NULL 10.00
Then you could create a link table coupons_products like this:
coupon_id required_product_id
INT FK INT FK
1 4773
1 993
So in this example, coupon ID 1 gives a $5.00 discount and requires two products to be present on the order: 4773 and 993. Coupon ID 2 gives a 10% discount and requires no products.
With SomeSQL, I'd rather not use JSON for it is nearly impossible to efficiently query it.
My Approach would Be, simplistically speaking, to have one Table for Coupon types (columns: id, name, ...) and another one for The actual coupons.
In The coupon Table, I would have a column "type_id" Cross-referencing to The "couponTypes" Table (or a Foreign Key, for that matter).
This way, you can always add new Coupon types later on without invalidating The Data you had to this Point.
Querying "Coupons by Type" is a matter of
"SELECT 'id' FROM couponTypes WHERE 'name' = 'fixed sum'"; => $id
"SELECT * FROM coupons WHERE 'type_id' = $id"; => All fixed sum Coupons.
Welcome to MySQL!