MySQL外键使⽤及说明详解
⼀、外键约束
MySQL通过外键约束来保证表与表之间的数据的完整性和准确性。
外键的使⽤条件:
1.两个表必须是InnoDB表,MyISAM表暂时不⽀持外键(据说以后的版本有可能⽀持,但⾄少⽬前不⽀持);
2.外键列必须建⽴了索引,MySQL 4.1.2以后的版本在建⽴外键时会⾃动创建索引,但如果在较早的版本则需要显⽰建⽴;
3.外键关系的两个表的列必须是数据类型相似,也就是可以相互转换类型的列,⽐如int和tinyint可以,⽽int和char则不可以;外键的好处:
可以使得两张表关联,保证数据的⼀致性和实现⼀些级联操作;
外键的定义语法:
1 2 3 4[CONSTRAINT symbol] FOREIGN KEY[id] (index_col_name, ...) REFERENCES tbl_name (index_col_name, ...)
[ON DELETE{RESTRICT| CASCADE| SET NULL| NO ACTION| SET DEFAULT}] [ON UPDATE{RESTRICT| CASCADE| SET NULL| NO ACTION| SET DEFAULT}]
该语法可以在 CREATE TABLE 和 ALTER TABLE 时使⽤,如果不指定CONSTRAINT symbol,MYSQL会⾃动⽣成⼀个名字。ON DELETE、ON UPDATE表⽰事件触发限制,可设参数:
RESTRICT(限制外表中的外键改动)
CASCADE(跟随外键改动)
SET NULL(设空值)
SET DEFAULT(设默认值)
NO ACTION(⽆动作,默认的)
简单演⽰⼀下使⽤,做dage和xiaodi两个表,⼤哥表是主键,⼩弟表是外键
建表:
1 2 3 4 5 6 7 8 9 10 11 12 13CREATE TABLE`dage` (
`id` int(11) NOT NULL auto_increment,
`name` varchar(32) default'',
foreign key references用法PRIMARY KEY(`id`))
ENGINE=InnoDB DEFAULT CHARSET=latin1;
CREATE TABLE`xiaodi` (
`id` int(11) NOT NULL auto_increment,
`dage_id` int(11) default NULL,
`name` varchar(32) default'',
PRIMARY KEY(`id`),
KEY`dage_id` (`dage_id`),
CONSTRAINT`xiaodi_ibfk_1` FOREIGN KEY(`dage_id`) REFERENCES`dage` (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1;
插⼊个⼤哥:
1 2 3 4 5 6 7 8 9mysql> insert into dage(name) values('铜锣湾'); Query OK, 1 row affected (0.01 sec) mysql> select* from dage;
+----+--------+
| id | name|
+----+--------+
| 1 | 铜锣湾 |
+----+--------+
1 row in set(0.00 sec)
插⼊个⼩弟:
1 2 3 4mysql> insert into xiaodi(dage_id,name) values(1,'铜锣湾_⼩弟A'); Query OK, 1 row affected (0.02 sec)
mysql> select* from xiaodi;
+----+---------+--------------+
5 6 7 8| id | dage_id | name| +----+---------+--------------+ | 1 | 1 | 铜锣湾_⼩弟A | +----+---------+--------------+
把⼤哥删除:
1 2mysql> delete from dage where id=1;
ERROR 1451 (23000): Cannot delete or update a parent row: a foreign key constraint fails (`bstar/xiaodi`, CONSTRAINT`xiaodi_ibfk_1` FOREIGN KEY(`dage_id`) REFERENCES`dage` (`id`))
提⽰:不⾏呀,有约束的,⼤哥下⾯还有⼩弟,可不能扔下我们不管呀!插⼊⼀个新的⼩弟:
1 2mysql> insert into xiaodi(dage_id,name) values(2,'旺⾓_⼩弟A');
ERROR 1452 (23000): Cannot add or update a child row: a foreign key constraint fails (`bstar/xiaodi`, CONSTRAINT`xiaodi_ibfk_1` FOREIGN KEY(`dage_id`) REFERENCES`dage` (`id`))
提⽰:⼩⼦,想造反呀!你还没⼤哥呢!把外键约束增加事件触发限制:
1 2 3 4 5 6 7 8mysql> show create table xiaodi;
CONSTRAINT`xiaodi_ibfk_1` FOREIGN KEY(`dage_id`) REFERENCES`dage` (`id`)
mysql> alter table xiaodi drop foreign key xiaodi_ibfk_1;
Query OK, 1 row affected (0.04 sec)
Records: 1 Duplicates: 0 Warnings:
mysql> alter table xiaodi add foreign key(dage_id) references dage(id) on delete cascade on update cascade; Query OK, 1 row affected (0.04 sec)
Records: 1 Duplicates: 0 Warnings: 0
再次试着把⼤哥删了:
1 2 3 4 5 6mysql> delete from dage where id=1; Query OK, 1 row affected (0.01 sec) mysql> select* from dage;
Empty set(0.01 sec)
mysql> select* from xiaodi; Empty set(0.00 sec)
需要注意点:
MySQL允许使⽤外键,但是为了完整性检验的⽬的,在除了InnoDB表类型之外的所有表类型中都忽略了这个功能。这可能有些怪异,实际上却⾮常正常:对于数据库的所有外键的每次插⼊、更新和删除后,进⾏完整性检查是⼀个耗费时间和资源的过程,它可能影响性能,特别是当处理复杂的或者是缠绕的连接树时。
因⽽,⽤户可以在表的基础上,选择适合于特定需求的最好结合。所以,如果需要更好的性能,并且不需要完整性检查,可以选择使⽤MyISAM表类型,如果想要在MySQL中根据参照完整性来建⽴表并且希望在此基础上保持良好的性能,最好选择表结构为innoDB类型。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论