mysql sets foreign key constraints on delete cascade on update cascade

MySQL sets foreign key constraints on delete cascade on update cascade


Summary: When deleting a parent node, the database helps to delete the child node, so that we don't need to explicitly write the code to delete the child node first, and then delete the parent node.

Example of foreign key constraint creation:
ALTER TABLE a
  ADD CONSTRAINT `FK_Reference_1`
  FOREIGN KEY (`parent_id` )
  REFERENCES parent_table (`parent_id` )
  ON DELETE CASCADE
  ON UPDATE RESTRICT;


1) First look at the On Delete attribute, the
possible values ​​are: No Action, Cascade, Set Null, Restrict properties.
When the value is No Action or Restrict, when deleting the corresponding record in the parent table (that is, the source table of the foreign key), first check whether the record has a corresponding foreign key, and if so, it is not allowed to delete.

When the value is Cascade, when deleting the corresponding record in the parent table (that is, the source table of the foreign key), first check whether the record has a corresponding foreign key, and if so, delete the foreign key in the child table (that is, the foreign key contains the foreign key) key table).

When the value is Set Null, when deleting the corresponding record in the parent table (that is, the source table of the foreign key), first check whether the record has a corresponding foreign key, and if so, set the foreign key value in the child table to null (However, this requires that the foreign key is allowed to take null).


2) Take a look at the on update property:
When the value is No Action or Restrict, when updating the corresponding record in the parent table (that is, the source table of the foreign key), first check whether the record has a corresponding foreign key, and if there is, it is not allowed to update.

When the value is Cascade, when the corresponding record is updated in the parent table (that is, the source table of the foreign key), first check whether the record has a corresponding foreign key, and if so, also update the foreign key in the child table (that is, containing the foreign key) key table).

When the value is Set Null, when updating the corresponding record in the parent table (that is, the source table of the foreign key), first check whether the record has a corresponding foreign key, and if so, set the foreign key value in the child table to null (However, this requires that the foreign key is allowed to take null).
 
For example, I have two tables like this:
tbluser user table:
CREATE TABLE tbluser (
UserID varchar(50) NOT NULL primary key,
UserName varchar(40) NOT NULL,
UserMail varchar(50) NOT NULL,
UserPassword varchar(50) NOT NULL,
UserType tinyint(3) unsigned DEFAULT '0',
UserCreated datetime DEFAULT '0000-00-00 00:00:00'
)ENGINE=InnoDB DEFAULT CHARSET=utf8;

