How to choose primary key and normalize this relation schema? - sql

Suppose I have a table with following attributes
order id
item id
item quantity
item unit price
item payment
where "item payment = item unit price x item quantity".
Let us simplify the situation, and assume each order has any quantity of just one item id, and different orders may have the same item id.
What is the primary key, "order id", "order id" and "item id", or
something else?
How can it be normalized into 3NF?
Here is a solution that I am thinking:
a table with order id (primary key), item id, item quantity, and item payment
a table with item id (primary key, and foreign key to the previous table), and item unit price.
Continue with the tentative solution I gave in part 2. In the first table, for each item id, item payment is
proportional to item quantity. If the primary key of the first table
is order id, item payment depends on non-primary-key attribute item quantity, which
violates 3NF requirements of no transitivity.
Shall I split the first table into:
a table with order id (primary key), and item id
a table with item id (primary key, and foreign key to the table before), item quantity, and item payment
or into:
a table with order id (primary key) and item id
a table with item unit price (primary key, and foreign key to the original second table), item quantity, and item payment?
Thanks.

You should probably have a table with OrderID as the primary key. This is because you're likely to have attributes that have non-trivial Functional Dependencies on the order (eg. order_date, order_status, CustomerID) that are not dependent on a line in the order.
You should also again have a table where ItemID is the primary key. Again it will have attributes that would have a functional dependencies on ItemID (e.g. description, price, etc)
Finally you'd have a third table. This table would have Foreign keys to Order and Item. These keys would represent a candidate compound key. You could either use this or create a surrogate Primary Key OrderItemID. If you do create a surrogate key I would still be sure to create a unique key (OrderID, Item).
+----------------+ +----------------+
| OrderID | | ItemID |
+----------------+ +----------------+
| CustomerID | | Description |
| OrderDate | | Price |
| Status | +----------------+
| Payment | |
+----------------+ |
| |
| |
| +---------------------+ |
| | OrderItemID | |
| +---------------------+ |
+-------+ OrderID FK U1 +---+
| ItemID FK U1 |
| Quantity |
+---------------------+

Let's not talk of IDs at the start...
There are orders. Orders usually have an order number that you can have printed on the invoice etc. An order has an order date, and a supplier when this is about orders you place with your suppliers or a client when this is about orders your clients place with you.
There are items that can be ordered. Items have an item number, e.g. a GTN (Global Trade Number). Items have a name and a price or even a price list for different dates, different customers, whatever.
An order can contain several items usually, e.g. 5 pieces of item A and 10 pieces of item B. These are order positions containing item, amount and price.
That could be the tables (primary key bold, unique columns italic):
client (client_number, client_name)
item (item_number, item_name, price)
order (order_number, order_date, client_number)
order_position (order_number, item_number, amount, price)
You would not store single price and amount and total price, as this would be redundant. Avoid redundancy in a database, for this can result in a lot of problems.
You can use technical IDs in your tables. You can make these the tables' primary keys, but you'll have to store all data mentioned above still, and what was a primary key before is then a column or set of columns that is defined non-nullable and unique which is literally the same as a primary key:
Tables (primary key bold, unique columns italic):
client (client_id, client_number, client_name)
item (item_id, item_number, item_name, price)
order (order_id, order_number, order_date, client_number)
order_position (order_position_id, order_id + item_id, amount, price)

This looks like an order line. Typically you'd have a primary key of order id and order line number. item id should be a foreign key from your items table, which should have a price, but unless you never give discounts, your order line should have a price, too.
Having the amount paid against an order line is OK, if you allow partial payments and want to track it at that level.

Guessing via your names & common sense, a 3NF decomposition of your table is
-- order order_id requests item item_id in quantity item_quantity
order_has_item_in_quantity(order_id, item_id, item_quantity)
-- item item_id has unit price item_unit_price
item_has_unit_price(item_id, item_unit_price)
-- some order requests some item in quantity item_quantity
-- and that item has unit price item_unit_price
-- and item_unit_price * item_quantity = item_payment
unit_price_and_quantity_has_payment(item_unit_price, item_quantity, item_payment)
However, if you already have access to a multiplication table (which is a constant), which you do in an SQL query (via operator *), then your design doesn't need column item_payment in the original and consequently its decomposition doesn't have table unit_price_and_quantity_has_payment--it is a certain restriction of the multiplication table; it is a certain function of the multiplication table & the first two tables.
As to my guesses, and relevant CKs (candidate keys), and justification: Normalization uses FDs (functional depencies), and you haven't mentioned them, so it doesn't seem like you have even a basic idea of what you are doing. So right now your question is just asking for some chapter(s) of some textbook(s). That's too broad--read some. None of the answers here correctly explain or reference how to do this--they are useless for the next case & unjustifiable for this case. Moreover they are all guessing at your specification but should be asking you for appropriate info.

Related

SQL ecommerce database. how to relate foreign keys in same row?

I am trying to create a sql table for orders. We have another table what has a primnary key of productID. When a customer creates an order it should list the orderID as well total and a foreignkey of productID. The issue I have is that it only allows 1 productID.
Is there a way for sql to add multiple foreign keys to the same row for the same item? If that makes sense?
I placed both tables here to try and show what I meant.
Your table structure only allows one product per order, because you've got a single productId column on the orders table.
To allow multiple products per order, I would create an orderItems table. Each orderItem has a different productId, and links back to the orders table via an orderId. Like this:
------------------------
orders table
------------------------
orderId (primary key)
orderDate
orderTotal
customerId (foreign key)
specialInstructions
-------------------------
orderItems table
-------------------------
orderItemId (primary key)
orderId (foreign key)
productId (foreign key)
quantity
-------------------------
products table
-------------------------
productId (primary key)
productTitle
productDescription
productPrice

