i am building an invoicing application consisting of following business logic.
a) Place a new order for customer. (an order is a group of three
related components, estimate, invoice and purchaseorder)
b) After placing an order a new estimate can be generated. an order
will have only one estimate.(An estimate consist of item details)
c) With reference to an estimate of the order. an invoice can be
generated. an invoice qualify for the discount of price. apart from
item details, an invoice consist of some expenses.an order can contain
only one invoice
d) with reference to an invoice of the order, PurchaseOrder can be
generated. PurchaseOrder consist of item information about vendor
purchase. an order can contain multiple PurchaseOrder.
here is the database table design i have come up with.
while all look good, i am having difficulty deciding where to store the items list that belongs to particular estimate, invoice or purchaseorder of the order.
i had thought of several solution.
Approach A : create different tables for item list for each. (estimate, invoice and purchase order)
table : estimate_item , invoice_item , purchaseorder_item.(this tables contains columns similar to that of
order_item in above image).
problem: problem with this approach is all the three tables consist of identical columns storing identical information, the only
difference is foreign key that will be stored.
Approach B: create one item list table order_item
tablename: order_item
problem: not sure what to store as foreign key in this table since the foreign key can be from three different table. i thought of few
way of handling foreign keys in this table as follows.
1)foreignKey table reference column: type (example values: estimate, invoice, purchaseorder) foreignKey column: type_id(consist
of foreignKey of any of three tables) problem: i am using naming
convention for column names for example column name ending with tablename_id defines the foreign key. and this method violate the rules.
2) foreignKeyColumn: order_id , estimate_id , invoice_id ,
purchaseorder_id. problem: unnecessary foreign key columns
defined.
i want to know how should i store the foreign key in order_item table so that it identifies the order and estimate/invoice/purchaseorder it belongs too.
the relationship for tables are:
id is the primary key for all the tables
table name: order relates to (contact, estimate, invoice, shipment) tables.
column name: contact_id (foreign key(referring to id column of the contact table)).
column name: estimate_id (foreign key(referring to id column of the estimate table)).
column name: invoice_id (foreign key(referring to id column of the invoice table)).
column name: shipment_id (foreign key(referring to id column of the shipment table)).
tablename: purchaseorder (this have one to many relationship with order table)
column name: order_id (foreign key(referring to id column of the order table)).
column name: contact_id (foreign key(referring to id column of the contact table)).
the question is about how to go with the storing of foreign keys in order_item table.
Thank you.
Update 1:
Please note that each table estimate , invoice and purchaseorder will have item of it's own and having no relation to each other.
Hi I'm not sure how the relations happen. for instance, you have 'estimate' pointing to 'order item' but I don't see what key you have to make that join (or look-up). as another 'order' points to 'estimate' but how are those two joined? I dont see any shared attributes that both those entities have.
I'm assuming 'id' is just something to make rows in each particular table unique, but are not id's that have value to the application. so, I would think you' need to carry estimate.reference number into the 'order item' table. This is just a cursory comment.
also, would hep for clarity if keys were listed first. so in 'order item' you have attribute 'order id' (which appears to be an FK) buried in the end of the list of other attributes. makes this hard to read.
If I understand you correctly, each document associated with an order (i.e. an estimate, purchaseorder and/or invoice) might contain a different list of items.
If that is the case, I would probably create a Documents table along the following lines:
CREATE TABLE Documents (
DocumentId INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
OrderId INT NOT NULL,
-- you can move any fields common to all document types here
-- e.g. date created, reference #, etc.
FOREIGN KEY (OrderId) REFERENCES order (id)
);
And then your order_item, estimate, purchaseorder and invoice tables all reference their associated entry in this table:
ALTER TABLE [tablename]
ADD COLUMN DocumentId INT NOT NULL,
ADD FOREIGN KEY (DocumentId) REFERENCES Documents (DocumentId)
);
Is this what you're after?
Related
I'm starting with MySQL database relashionships and I have a question.
I'm going to put in an exemple:
Table A = customer
Table B = products
Table C = sales
I wanna know how can I make a relationship with these tables where "sales" has only one customer and multiple produts.
The "sales" table can't have a Primary Key with both foreign keys, cuz it will have multiple products.
I could create a ´idsale´, but how I would structure the table to receive multiple products?
Thank you.
Costumers and Sales have a ONE-TO-MANY relation. You could add a customer reference on the Sales table
Table sales
- id PK
- customers_id FK
Sales and Product have a MANY-TO-MANY relation. You will need a new table to map this relation
Table sales_has_products
- sales_id FK
- products_id FK
I would recommend creating a fourth table, let's call it productSale, that has its own primary key, as well as foreign keys the sale ID and the product ID. Sale, then, will just have an ID and the foreign key of the customer ID (as well as any additional info you want, of course.)
This way, a sale can include multiple items of the same product (because all productSale rows have a unique ID), and all of the items included in a sale can be found by querying productSale by the specific sale ID.
I have a CUSTOMERS table and a CONTACTS table the relation between them is one to many obviously.
also I have PROJECTS table and PROJECT_CUSTOMERS table with relation one to many and with relation one to one between CUSTOMERS and PROJECT_CUSTOMERS.
my problem is that I have a fifth table PROJECT_CONTACTS ....I can't figure which tables shall I refer to in this tables, currently I am refering to PROJECT_CUSTOMERS and CONTACTS table, is this correct or there is something better ?
Your title refers to "foreign keys" but your question just seems to be about what columns should go in what tables.
First, decide what situations can arise and what you want/need to say about them. (This will your tables, columns, candidate keys, foreign keys and constraints.)
Every table holds rows that make some predicate (statement template parameterized by column names) true. Your design seems to have:
CUSTOMERS(id, ...) -- ID identifies a customer and ...
CONTACTS(id, ...) -- ID identifies a contact and ...
PROJECTS(id, ...) -- ID identifies a project and ...
PROJECT_CUSTOMERS(pid, cust_id, ...) -- project PID has customer CUST_ID and ...
PROJECT_CONTACTS(pid, cont_id, cust_id)...)
-- project PID has contact CONT_ID and project pid has customer CUST_ID and ...
A foreign key has a table & column list referencing a table and column list that forms a candidate key. It says that lists of values in the first table appear as lists of values in the second table. Where that is so, declare a foreign key.
Let's say there are two entities - Product and Image with a many-to-many relationship between them. The order of images associated with each product does matter.
Product
------------------------------------
ProductID (primary key)
ProductName
...
Image
------------------------------------
ImageID (primary key)
Url
Size
...
What are the cons and pros of the following three many-to-many "bridge" table approaches for solving this problem?
ProductImage
------------------------------------
ProductImageID (primary key, identity)
ProductID (foreign key)
FullImageID (foreign key)
ThumbImageID (foreign key)
OrderNumber
or
ProductImage
------------------------------------
ProductID (primary key, foreign key)
IndexNumber (primary key)
FullImageID (foreign key)
ThumbImageID (foreign key)
or
ProductImage
------------------------------------
ProductID (primary key, foreign key)
FullImageID (primary key, foreign key)
ThumbImageID (foreign key)
OrderNumber (index)
There is no purpose (that I have ever found) in adding a surrogate key (i.e. the IDENTITY field) to a many-to-many "bridge" table (or whatever you want to call it). However, neither of your proposed schemas is correct.
In order to get the ideal setup, you first need to determine the scope / context of the following requirement:
The order of images associated with each product does matter.
Should the ordering of the images be the same, in relation to each other, regardless of what Products they are associated with? Meaning, images A, B, C, and D are always in alphabetical order, regardless of what combination of them any particular Product has.
Or, can the ordering change based on the Product that the Image is associated with?
If the ordering of the Images needs to remain consistent across Products, then the OrderNumber field needs to go into the Image table. Else, if the ordering can change per Product, then the OrderNumber field go into this bridge / relationship table.
In either case:
the PK is the combination of FKs:
A Primary Key uniquely, and hopefully reliably (meaning that is doesn't change), identifies each row. And if at all possible, it should be meaningful. Using the combination of the two FK fields gives exactly that while enforcing that uniqueness (so that one Product cannot be given the same Image multiple times, and vice-versa). Even if these two fields weren't chosen as the PK, they would still need to be grouped into a UNIQUE INDEX or UNIQUE CONSTRAINT to enforce that data integrity (effectively making it an "alternate key"). But since these IDs won't be changing (only inserted and deleted) they are well suited to be the PK. And if you are using SQL Server (and maybe others) and decide to use this PK as the Clustered index, then you will have the benefit of having both ProductID and ImageID in any Non-Clustered Indexes. So when you need to sort by [OrderNumber], the Non-Clustered Index on that field will automatically be a covering index because the only two data fields you need from it are already there.
On the other hand, placing the [OrderNumber] field into the PK has a few downsides:
It can change, which is not ideal for PKs.
It removes the ability to enforce that a ProductID and ImageID can only relate to each other one time. Hence would need that additional UNIQUE INDEX or UNIQUE CONSTRAINT in order to maintain the data integrity. Else, even if you include all 3 fields in the PK, it still allows for the ProductID + ImageID combination to be there multiple times per various values of IndexID.
there is no need for an IDENTITY field:
With the above information in mind, all of the requirements of a PK have already been met. Adding a surrogate key / auto-increment field adds no value, but does take up additional space.
And to address the typical reply to the above statement regarding the surrogate key not adding any value, some will say that it makes JOINs easier if this combination of ProductID+ImageID needs to be Foreign Keyed to a child table. Maybe each combination can have attributes that are not singular like [OrderNum] is. An example might be "tags" (although those would most likely be associated with just ImageID, but it works as a basic example). Some people prefer to only place a single ID field in the child table because it is "easier". Well, it's not easier. By placing both ImageID and ProductID fields in the child table and doing the FK on both back to this PK, you now have meaningful values in the child table and will not need to JOIN to this [ProductImage] table all of the time just to get that information (which will probably be needed in most queries that are not simply listing or updating those attributes for a particular ProductID+ImageID combination). And if it is not clear, adding a surrogate key still requires a UNIQUE INDEX or UNIQUE CONSTRAINT to enforce the data integrity of unique ProductID+ImageID combinations (as stated above in the first bullet point).
And placing both ID fields into the child table is another reason to stay away from fields that can change when choosing a PK: if you have FKs defined, you need to set the FK to ON UPDATE CASCADE so that the new value for the PK propagates to all child tables, else the UPDATE will fail.
ProductImage
------------------------------------
ProductID (primary key, foreign key to Product table)
FullImageID (primary key, foreign key to Image table)
ThumbImageID (foreign key; shouldn't this field be in the Image table?)
OrderNumber TINYINT (only here if ordering is per Product, else is in Image table)
The only reason I can see for adding a surrogate key in this situation is if there is a requirement from some other software. Things such as SQL Server Replication (or was it Service Broker?) and/or Entity Framework and/or Full-Text Search. Not sure if those examples do require it, but I have definitely seen 1 or 2 "features" that require a single-field PK.
The best way to achieve this is by having three tables, one for products, one for images and one for their relationship
products
--------
+ product_id (pk)
- product_name
- product_description
- ...
images
------
+ image_id (pk)
- image_title
- ...
product_images
--------------
+ product_id (fk)
+ image_id (fk)
Why do you have seperate tables for fullImage and thumbImage?
Table1 is better since it allows you identify individual rows inside the table.
Table2, im sure you can't have two primary keys.
It might be better to have an Image table as follows.
ImageId (primary)
FullImage [actual value/FK]
ThumbNail [actual value/FK]
and then,
ProductImageID (primary)
ProductID [FK]
ImageID [FK]
How that helps,
Regards,
Rainy
In mySQL if I created two tables and on table contains a foreign key referenced to the other table. I have entered data in the other table and for the defined foreign key in that as well. Is there any way for the foreign key to automatically update in the second table without having to type in the entire data?
For example I have a customer table which has 2 fields- customerID and customerName. Another table is say a invoice table which has 3 fields- invoiceID, cost and customerID, where customerID is foreign key. So if I enter data in customer table and invoice table as the number of customers are very large I do not want to keep on entering the customerID in the invoice table. As customerID is a foreign key in the other table, how do I make it automatically reference it from customer table?
You can automatically add a predefined number, like 1, but that will assign all invoices to customer#1.
On the other hand, you can add customers automatically while adding invoices. For that, you need to control the customerID and if a customer with the given ID is not present, insert a new customer to the customer table with empty name. After that, you still need to enter names for those customers, but not by one and that would get things (maybe) easier.
I think you have a misleading idea here. I strongly suggest reading a book or seeing a tutorial online or examining an example project's database tables.
If you have the customer name in invoice data and customer data already populated, you could do
INSERT INTO tbl_invoice (invoiceData, invoiceData2, customerID)
SELECT 'value1', 'value2', customer.customerID
FROM tbl_customer customer
WHERE customer.customerName = 'customer name'
So you wouldn't need to deal with customer ids directly.
There is no automatic feature in MySQL to do exactly this. A trigger could be used for it if needed.
I have two tables and I need to establish a 1-many relation among them, as an example:
1 Customer can have many Order(s).
What is a good way to create keys on the Order table such that there can be many rows in Orders, relating to one/same Customer details? i.e can I have cases when there are 2 rows with same CustomerID inserted into Order (1-many relation on CustomerID foreign key)
Assume
Customer table has columns:
CustomerID (key)
Name
OtherColumns
Order:
<IsaKeyNeeded>
customerID (foreign key)
OrderName
Another question I have is does 'Order' need to have it's own key?
You have it set up correctly ... the Order table should have a foreign key to the Customer table. This establishes the relationship of one customer to many orders. Just do not make the CustomerID a unique key.
To answer your other question ... yes, the Order table should have it's own primary key.