MySQL table for saving a quantity to a 1:M relationship - mysql

I have a tables called invoice, item and invoice_item. The invoice item tables has invoice_id and item_id columns to store a 1:M type relationship, where an invoice can have many items.
Now I want to somehow store information for item quantity. Would it be suitable to create an invoice_item_quantity table, that store invoice_id, item_id and invoice_item_quantity values, respectively? Or would there be a more optimal solution?
I could be over-engineering this, but adding something like a item_quantity column to the invoice table won't work cause you can have many different types of items, so there would be no context there.
I basically need a way to store a model like this:
Invoice
Item 1 x 5
Item 2 x 2
Item 3 x 15
How can I optimally store the quantities in the model above?

I may be misunderstanding, but it sounds like you have a many-to-many relationship between the invoice and item tables, and that you are using a junction table to support this with the invoice_item table (this junction has a one-to-many relationship with both invoice and item).
If you are looking for a typical, normalized database design, then storing the quantity on the invoice_item table is good. Another good idea would be to make the invoice ID and the item ID a compound primary key on your junction table.

Related

Database design issue in project?

I am designing a database for my app. In which I want to do mapping between multiple tables. Now situation is like There is one user table. User can have generate multiple orders. So I was thinking if I can put json obejct of order_id in a column in order table. Or I can create a user_id column in order table & repeat user_id for same user. So which is a better way of doing it?
PS: What is the standard way of doing it?
You should just have user_id in your order table, then make queries like
select * from orders where user_id = *some_user_id*
A user can place multiple orders which in turn can have multiple line items. Each line item can have n quantity of a specific product. So when product comes in picture, then it becomes many to many relationship between user and product because a user can place order for many products and a product can be ordered by many users. So my suggestion is -
Create a User table with UserID
Create a PurchaseOrder table with OrderID, UserID and LineItemID
Create a LineItem table with OrderID, ProductID and LineItemID
Create a SKU table with ProductID
A user can place multiple orders.
Based on this you should maintain three different tables as given below:
User (user_id,...)
Order (order_id,...)
UserOrder (user_id,order_id,...)
Only the primary keys in the above tables are focused
Storing comma separated list or json object will worsen the design. And this is strongly discouraged.
EDIT:
As #NevilleK suggested, the above design is typically used for many-to-many relationships. For one-to-many relationship you can create a foreign key constraint in orders table where user_id should refer to the user_id in the User table.
But still you can adopt the above design for one-to-many relationship since many-to-many qualifies for one-to-many too.
The best way is to have different table for your
User table - which hosts the user information
Transaction table - which will have order_id against each user_id.
Transaction table will carry all the transaction details with user_id. If you create a JSON object, how will you map the USER to the transaction. So at the time of retrieving the json information you will have to map it to the user table anyway. I suggest you the use the above said method, which will help you maintain and scale your application much easily.

How are these tables related?

