How to choose what FOREIGN KEY to create on what attribute? - mysql

Assume I have 2 tables with following attributes.
table 1 (customers): id (PRIMARY), customer (UNIQUE), totalspent
table 2 (receipts): id, cost
What indexes do I need to create on customers or receipts to make it so when a customer is deleted from the table all the receipts tied to him via id are deleted as well?
I set receipts.id to primary key, but when deleting entries from customers, they would not be deleted from receipts. Should I make customers.id a foreign key that references receipts.id? Can a primary key be a foreign key?

You are looking for a cascading foreign key constraint, rather than an index.
alter table receipts add constraint fk_receipts_cust
foreign key (cust) reference customers(id)
on delete cascade;
In MySQL, a foreign key also happens to create an index. This is a "special feature" of MySQL. The functionality you are looking for is the cascading part. You can read more about this in the documentation.

Related

Composite key mySQL constraint

If I wanted to write mySQL for this database that's been already normalized, how would I add a constraint for the (Branch_ID, Employee_ID) composite key?
Branch Table
Branch ID
Branch Name
Address
Post Code
Town
County
Branch Employee Table
Branch ID
Employee ID
Employee Table
Employee ID
Employee First Name
Employee Surname
Employee NI No.
I made primary keys bald. I know how to make both the Branch Id and Employee ID primary keys using constraint, but should I also make the Employee_ID in the Branch Employee table a foreign key since I use it in another table?
To add a composite key to an existing table, use the code:
ALTER TABLE `Branch Employee`
ADD PRIMARY KEY (BranchID,Employee ID)
You are correct that each column in the Branch Employee table should be a foreign key as the values are used in other tables. Without the foreign key it could be possible to enter employees and branches that don't exist in their respective tables
Create the foreign keys as follows
ALTER TABLE `Branch Employee`
ADD FOREIGN KEY (EmployeeID_FK) REFERENCES Employee(EmployeeID);
ALTER TABLE `Branch Employee`
ADD FOREIGN KEY (BranchID_FK) REFERENCES Branch(BranchID);
Edited in light of Raymond's comment:
The order of columns in the composite key matters as a clustered index will be created with the primary key. The most selective (most queried) column of the two should go first and then less selective second. The right or wrong order will depend on the queries being run against the table
a PRIMARY KEY is an identifier for each table.
a FOREIGN KEY means that a value ina table is referenced by a PRIMARY KEY in another table.
In this case, you need to set your Branch ID Employee ID both, PRIMARY KEY and FOREIGN KEY;
FOREIGN KEY - because they are referenced by another table.
PRIMARY KEY - because you don't want 'employee a' to be twice in 'branch a'.
Caution: You can still have 'employee a' in both 'branch a' and 'branch b'.
To avoid this, is better that Employee table contains a parameter call branch id, and become it the foreign key.
Hope it helps

In M:N database relationship it's better to reference by a composite PK or two foreign keys

I have a database that involves a table called U and a table called P .
table U
U_Id primary key.
table P
P_Id primary key
There is many to many relationship between the two tables.
I have two ways to create relationship between the two table:
1) create a new table that contains a composite Primary Key (U_Id,P_Id)
2) create a new table that contains references from U table and P table as foreign keys.
(U_id and P_id as foreign keys )
Third_Table
U_id FK not null
P_Id FK not null
What the better option?
Options 1 and 2 aren't opposed. Your relationship table will contain U_Id and P_Id as foreign keys, and the combination of these two columns should at least be marked as a unique key, if not a primary key.
Some DB designers prefer to introduce a surrogate identifier as primary key. Others (including myself) prefer to use the combination of foreign keys as the primary key.
2) create a new table that contains references from U table and P table as foreign keys.
That you need for referential integrity, else the 3rd table could have values that do not refer to anything. (Hurrah for many-to-nothing rows!)
1) create a new table that contains a composite Primary Key (U_Id,P_Id)
If you don't do that, what will be the primary key to the 3rd table? It will have one, right?
A primary key is one form of unique constraint. If a table has more than one unique constraint, the choice of which one to call the primary key is arbitrary. In your case, though, there's only one.
You need some kind of unique constraint on the 3rd table to prevent duplicate rows. Primary Key (U_Id,P_Id) says than any {U_Id,P_Id} pair is unique, and identifies that relationship. From what you say, that's what you want.
I would expect a composite key consisting of two foreign keys. Example code (untested):
CREATE TABLE Q
(u_id INT NOT NULL FOREIGN KEY REFERENCES U (u_id),
p_id INT NOT NULL FOREIGN KEY REFERENCES P (u_id),
PRIMARY KEY (u_id, pi_id));

