外键字段必须先是一个索引,否则将会先创建索引,然后才能创建外键。

如果外键字段为混合键值其中一个,需要为该字段建立单独索引。删除的时候必须先删除外键,才能删除索引。

子表中外键字段数据要么为null,要么为父表中引用字段数据!

【1】创建表的时候增加外键

此时创建的索引使用默认名字;创建的外键为表默认名字。

create table my_foreign1(
id int PRIMARY KEY auto_increment,
name varchar(20) default null COMMENT '名字',
age int,
p_id INT,
FOREIGN KEY (p_id) REFERENCES p_user_2(id)
)CHARSET utf8;-- FOREIGN KEY fk_id(p_id) REFERENCES p_user_2(id)
--将指定索引名字为fk_id,但是不能改变外键名字。

查看表结构

CREATE TABLE `my_foreign1` (`id` int(11) NOT NULL AUTO_INCREMENT,`name` varchar(20) DEFAULT NULL COMMENT '名字',`age` int(11) DEFAULT NULL,`p_id` int(11) DEFAULT NULL,PRIMARY KEY (`id`),KEY `p_id` (`p_id`),// 先添加了索引,再创建外键CONSTRAINT `my_foreign1_ibfk_1` FOREIGN KEY (`p_id`) REFERENCES `p_user_2` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

创建表时创建外键并指定索引名字和外键名字

create table my_foreign1(
id int PRIMARY KEY auto_increment,
name varchar(20) default null COMMENT '名字',
age int,
p_id INT,
CONSTRAINT fk_pid FOREIGN KEY (p_id) REFERENCES p_user_2(id)
)CHARSET utf8;-- 索引和外键名字都为 fk_pid;

查看表结构

CREATE TABLE `my_foreign1` (`id` int(11) NOT NULL AUTO_INCREMENT,`name` varchar(20) DEFAULT NULL COMMENT '名字',`age` int(11) DEFAULT NULL,`p_id` int(11) DEFAULT NULL,PRIMARY KEY (`id`),KEY `fk_pid` (`p_id`),CONSTRAINT `fk_pid` FOREIGN KEY (`p_id`) REFERENCES `p_user_2` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

【2】创建表后为表增加外键

语法格式如下:

alter table [table_name]
add [constraint] [constraint_name]
[unique| primary key|foreign key]
([column_name])

如果外键字段没有索引,会先添加索引,然后创建外键;

ALTER TABLE t_class
add CONSTRAINT fk_teacher_id
FOREIGN KEY (t_id) REFERENCES t_teacher(t_id)

【3】为表删除外键

先删除外键,后删除索引;不能先删除索引,因为有外键约束。

ALTER TABLE t_class
drop FOREIGN KEY fk_teacher_id(外键名,非字段名);-- 根据外键名删除外键ALTER TABLE t_class
drop index fk_teacher_id;
-- 删除对应索引

【4】创建外键的几个条件

总结如下:

  • 父表和子表引擎一致,否则报错;

  • 保证表的存储引擎为InnoDB,否则虽然不报错但是无约束(只有index);

    实际上,如果两个表都是MyISAM 引擎的,错误根本不会发生,但也不会产生外键。

  • 两个字段数据类型一致,数据显示长度可以不同,另外需注意有符号无符号,必须一致;

  • 两个字段都添加了独立索引,如果子表外键字段无索引,那么在创建外键的时候会自动先添加索引;如果父表字段无索引,将报错;

  • 字段是否允许为空,在更新或删除时候对外键字段操作有关;如外键创建时候 on delete set null on udpate cascade。但是子表外键字段不允许为空, 矛盾,创建不成功。

  • 字段的字符集和校对集(外键类型为字符的时候);

  • 外键名字不能重复,是针对数据库而不是表;

  • 子表外键字段 - 数据 为父表引用字段子集;

  • 字段可能为混合键值中一个,没有自己独立索引。外键字段必须有自己独立索引。


【5】外键的作用

外键默认的作用有两点:一个对父表,一个对子表(外键字段所在的表)。

对子表约束

子表数据在进行写操作(增和改)的时候,如果对应的外键字段在父表找不到对应的匹配,那么操作会失败。插入的时候外键字段值要么为null,要么为父表中字段。

INSERT into my_foreign1 values(null,'嘉嘉',12,40)

插入的40为外键字段数据,在父表中对应的被引用字段无此数据值。


对父表约束

父表数据进行写操作(删和改:都必须涉及到字段本身),如果对应的字段在子表中已经被数据所引用,那么就不允许操作。

INSERT into my_foreign1 values(null,'皇甫',18,2)
INSERT into my_foreign1 values(null,'嘉嘉',12,4)

2,4分别为父表里面被引用的字段数据。现在尝试更改2:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0o3QaJtp-1654482724968)(https://img-blog.csdn.net/20170606170723575?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvSjA4MDYyNA==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)]


【6】外键约束模式


外键约束有三种约束模式:都是针对父表; 对应MySQL有四种约束:RESTRICT,NO ACTION , CASCADE , SET NULL。

① RESTRICT

严格模式(默认的),父表不能删除或者更新一个已经被子表引用的记录数据(外键对应的父表被引用的字段,其他字段可以更改)。

即,当父表字段数据已经被子表引用时,不能再删除或者更新父表被引用的字段数据。

示例如下:

ALTER TABLE my_foreign1 add CONSTRAINT fk_id
FOREIGN KEY (p_id) REFERENCES  p_user_2(id)
ON DELETE NO ACTION ON UPDATE NO ACTION;-- 或者
ON DELETE RESTRICT ON UPDATE RESTRICT;

② Cascade

级联模式;针对父表的操作,对应子表关联的数据也跟着被操作。

  • 更新父表被引用的字段,如果该数据被子表外键使用,则子表外键随之更新;
  • 删除父表被引用的字段记录,如果该数据被子表外键使用,子表对应外键所属记录随之删除。

示例如下:

ALTER TABLE my_foreign1 add CONSTRAINT fk_id
FOREIGN KEY (p_id) REFERENCES  p_user_2(id)
ON DELETE CASCADE ON UPDATE CASCADE;

③Set null

置空模式,父表字段操作之后,如果该数据被子表外键使用,子表对应的外键字段被置空。

外键置空的前提是对应字段允许为空,否则外键创建不成功。

示例如下:

ALTER TABLE my_foreign1 add CONSTRAINT fk_id
FOREIGN KEY (p_id) REFERENCES  p_user_2(id)
ON DELETE SET NULL ON UPDATE SET NULL;

通常一个合理的做法(约束模式)是:删除的时候子表置空,更新的时候子表级联:

ON DELETE SET NULL ON UPDATE CASCADE;

【7】创建外键出现的错误

① errno: 150错误:

这种情况下,参考创建外键的几个条件,一一排查。

② error:121错误:

这种情况下显然是你的外键名字重复。MySQL判断外键名字基础单位是数据库,而不是表。

用如下语句查看数据库已经存在的外键与所属表:

SELECTconstraint_name,table_name
FROMinformation_schema.table_constraints
WHEREconstraint_type = 'FOREIGN KEY'
AND table_schema = DATABASE()
ORDER BYconstraint_name;

MySQL 中外键与使用详解相关推荐

  1. mysql临键锁_详解 MySql InnoDB 中的三种行锁(记录锁、间隙锁与临键锁)

    详解 MySql InnoDB 中的三种行锁(记录锁.间隙锁与临键锁) 前言 InnoDB 通过 MVCC 和 NEXT-KEY Locks,解决了在可重复读的事务隔离级别下出现幻读的问题.MVCC  ...

  2. mysql 主键溢出检查_详解MySQL 表中非主键列溢出情况监控

    今天,又掉坑了. 之前踩到过MySQL主键溢出的情况,通过prometheus监控起来了. 这次遇到的坑,更加的隐蔽. 是一个log表里面的一个int signed类型的列写满了.快速的解决方法当然还 ...

  3. mysql 外键设置_详解MySQL外键设置

    MySQL外键设置是学习MySQL数据库过程中不能不提的,下面就会为您详细介绍MySQL外键设置的方法,希望对您学习MySQL外键设置方面能有所帮助. 外键的作用: 保持数据一致性,完整性,主要目的是 ...

  4. mysql入门优化_MySQL数据库:MySQL十大优化技巧详解

    本文主要向大家介绍了MySQL数据库的MySQL十大优化技巧详解,通过具体的内容向大家展现,希望对大家学习MySQL数据库有所帮助. WEB开发者不光要解决程序的效率问题,对数据库的快速访问和相应也是 ...

  5. mysql 聚集函数 count 使用详解

    mysql 聚集函数 count 使用详解 本文将探讨以下问题 1.count(*) . count(n).count(null)与count(fieldName) 2.distinct 与 coun ...

  6. MySQL数据类型以及基本使用详解

    MySQL数据类型以及基本使用详解 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.MySQL服务器的主要组件 我们知道MySQL的主要组件主要是由服务端(mysqld)和客户端 ...

  7. linux 用root安装mysql数据库_Linux上安装Mysql及简单的使用详解

    1. 安装mysql sudo apt-get update sudo apt-get install mysql-server sudo apt-get install python-mysqldb ...

  8. docker导入MySQL文件_Docker容器中Mysql数据的导入/导出详解

    前言 Mysql数据的导入导出我们都知道一个mysqldump命令就能够解决,但如果是运行在docker环境下的mysql呢? 解决办法其实还是用mysqldump命令,但是我们需要进入docker的 ...

  9. php mysql无限_php+mysql实现无限分类实例详解

    php+mysql实现无限分类实例详解 fenlei($arr[$i][0]);   //$arr[$i][1]表示第$i+1个分类的id的值.进行递归,也就是把自己的id作为f_id参数把自己的子类 ...

最新文章

  1. 做一个有姿态的女孩子
  2. 韩军星:汇报工作的四个层级
  3. 电子表单设计,表单打印,表单填写,数据发布,VC++,VB,源代码组件库
  4. 画图软件怎么做性能测试,软件性能测试能力提升解决方案.pdf
  5. 什么是3G-SDI光端机?
  6. nginx模块nginx_upstream_check_module来检查后端服务器的健康情况
  7. 启动root用户 银河麒麟_银河麒麟桌面版系统-用户密码到期无法正常进入系统解决办法...
  8. 微型计算机原理与接口技术知识点
  9. Matlab绘制简单动画
  10. 商超霸主之争:天猫节节败退 沦为京东陪练
  11. 计算机管理员权限打不开怎么办,administrator管理员权限怎么打开?
  12. 量子通信,究竟是怎样保障信息安全的?
  13. 硬件开发:嵌入式系统知识和接口技术(值得收藏)
  14. 基因组序列genbank格式和fasta格式批量下载
  15. Android开发 报错: xxx does not have a NavController set on xxx
  16. 一段从API读取基金净值信息并写入Excel表的Python代码
  17. 数字孪生技术打造智慧车联网数据可视化大屏
  18. 有10瓶药 里面有9瓶是无毒的 有1瓶毒药
  19. 7月29日绝地求生服务器维护,绝地求生7月29日正式服维护公告内容一览
  20. 文件查找 find locate

热门文章

  1. C语言编程:猴子吃桃问题
  2. 【引用】音频文件格式全介绍_chrome os
  3. 制定项目计划,确保团队协同效率
  4. 校园最热微信小程序——校园表白墙之我想对你说(青春感人系列)
  5. 逐次超松弛迭代法SOR
  6. 硬件术语大全—CPU、内存、主板、硬盘、显卡、显示器
  7. assets在前端开发项目中的含义是什么
  8. 图书管理系统测试计划说明书
  9. 区块链学习 | 区块链的核心概念
  10. 个人设计web前端大作业