Say I run an online business where you can order products from my website, and I have a database with two tables:
Table order with the fields order_number, customer_ID, address
Table customer with the fields customer_ID, first_name, last_name
To get a full, detailed 'report' of the order, I would perform a LEFT JOIN to concatenate data from the order table to include the customer's first and last names along with their address and order number.
My question is, how are these tables related? Are they at all? What would an entity relationship diagram look like? Separately they don't seem to interact and act more like lookup tables for each other.
An order would always have a customer, no? So it is not a left but inner join.
What links them is the customer_id. So your SQL is simply:
select o.order_number, o.customer_ID, o.address,
c.first_name, c.last_name
from orders o
inner join customer c on o.customer_ID = c.customer_ID;
Entity relationship:
Order Customer
Customer_Id 0...N >---+ 1 Customer_Id
... ...
This EF relation is from MS SQL Server's sample database Northwind. In that sample database, just like yours, there are Customers and Orders. Customers and Orders tables are related via the CustomerId fields in both tables (it is the primary key in Customers, and foreign key in Orders table). When you model that as an Entity relation than you have the above diagram. Customer entity have an "Orders" navigation property (via customerId) that points to a particular Customer's Orders. And Order entity have a navigation property that points to its Customer (again via CustomerId). The relation is 1 to 0 or many (1 - *), meaning a Customer might have 0 or more Orders.
When you do the join from Customer's side, you use a LEFT join "if you want to see all Customers regardless they have Order(s) or not" - 0 or more Order(s). If you want to see only those with Order(s) then you use an inner join.
When you do the join from Orders' side, then an Order must have a Customer so it can't be a LEFT join. It is an INNER join.
You can check the relation from both sides using the connecting CustomerId field.
You wouldn't have a separate table for "OrderId, CustomerId" as it is not many-to-many relation (it would be pure redundancy and would create normalization anomalies).
Hope it is more clear now.
In the entity-relationship model, we don't relate tables. Instead, we relate entities which are represented by their key values. In your example, the customer entity (represented by customer_ID) has a one-to-many relationship with the order entity (represented by order_number) and this relationship is recorded in the order table (where order_number is associated with customer_ID). If we were to strictly follow the ER model, we would record (order_number, customer_ID) (a relationship relation) in a separate table from (order_number, address) (an entity relation).
If there's a foreign key constraint on order.customer_ID referencing customer.customer_ID, that's a subset relation that ensures that every order's customer is a known customer. Thus, the relation between the tables and the relation between the entities is not the same thing.
The relational model allows us to relate (join) tables in any way we need. The obvious join for your example would be on the shared domain customer_ID, but I could just as easily find orders which contain a customer's last_name in its delivery address.
An ER diagram for your example could look like this:
My question is, how are these tables related? Are they at all? What
would an entity relationship diagram look like? Separately they don't
seem to interact and act more like lookup tables for each other.
When dealing with data modeling in an ER-Diagram, more in the conceptual model, we should never start thinking of tables, primary keys, foreign keys and stuff as this is for the later model to the conceptual model, the logical model.
By modeling entities in ER-Diagram, we must always recognize them by their attributes/properties. The entities become concrete when we can find properties in them. I feel a lack of context here, so I'll proceed with a guess:
If you need to persist products in your database, and you need to
save the attributes/properties of them, then we have a Products
entity.
If you need to persist clients/users in your database along with
their properties/attributes, then we have a Customers entity.
According to what you said, customers are able to purchase products. So, you have to relate these two entities in any way. With this in mind, stop and think about the following:
You need to persist purchases/orders.
Purchases/orders show which users bought which products.
By linking products and customers, what would we get? The purchasing/orders event, right?
We would then have two entities relating to each other forming the purchasing (or "orders", you name it) event. This event is formed by the need for the present business rules (your rules). You as modeler you need to persist the orders, and you know that products and customers relate in some way, so you can create a relationship between the two entities representing the orders event.
As has been well discussed in other answers, there is the need of separation of attributes here. If the field "address" is where a user lives, not where the product will be delivered, then this attribute must exist in the Customers entity.
If this field/attribute/property is the final location of delivery, it should remain in the relationship orders created between the two entities, customers and products.
Let's talk now about cardinality. If a customer can purchase/order more than one product, and the same product can be purchased by more than one user, then we have a N-N relationship here. I believe this is your case.
Based on everything that was said, we find the following conceptual model:
By decomposing this model, and developing the logic model, we would have:
Now, for what reason we end up with this kind of model?
Relations N-N allow the existence of properties/attributes (if needed), so we can have attributes/properties in the relation Orders, resulting in an ORDERS table with the fields shown. This table represents the purchases/orders made by users/customers.
And for what reason the existence of "Products from orders"?
We need to say what products were purchased in which purchases/orders, especially showing how many of the same type are acquired. In N-N relationships, some properties induces the appearance of new relations which become tables later. In such situations, it is the discretion of the modeler.
In "Products from orders" entity we have a composite primary key, represented by foreign keys.
With this type of model, you can see:
Which users made purchases/orders.
Which purchases/orders were made by which users.
Which products belong to which purchases/orders.
Which products have been acquired by which users.
How many products of a type were purchased/ordered.
Using the date field, you can find out how many purchases were made in periods:
Weeks.
Months.
Years.
Quarters.
Etc.
If you are interested, see also:
E-R diagram confusion
If you have any questions, please comment and I will answer.I hope I've helped a bit.
Cheers.
"Related" is a vague and confusing term. This is because "relationship" gets used in two different ways: as "association" (between values) and as "foreign key" (between tables).
You do not need to know anything about how tables are "related" by foreign keys or common columns in order to query. What matters is how values in a query's result rows are related/associated by the query. The important relationships/associations are (represented by) the tables.
From a relational perspective, there would be a foreign key from Order referencing Customer on customer_id.
A Chen-style ER diagram would have Order and Customer entity types (boxes) and an Orders relationship type (diamond) with participations (lines) from Orders to Order and to Customer. It would have a table for each type. This is an example of perfectly sensible relational design that the ER model, with its artificial and perverse distinction between entities and relationships, cannot capture. People will use a database design like yours to implement such an ER design, though. Even though the ER design isn't, then, the design.
--
When using a database, values are used to identify entities or as property names and magnitudes. Each base table holds the rows of values that participate in some relationship/association given by the DBA. Each query result holds the rows of values that participate in a relation/association that is a combination of conditions and the relationships/associations of the base tables it mentions. All you need to know to query is the relationships/associations of tables.
Order -- order ORDER_NUMBER is by customer CUSTOMER_ID to address ADDRESS
Customer -- customer CUSTOMER_ID is named FIRST_NAME LAST NAME
Order JOIN (Customer WHERE FIRST_NAME='Eddie')
-- order ORDER_NUMBER is by customer CUSTOMER_ID to address ADDRESS
AND customer CUSTOMER_ID is named FIRST_NAME LAST NAME
AND FIRST_NAME='Eddie'
Sometimes values for a list of columns in a row of one table must also appear as values for a list of columns in another table or that table. This is because if the listed values and others satisfy one table's relationship/association then the listed values and yet others will satisfy the other table's relationship/association.
/* IF there exist ORDER_ID & ADDRESS satisfying
order ORDER_NUMBER is by customer CUSTOMER_ID to address ADDRESS
THEN there exist FIRST_NAME & LAST_NAME satisfying
customer CUSTOMER_ID is named FIRST_NAME LAST_NAME
*/
FOREIGN KEY Order(customer_id) REFERENCES Customer(customer_id)
This means that those particular tables and column lists satisfy the (one and only) relationship/association "foreign key in this database". (And a database will have a meta-data table for its foreign key relationship/association.)
We say that "there is a foreign key" from the first table's list of columns to the second table's list of columns. There's only one foreign key relationship/association for the database. When there is a foreign key its tables and column lists satisfy this database's foreign key relationship. But a foreign key isn't a relationship/association. People call foreign keys "relationships", but they are not.
But foreign keys don't matter to querying! (Ditto for any other constraint.) A query's result holds rows whose values (entity & property info) are related/associated by that query's relationship/association, built from conditions and base table relationships/associations.

