Fortunately, the lesser-used InnoDB table type does support foreign keys: this article will show how they could reduce your coding effort and increase data integrity.
What are Foreign Keys?
A foreign key establishes a relationship, or constraint, between two tables.Disclaimer! For the purpose of this example, we will create two simple database tables. They are not well designed, but will demonstrate the power of foreign keys!
- employee: a table of company employees where each member is assigned a unique ID
- borrowed: a table of borrowed books. Every record will reference a borrower’s employee ID.
- It is not possible to enter an invalid employee ID in the ‘borrowed’ table.
- Employee changes are handled automatically by MySQL.
Creating an Example Database
Our example database is created as follows:CREATE DATABASE mydb;
USE mydb;
We now define our two tables. Note that InnoDB
is specified as the table type and we will also add an index for the
employee’s last name.
CREATE TABLE employee (
id smallint(5) unsigned NOT NULL,
firstname varchar(30),
lastname varchar(30),
birthdate date,
PRIMARY KEY (id),
KEY idx_lastname (lastname)
) ENGINE=InnoDB;
CREATE TABLE borrowed (
ref int(10) unsigned NOT NULL auto_increment,
employeeid smallint(5) unsigned NOT NULL,
book varchar(50),
PRIMARY KEY (ref)
) ENGINE=InnoDB;
We can now specify our foreign key (this could be handled in the CREATE TABLE statement, but it is shown separately here):
ALTER TABLE borrowed
ADD CONSTRAINT FK_borrowed
FOREIGN KEY (employeeid) REFERENCES employee(id)
ON UPDATE CASCADE
ON DELETE CASCADE;
This tells MySQL that we want to alter the borrowed
table by adding a constraint called ‘FK_borrowed’. The employeeid column
will reference the id column in the employee table – in other words, an
employee must exist before they can borrow a book.The final two lines are perhaps the most interesting. They state that if an employee ID is updated or an employee is deleted, the changes should be applied to the borrowed table.
Adding Table Data
We will now populate the tables with data. Remember that our employees must be added first:employee:
id | firstname | lastname | birthdate |
---|---|---|---|
1 | John | Smith | 1976-01-02 |
2 | Laura | Jones | 1969-09-05 |
3 | Jane | Green | 1967-07-15 |
ref | employeeid | book |
---|---|---|
1 | 1 | SitePoint Simply SQL |
2 | 1 | SitePoint Ultimate HTML Reference |
3 | 1 | SitePoint Ultimate CSS Reference |
4 | 2 | SitePoint Art and Science of JavaScript |
SELECT book FROM borrowed
JOIN employee ON employee.id=borrowed.employeeid
WHERE employee.lastname='Smith';
Result:SitePoint Simply SQL
SitePoint Ultimate HTML Reference
SitePoint Ultimate CSS Reference
Cascading in Action
The Accounts Department calls us with a problem: Laura’s employee ID must be changed from 2 to 22 owing to a clerical error. With standard MyISAM tables, you would need to change every table that referenced the employee ID. However, our InnoDB constraints ensure that changes are cascaded following a single update:
UPDATE employee SET id=22 WHERE id=2;
If we examine our borrowed table, we will find that the update has occurred without us needing to run additional code:borrowed:
ref | employeeid | book |
---|---|---|
1 | 1 | SitePoint Simply SQL |
2 | 1 | SitePoint Ultimate HTML Reference |
3 | 1 | SitePoint Ultimate CSS Reference |
4 | 22 | SitePoint Art and Science of JavaScript |
DELETE FROM employee WHERE id=1;
The deletion is cascaded through to our borrowed table, so all John’s references are removed:borrowed:
ref | employeeid | book |
---|---|---|
4 | 22 | SitePoint Art and Science of JavaScript |
- NO ACTION or RESTRICT: the update/delete is rejected if there are one or more related foreign key values in a referencing table, i.e. you could not delete the employee until their books had been returned.
- SET NULL: update/delete the parent table row, but set the mis-matching foreign key columns in our child table to NULL (note that the table column must not be defined as NOT NULL).
No comments:
Post a Comment