Two columns in same table and same foreign key

I'm developing an application, actually a billing system. Here accountant can add invoice for a client.
I have two tables, users and invoices:
invoices (user_id, created_by)
users (id)
Invoices has two columns, user_id and created_by, I want both to be linked with id of the users table.
Already user_id has been added as foreign key. Now I'm trying to add created_by as foreign key. So issued following command:
ALTER TABLE `invoices`
ADD FOREIGN KEY (`created_by`) REFERENCES `secureap_maind`.`users` (`id`)
ON DELETE RESTRICT ON UPDATE RESTRICT;
And I'm getting an error message.
#1452 - Cannot add or update a child row: a foreign key constraint fails (secureap_maind.#sql-3717_a323d, CONSTRAINT #sql-3717_a323d_ibfk_2 FOREIGN KEY (created_by) REFERENCES users (id))
I'm not sure if I can add two columns as foreign key. IF possible, can you please advice to do that?
Thanks in advance.
This SO post implies that removing your ON DELETE RESTRICT clause from the ALTER TABLE statement might solve your problem. Try running this query instead:
ALTER TABLE `invoices`
ADD FOREIGN KEY (`created_by`) REFERENCES `secureap_maind`.`users`(`id`)
I am assuming that the invoices table was created using InnoDB rather than MyISAM, the latter which does not enforce foreign keys.

Foreign Key Tables Updates

I just started learning SQL so I am a bit confused.
If I have Table A that has a primary key : CustomerID & Table B with foreign key CustomerID
I added the foreign key constraint by using CASCADE so that the foreign key should update or delete automatically when primary key is deleted or updated.
However, it only works for delete. When I add a new record in the primary field table, that record is not shown in the foreign key table, why is that ?
Corresponding rows are updated or deleted in the referencing table
when that row is updated or deleted in the parent table. CASCADE
cannot be specified if a timestamp column is part of either the
foreign key or the referenced key. ON DELETE CASCADE cannot be
specified for a table that has an INSTEAD OF DELETE trigger. ON UPDATE
CASCADE cannot be specified for tables that have INSTEAD OF UPDATE
triggers.
As mention in MSDN. They have mentioned the only update and delete operation of primary key table will affect the Foreign key table's column. If any insert made to primary key, it will not affected the foreign key. Since the Main objective in primary key and foreign key relationship
"An each every record is available in the foreign key table, it should contain corresponding record should be present in the primay key table and vice versa is not applicable".
If you insert any record to foreign key table that it will throws foreign referential integrity error. It will not allows you to insert a record in the foreign table unless and until you will corresponding record in the primary key table.
for information take look in following in MSDN links
http://msdn.microsoft.com/en-us/library/ms179610.aspx
Note:
if you want to achieve this functionality then you have write a logic in Stored procedure or trigger.
No,is not automatic add in your foreign key table , it's not make sense , for example if you have two table ,"City" and "People" , People in the City , so there must be a FK refer for People , if you add record in City e.g. New York , How is database know who's need to insert to People table?How many people? , and what this people properties? e.g. People Name?
So database can't do that automatic , you have to do it manually!

Cannot add a foreign key to exists table

I cannot add a foreign key to my exists table. I want to add a foreign key publisher_id from table games references to publishers (publisher_id).
But when running the below sql, it says:
Source and target columns must have the same data type, there must be an index on the target columns and referenced data must exist.
Cannot add or update a child row: a foreign key constraint fails (vngarena.com.#sql-818_1b1, CONSTRAINT #sql-818_1b1_ibfk_2 FOREIGN KEY (publisher_id) REFERENCES publishers (publisher_id) ON DELETE CASCADE ON UPDATE CASCADE
The sql is:
ALTER TABLE games
ADD FOREIGN KEY (publisher_id) REFERENCES publishers (publisher_id) ON DELETE CASCADE ON UPDATE CASCADE;
And here is the diagram of my db:
More info:
- Table games has two records
- Table games has other foreign key which references to table gamecats (gamecat_id)
- Table gamecats has two records
- Table publishers has no record
If there is any existing data that violates the relationship, you will need to clean it up before adding the key.
[Edited]
After your edit: The publisher_id in Table games, is looking for a match in the publishers table. Add a publisher with an id that matches what's in the games table.
You need to delete the games table records before adding foreign key.
If you add foreign key,it should match with existing data. In your condition the publishers table has no records . so it will fails foreign key if you add data with records in games table
or
You should add two records in publishers table with same keys exists in games table.
For more detail, refer below link
Foreign Key