Add extra table or just pass the foreign key

I have a doubt about this. I have 2 tables
Ordered_products
ordered_product_id
product_id
quantity
price_charged
Ordered_items
ordered_item_id
item_id
unit_of_measure
box_type
Each ordered product can be composed by one or more items and one item has only one ordered product.
Which solution is better:
Sol 1: Just add as foreign key the ordered_product_id into ordered_items table. (http://cl.ly/image/0g3G2J231U0P)
Sol 2: Create a new table with ordered_product_id and ordered_items keys. (http://cl.ly/image/0Z1D1C1g0R3t)
Please give me any advice
Solution one is better. The only time you need seperate table is for many to many relationships or when that table needs to store information specific to the relationship, like when it starts and ends.
With a one to many relationship, just add a column to the many table to point to its parent. It makes joins easy and clear.
Solution 1. Don't create unnecessary tables.
Association tables are only used for many-to-many relations.

Deciding on foreign key while implementing one to one relationship in MySQL

I have two simple tables "items" and "orders". For the sake of simplicity lets assume that one item can only be in one order or one order can only contain one item.
Now as this can be implemented using simple one to one relationship I can do following:
I can add the primary key of the orders table to the items table like below
//Table Items
item_id, item_name, order_id
1, shoes, 1
2, watch, 2
//Table Orders
order_id, customer
1, James
2, Rick
or I can add the primary key of the items table to the orders table like below
//Table Items
item_id, item_name
1, shoes
2, watch
//Table Orders
order_id, customer, item_id
1, James, 1
2, Rick, 2
Which one is correct and why? Are there any guide lines to decide which key goes where? Sure common sense will work in simple examples as above but in complex examples how do we decide?
One-to-One relationships should be generally merged simply into one table. If there aren't any contradictions, the One-to-One relationship might be a sign of an unconsidered decision.
And If You really want to use this kind of relationship, it's totally up to You where to place FK. You might want to take optionality into consideration when applying FK. However, in MySQL, it still won't be a true One-to-One relationship because deferred keys are not supported there.

Insert new record when updating information?

I am developing online shopping cart system, I have items and item_options tables.
Each Item can have 1 or more options, see below.
items table
item_id (PK)
item_name
item_description
Note: item prices are in the item_options tables
item_options table
option_id (PK)
item_id (FK)
option_name
option_price
When the customer placed an order, the data will be added into the order and order_items table.
orders table
orders_id (PK)
customer_id (FK)
address_address_id (FK)
date_purchased
orders_status
orders_date_finished
order_items table
orders_items_id (PK)
orders_id (FK)
item_id (FK)
item_option_id (FK)
There is a problem, if the staffs change the price, item name or delete a item.. the customer invoices will be affected because the FK from the order_items will no longer be existed in the items table. What is the solution to this?
How about this solution: add active field in the items and item_options tables. When the staffs want to change the price or name of a item - just turn the current active record to 0 (items.active) and then insert a new record with the new information and active become 1. The old orders still point the correct id of the entry that is not active. Is this good way doing it?
When the new information has been inserted in the items table, does that mean I have to update/change the new PK ID in the item_id.item_options table?
In something like this, I am definitely against the use of hard deletes. Every update or delete should be adding a new row into the item_options table and then marking the previous one as inactive (that way there is no chance that a user can select one of the previous values).
Each new item inserted should consist of two steps:
Add the item to the items table
Using the item_id from the items table, add the item into the item_options table
The typical solution to this that I've seen is to store the snapshot of the data that you want a history of in a separate table. That way you can store only the data you want a snapshot of at the time of the invoice, instead of all data in a particular table.
It will also help to store history data away from live data when it comes to simplifying reporting and queries in the code.. generally these two things don't need to be accessed at the same time, so you avoid the more complex queries (and heavier load on a single table) just to access one or the other.
If you are going to do things the way you describe, you are going to have to add a new rows to the item_options table to handle the new items.