tblfile file (user's file) table:
CREATE TABLE tblfile (
FileID int (10) unsigned NOT NULL AUTO_INCREMENT,
FileOwner varchar(50) DEFAULT NULL,
FileName varchar(200) NOT NULL,
FilePath varchar(200) NOT NULL,
FileType varchar(10) NOT NULL,
FileSubject varchar(100) NOT NULL,
FileCreated datetime DEFAULT '0000-00-00 00 :00:00',
PRIMARY KEY (FileID)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

create index ind_FileOwner on tblfile(FileOwner);
ALTER TABLE `tblfile` ADD CONSTRAINT `FK_tblfile_1` FOREIGN KEY (`FileOwner`) REFERENCES `tbluser` (`UserID`) ON DELETE SET NULL ON UPDATE CASCADE;


It can be seen from the above that FileOwner is the foreign key of the file table, which refers to the UserID of the user table. And here the foreign key constraint is set to "ON DELETE SET NULL ON UPDATE CASCADE" 
and now the user table has records (other irrelevant fields are omitted):

mysql> select * from tbluser;
+--------+----------+------------------+--------------+----------+---------------------+
| UserID | UserName | UserMail         | UserPassword | UserType | UserCreated         |
+--------+----------+------------------+--------------+----------+---------------------+
| 1      | tina     | [email protected]     | tina         |        0 | 0000-00-00 00:00:00 |
| 2      | bobo     | [email protected]      | bobo         |        1 | 2016-12-27 16:07:51 |
| 3      | lio      | [email protected] | jiou         |        2 | 2016-11-21 16:08:31 |
| 4      | kaka     | [email protected] | jiujiu       |        0 | 2016-11-06 16:09:03 |
+--------+----------+------------------+--------------+----------+---------------------+
4 rows in set (0.00 sec)

mysql> select * from tblfile;
+--------+-----------+----------+--------------+----------+-------------+---------------------+
| FileID | FileOwner | FileName | FilePath     | FileType | FileSubject | FileCreated         |
+--------+-----------+----------+--------------+----------+-------------+---------------------+
|      1 | 1         | test     | /tmp/a.txt   | 1        | en          | 2016-12-04 16:09:39 |
|      2 | 4         | jiujiu   | /tmp/jiu.txt | 2        | jieng       | 0000-00-00 00:00:00 |
|      3 | 4         | enogeh   | /tmp/3hoge   | 2        | eg          | 0000-00-00 00:00:00 |
|      4 | 2         | egoe     | /tmp/ghoeh   | 3        | eighha      | 2016-12-06 16:10:42 |
+------------+-------------+----------+--------------+-- --------+-------------+---------------------+
4 rows in set ( 0.00 sec)


Let's delete the parent table data:
mysql> set autocommit=0;
Query OK, 0 rows affected (0.00 sec)

mysql> savepoint p1;
Query OK, 0 rows affected (0.00 sec)

mysql> delete from tbluser where UserId= 2; If the parent table is deleted, the associated fields of the child table will be set null
Query OK, 1 row affected (0.00 sec)

mysql> select * from tblfile;
+--------+------- ----+----------+-------------+----------+-------- -----+---------------------------------+
| FileID | FileOwner | FileName | FilePath | FileType | FileSubject | FileCreated |
+------ --+------------+------------+--------------+--------- -+-------------+-----------------------+
| 1 | 1 | test | /tmp/a.txt | 1 | en | 2016-12-04 16:09:39 |
| 2 | 4 | jiujiu | /tmp/jiu.txt | 2 | jieng | 0000-00 -00 00:00:00 |
| 3 | 4 | enogeh | /tmp/3hoge | 2 | eg | 0000-00-00 00:00:00 |
| 4 | NULL | egoe | /tmp/ghoeh | 3 | eighha | 2016-12-06 16:10:42 |
+-------+-----------+----------+----- ---------+------------+-------------+--------------- ------+
4 rows in set (0.00 sec)


Let's update the parent table data:
mysql> update tbluser set UserId=5 where UserId=4; ---Update the parent table, update the child table
Query OK, 1 row affected (0.00 sec)
Rows matched: 1 Changed: 1 Warnings: 0

mysql> select * from tblfile;
+--------+-----------+----------+--------------+----------+-------------+---------------------+
| FileID | FileOwner | FileName | FilePath     | FileType | FileSubject | FileCreated         |
+--------+-----------+----------+--------------+----------+-------------+---------------------+
|      1 | 1         | test     | /tmp/a.txt   | 1        | en          | 2016-12-04 16:09:39 |
|      2 | 5         | jiujiu   | /tmp/jiu.txt | 2        | jieng       | 0000-00-00 00:00:00 |
|      3 | 5         | enogeh   | /tmp/3hoge   | 2        | eg          | 0000-00-00 00:00:00 |
|      4 | NULL      | egoe     | /tmp/ghoeh   | 3        | eighha      | 2016-12-06 16:10:42 |
+------------+-------------+----------+--------------+-- --------+-------------+---------------------+
4 rows in set ( 0.00 sec)

mysql> rollback to p1; --- Rollback to prepare for later testing.
Query OK, 0 rows affected (0.01 sec)

mysql> select * from tblfile;
+--------+-----------+----------+ --------------+----------+-------------+---------- -------------+
| FileID | FileOwner | FileName | FilePath | FileType | FileSubject | FileCreated |
+--------+-----------+- ---------+--------------+------------+-------------+ ---------------------+
| 1 | 1 | test | /tmp/a.txt | 1 | en | 2016-12-04 16:09:39 |
| 2 | 4 | jiujiu | /tmp/jiu.txt | 2 | jieng | 0000-00-00 00:00:00 |
| 3 | 4 | enogeh | /tmp/3hoge | 2 | eg | 0000-00-00 00:00:00 |
| 4 | 2 | egoe | /tmp/ghoeh | 3 | eighha | 2016-12-06 16: 10:42 |
+-------+-------------+------------+------------- -+------------+-------------+----------------------+
4 rows in set (0.00 sec)


delete the previous foreign key constraint and change the rules.
ALTER TABLE `tblfile` DROP FOREIGN KEY `FK_tblfile_1`; ALTER TABLE `tblfile` ADD CONSTRAINT `FK_tblfile_1` FOREIGN KEY (`FileOwner`) REFERENCES ` tbluser`
(`UserID`) ON DELETE RESTRICT ON UPDATE NO ACTION;

Action:
mysql> set autocommit=0;
Query OK, 0 rows affected (0.00 sec)

mysql> savepoint p1;
Query OK, 0 rows affected (0.00 sec)

mysql> delete from tbluser where UserId=2; -- Both deletion and update of the parent table are restricted because the child table has this user's information.
ERROR 1451 (23000): Cannot delete or update a parent row: a foreign key constraint fails (`tina`.`tblfile`, CONSTRAINT `FK_tblfile_1`
FOREIGN KEY (`FileOwner`) REFERENCES `tbluser` (`UserID`) ON UPDATE NO ACTION)
mysql> update tbluser set UserId=5 where UserId=4;
ERROR 1451 (23000): Cannot delete or update a parent row: a foreign key constraint fails (`tina`.`tblfile`, CONSTRAINT `FK_tblfile_1`
FOREIGN KEY (`FileOwner`) REFERENCES `tbluser` (`UserID`) ON UPDATE NO ACTION)

no action is the same as RESTRICT, that is, the operation is not allowed if there is a record.


Change the rules again:
ALTER TABLE `tblfile` DROP FOREIGN KEY `FK_tblfile_1`;
ALTER TABLE `tblfile` ADD CONSTRAINT `FK_tblfile_1` FOREIGN KEY (`FileOwner`) REFERENCES `tbluser` (`UserID`) ON DELETE CASCADE ON UPDATE CASCADE;

mysql> set autocommit=0;
Query OK, 0 rows affected (0.00 sec)

mysql> savepoint p1;
Query OK, 0 rows affected (0.00 sec)

mysql> delete from tbluser where UserId=2;
Query OK, 1 row affected (0.00 sec)

mysql> select * from tblfile;
+--------+-----------+----------+--------------+----------+-------------+---------------------+
| FileID | FileOwner | FileName | FilePath     | FileType | FileSubject | FileCreated         |
+--------+-----------+----------+--------------+----------+-------------+---------------------+
| 1 | 1 | test | /tmp/a.txt | 1 | en | 2016-12-04 16:09:39 |
| 2 | 4 | jiujiu | /tmp/jiu.txt | 2 | jieng | 0000-00 -00 00:00:00 |
| 3 | 4 | enogeh | /tmp/3hoge | 2 | eg | 0000-00-00 00:00:00 |
+--------+----- ------+------------+--------------+----------+------ -------+---------------------+
3 rows in set (0.00 sec)

mysql> update tbluser set UserId=5 where UserId=4 ; -- Delete and update in the parent table, and delete and update in the child table.
Query OK, 1 row affected (0.00 sec)
Rows matched: 1 Changed: 1 Warnings: 0

mysql> select * from tblfile;
+--------+-----------+- ---------+--------------+------------+-------------+ ---------------------+
| FileID | FileOwner | FileName | FilePath     | FileType | FileSubject | FileCreated         |
+--------+-----------+----------+--------------+----------+-------------+---------------------+
|      1 | 1         | test     | /tmp/a.txt   | 1        | en          | 2016-12-04 16:09:39 |
|      2 | 5         | jiujiu   | /tmp/jiu.txt | 2        | jieng       | 0000-00-00 00:00:00 |
|      3 | 5         | enogeh   | /tmp/3hoge   | 2        | eg          | 0000-00-00 00:00:00 |
+--------+-----------+----------+--------------+----------+-------------+---------------------+
3 rows in set (0.00 sec)

mysql> rollback to p1;
Query OK, 0 rows affected (0.00 sec)

mysql> select * from tblfile;
+--------+-----------+----------+--------------+----------+-------------+---------------------+
| FileID | FileOwner | FileName | FilePath     | FileType | FileSubject | FileCreated         |
+--------+-----------+----------+--------------+----------+-------------+---------------------+
|      1 | 1         | test     | /tmp/a.txt   | 1        | en          | 2016-12-04 16:09:39 |
|      2 | 4         | jiujiu   | /tmp/jiu.txt | 2        | jieng       | 0000-00-00 00:00:00 |
|      3 | 4         | enogeh   | /tmp/3hoge   | 2        | eg          | 0000-00-00 00:00:00 |
|      4 | 2         | egoe     | /tmp/ghoeh   | 3        | eighha      | 2016-12-06 16:10:42 |
+------------+-------------+----------+--------------+-- --------+-------------+---------------------+
4 rows in set ( 0.00 sec)


foreign keys are used to reduce database redundancy and ensure data integrity and consistency.
Also note that if there is a foreign key relationship between the two tables, MySQL cannot directly delete the table (Drop Table), but should delete the foreign key first, and then delete it.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=326477484&siteId=291194637