MYSQL外键(Foreign Key)的使用

本文介绍了MySQL中InnoDB引擎表的外键约束。阐述了外键使用条件,如两表须为InnoDB表、外键列要建索引、列数据类型要相似等。说明了外键好处,给出定义语法及事件触发限制参数。还通过示例演示了外键的创建、插入数据、删除数据及添加事件触发限制等操作。

在MySQL 3.23.44版本后,InnoDB引擎类型的表支持了外键约束。
外键的使用条件:
1.两个表必须是InnoDB表,MyISAM表暂时不支持外键(据说以后的版本有可能支持,但至少目前不支持);
2.外键列必须建立了索引,MySQL 4.1.2以后的版本在建立外键时会自动创建索引,但如果在较早的版本则需要显示建立; 
3.外键关系的两个表的列必须是数据类型相似,也就是可以相互转换类型的列,比如int和tinyint可以,而int和char则不可以;

外键的好处:可以使得两张表关联,保证数据的一致性和实现一些级联操作;

外键的定义语法:
[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两个表,大哥表是主键,小弟表是外键:
建表:

 1CREATE TABLE `dage` (
 2  `id` int(11) NOT NULL auto_increment,
 3  `name` varchar(32) default '',
 4  PRIMARY KEY  (`id`)
 5) ENGINE=InnoDB DEFAULT CHARSET=latin1;
 6
 7CREATE TABLE `xiaodi` (
 8  `id` int(11) NOT NULL auto_increment,
 9  `dage_id` int(11) default NULL,
10  `name` varchar(32) default '',
11  PRIMARY KEY  (`id`),
12  KEY `dage_id` (`dage_id`),
13  CONSTRAINT `xiaodi_ibfk_1` FOREIGN KEY (`dage_id`) REFERENCES `dage` (`id`)
14) ENGINE=InnoDB DEFAULT CHARSET=latin1;


插入个大哥:

1mysql> insert into dage(name) values('铜锣湾');
2Query OK, 1 row affected (0.01 sec)
3mysql> select * from dage;
4+----+--------+
5| id | name   |
6+----+--------+
7|  1 | 铜锣湾 |
8+----+--------+
91 row in set (0.00 sec)


插入个小弟:

1mysql> insert into xiaodi(dage_id,name) values(1,'铜锣湾_小弟A');
2Query OK, 1 row affected (0.02 sec)
3
4mysql> select * from xiaodi;
5+----+---------+--------------+
6| id | dage_id | name         |
7+----+---------+--------------+
8|  1 |       1 | 铜锣湾_小弟A |
9+----+---------+--------------+


把大哥删除:

1mysql> delete from dage where id=1;
2ERROR 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`))


提示:不行呀,有约束的,大哥下面还有小弟,可不能扔下我们不管呀!

插入一个新的小弟:

1mysql> insert into xiaodi(dage_id,name) values(2,'旺角_小弟A');              
2ERROR 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`))
3


提示:小子,想造反呀!你还没大哥呢!

把外键约束增加事件触发限制:

 1mysql> show create table xiaodi;
 2
 3  CONSTRAINT `xiaodi_ibfk_1` FOREIGN KEY (`dage_id`) REFERENCES `dage` (`id`)
 4
 5mysql> alter table xiaodi drop foreign key xiaodi_ibfk_1; 
 6Query OK, 1 row affected (0.04 sec)
 7Records: 1  Duplicates: 0  Warnings: 
 8mysql> alter table xiaodi add foreign key(dage_id) references dage(id) on delete cascade on update cascade;
 9Query OK, 1 row affected (0.04 sec)
10Records: 1  Duplicates: 0  Warnings: 0


再次试着把大哥删了:

1mysql> delete from dage where id=1;
2Query OK, 1 row affected (0.01 sec)
3
4mysql> select * from dage;
5Empty set (0.01 sec)
6
7mysql> select * from xiaodi;
8Empty set (0.00 sec)



得,这回对应的小弟也没了,没办法,谁让你跟我on delete cascade了呢!

例子说明的应该蛮清楚了吧,其他功能对应手册自己实践吧!:-)

<think>好的,我现在需要帮助用户解决在MySQL 8.0中添加关联的问题。首先,我应该回顾用户提供的引用内容,确保答案准确。用户提到了四个引用,涉及语法、错误处理、InnoDB引擎支持以及两种创建方式。 首先,约束需要满足几个条件:使用InnoDB引擎,字段类型和长度必须匹配,索引的存在等。用户可能遇到的常见问题比如Error 1215,应该解释如何避免。 接下来,我需要分步骤说明创建的方法。根据引用[3]和[4],有两种方式:建表时添加和后期修改。需要给出具体的SQL示例,比如CREATE TABLE和ALTER TABLE的语法,同时注意CONSTRAINT的可选性。 还要提到的更新和删除行为,比如CASCADE、SET NULL等,这在引用[4]中有涉及。此,注意事项部分应该涵盖引擎类型、字段匹配、索引和命名约束,这些在引用[1]、[2]和[4]中都有提到。 用户可能对错误1215的原因感兴趣,需要解释可能的原因,比如引擎不对或者字段不匹配。同时,提醒他们使用SHOW ENGINE INNODB STATUS来查看详细错误信息,这来自引用[1]。 最后,生成相关问题,覆盖的作用、错误处理、不同引擎支持、行为参数以及性能影响,这样用户可以有进一步的学习方向。 需要确保回答结构清晰,步骤明确,语法正确,并且引用正确标注。避免使用Markdown,用自然的中文分步骤解释,同时保持口语化。</think>在 MySQL 8.0 中创建约束需要遵循以下步骤: ### 一、创建的条件 1. 必须使用 `InnoDB` 存储引擎(可通过 `ENGINE=InnoDB` 指定)[^2] 2. 关联字段的数据类型和长度必须完全一致 3. 父表的被引用字段必须建立索引(主或唯一索引) ### 二、创建的两种方式 #### 方式1:建表时创建 ```sql CREATE TABLE 子表 ( 子表_id INT PRIMARY KEY, 父表_id INT, -- 定义语法: FOREIGN KEY (父表_id) REFERENCES 父表(父表主字段) ON DELETE CASCADE -- 级联删除 ON UPDATE RESTRICT -- 禁止更新 ) ENGINE=InnoDB; ``` #### 方式2:后期添加(推荐) ```sql ALTER TABLE 子表 ADD CONSTRAINT fk_自定义约束名 -- CONSTRAINT可选[^4] FOREIGN KEY (字段) REFERENCES 父表(字段) [ON DELETE {RESTRICT | CASCADE | SET NULL | NO ACTION}] [ON UPDATE {RESTRICT | CASCADE | SET NULL | NO ACTION}]; ``` ### 三、行为参数说明 | 参数 | 功能说明 | |------------|------------------------------| | CASCADE | 级联操作(删除/更新父表记录时同步子表)| | SET NULL | 将子表字段设为NULL | | RESTRICT | 默认值,禁止对父表进行相关操作| | NO ACTION | 与RESTRICT等效 | ### 四、注意事项 1. 出现 Error 1215 的常见原因: - 表未使用 InnoDB 引擎 - 字段类型/长度不匹配(如 INT 与 BIGINT) - 缺少父表对应字段的索引[^1] 2. 可通过 `SHOW ENGINE INNODB STATUS` 查看详细错误信息 3. 建议显式命名约束(`CONSTRAINT fk_name`)便于后续管理
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值