Normalizing Data and Insert Into SQL

I have what may be a stupid question but here it goes.
I have an ORDER_T table, a CUSTOMER_T table, and a ORDERLINE_T table.
I also have a set of data I need to normalize. Each record in this "bad data" has up to 3 items stored in it in attributes called Item1, Item2, and Item3. I thought I was normalizing it correctly by taking each item, separating it, and having it constitute it's own record was good. For example
ORDER_T
OrderID ItemID ItemDescription CustomerID
1 1001 Apple 100
1 1002 Grape 100
1 1003 Pear 100
OrderID is the PK and CustomerID is the FK. I realize thought as I tried to INSERT INTO my DB that it complained of multiple duplicate records via the PK. Duh--that makes sense. Now my question is:
I believe I am wrong but what would be the correct way to normalize data (to the third form) where each OrderID consists of multiple items? Is having attributes such as Item1, Item2, Item3, etc. "bad form" where it is not scalable and statically set like that? Am I overthinking it and should have simply left it alone?
I just believe I need some direction and I'll be good to go.
you need next tables:
all unique customers
customers:
CustomerId (PK)
Name
all unique items
Items:
ItemId (PK)
ItemName
all unique orders:
Orders:
OrderId (PK)
CustomerID (FK)
OrderDate
and then you need many-to-many relationship table:
OrderItems:
OrderId (FK)
ItemId (FK)
count
primary key (OrderId, ItemId)
then you will be able to insert order (which can be empty), then add/remove items from this order via OrderItems table

Primary key VS Foreign key

Im a newbie here
I created one table with primary key customer_id , and another table with a foreign key customer_id to join it to the first table
my question
when I want to enter data in the two tables , should I insert the customer_id twice ( one in the first table and the other in the second ) .
should I do that in every time I insert data ??
thanks :)
Your CustomerId table represents each customer in the Customer table. So whenever a new customer arrives, you create an id for that customer.
For other tables that "relate" to the customer, you insert a customer_id for each entry.
E.g.
Customer
CustomerId, CustomerName
Each customer has a unique id..
ProductSold
ProductId, ProductName, CustomerId
You can now tell which customer bought a product because of the foreign key in the Product table.
So for each product, you insert the customer's id that bought it. I hope that makes sense.
-- A new customer, requires a new id (when you insert a new customer)
-- A product bought by customer, requires a foreign CustomerId to identify its buyer.
So 2 CustomerId inserts.
So yes.. you are right lol :P

Storing invoices in a database

I am making a piece of invoicing software and I want it to save each individual invoice.
The user creates invoices by selecting a customer, as well as however many items are being billed to the customer. Seeing as most invoices will have multiple items, what is the best way to save them to the database without being incredibly redundant? I'm willing to rearrange my entire database if need be.
My tables look like this:
Customers Table:
Id / Primary key
FullName
Address
Phone
Items Table (a table of products offered):
Id / Primary key
ItemName
Price
Description
Invoices Table (saved invoices):
Id / Primary key
CustId / Foreign key is Id in Customer table
ItemId / Foreign key is Id in Item table
Notes
You need another table to store invoices (what you call Invoices now actually stores invoice items).
Customer
id
name
etc.
Item
id
name
etc.
Invoice
id
cust_id
date
InvoiceItem
id
inv_id
item_id
This is the classic way of modeling a many to many relationship using a junction table (i.e. InvoiceItem).
It looks like you will actually want a 4th table to join them. To normalize your data, only keep on each line things that are specific to that invoice
Invoices table
Id / Primary key
CustId / Foreign key is Id in Customer table
Notes
Invoice Items table
InvoiceId
ItemId

Database structure: Customers buy different items

I have a table which stores all item information and its id. Now I want to create an table with all customers and log which item who bought. What is the best solution for this? I guess it is not very efficient if store it like this:
|customer_id | username | password | boughtproducts |
| 1 | herbert |123 |productid1,pid2...|
How would you do it?
A simpler way to deal with this situation is the following:
Table Customer:
customer_id | username | password
Table Product:
product_id | productName | ...
Table Sales:
sale_id | customer_id | product_id | Time of sale
This way, using the table 'Sales', you will store all the sales of every customer and product.
The customer_id in 'Sales' is a foreign key from 'Customer' table, and product_id in 'Sales' is a foreign key from 'Product' table.
I hope this answered your question
There are numerous examples of this type of schema available on the web.
But in summary your DB may take the form of...
Customer table : One customer can have many..
Order table : One order can have many..
OrderLine table : One orderline will be related to one...
Product table. (And one Product will be related to may OrderLines)
So OrderLine will contain a ProductID and Quantity. You can then JOIN tables and make a full Order.
I would actually go with 2 more tables. One for Customer and then a second for Products they bought Like So:
Customer
CustomerID|Username|Password
PUrchases:
CustomerID|ProductID|Date| etc
have one Customers Table // store details of the customers
have once Products Table // store details of the products
have one Customers_products Table
|primary_key|customer_id | product_id |
| | 1 | 1 |
| | 1 | 2 |
There is Many to Many Relationship between Customers and Products. One customer can buy many products, similarly one product can be bought by many customers. So standard way to implement many to many relationships, is to have one more table, and this new table will contain primary keys from both tables.
Primary Key can be AutoIncremented, or a composite key of both the foreign keys.