MySQL数据库的主键和外键详解

主键

主键的定义

主键:表中经常有一个列或多列的组合,其值能唯一地标识表中的每一行。这样的一列或多列称为表的主键,通过它可强制表的实体完整性。当创建或更改表时可通过定义 PRIMARY KEY 约束来创建主键。一个表只能有一个 PRIMARY KEY 约束,而且 PRIMARY KEY 约束中的列不能接受空值。由于 PRIMARY KEY 约束确保唯一数据,所以经常用来定义标识列。作用:

1)保证实体的完整性;

2)加快数据库的操作速度

3) 在表中添加新记录时,DBMS会自动检查新记录的主键值,不允许该值与其他记录的主键值重复。

4) DBMS自动按主键值的顺序显示表中的记录。如果没有定义主键,则按输入记录的顺序显示表中的记录。

联合主键关系数据库实际上还允许通过多个字段唯一标识记录,即两个或更多的字段都设置为主键,这种主键被称为联合主键。

对于联合主键,允许一列有重复,只要不是所有主键列都重复即可。

主键的特性

主键的必要性

在有些数据库中,虽然主键不是必需的,但最好为每个表都设置一个主键,不管是单主键还是复合主键。它存在代表着表结构的完整性,表的记录必须得有唯一区分的字段,主键主要是用于其他表的外键关联,以及本记录的修改与删除。

主键的无意义性

由于主键的作用十分重要,如何选取主键会对业务开发产生重要影响。如果我们以学生的身份证号作为主键,似乎能唯一定位记录。然而,身份证号也是一种业务场景,如果身份证号升位了,或者需要变更,作为主键,不得不修改的时候,就会对业务产生严重影响。

选取主键的一个基本原则是:不使用任何业务相关的字段作为主键。

因此,身份证号、手机号、邮箱地址这些看上去可以唯一的字段,均不可用作主键。

主键的选择自增整数类型:数据库会在插入数据时自动为每一条记录分配一个自增整数,这样我们就完全不用担心主键重复,也不用自己预先生成主键;

全局唯一GUID类型:使用一种全局唯一的字符串作为主键,类似8f55d96b-8acc-4636-8cb8-76bf8abc2f57。GUID算法通过网卡MAC地址、时间戳和随机数保证任意计算机在任意时间生成的字符串都是不同的,大部分编程语言都内置了GUID算法,可以自己预算出主键。对于大部分应用来说,通常自增类型的主键就能满足需求

定义的自增性整数类型的主键一般使用是BIGINT NOT NULL AUTO_INCREMENT类型。

如果使用INT自增类型,那么当一张表的记录数超过2147483647(约21亿)时,会达到上限而出错。使用BIGINT自增类型则可以最多约922亿亿条记录。

外键

外键的定义如果公共关键字在一个关系中是主关键字,那么这个公共关键字被称为另一个关系的外键。由此可见,外键表示了两个关系之间的相关联系。以另一个关系的外键作主关键字的表被称为主表,具有此外键的表被称为主表的从表。外键又称作外关键字。

举例:

student表:

class表:

由于一个班级可以有多个学生,在关系模型中,这两个表的关系可以称为“一对多”,即一个class的记录可以对应多个student表的记录。

为了表达这种一对多的关系,我们需要在student表中加入一列class_id,让它的值与class表的某条记录相对应。

这样,我们就可以根据class_id这个列直接定位出一个student表的记录应该对应到class的哪条记录。

在student表中,通过class_id的字段,可以把数据与另一张表关联起来,这种列称为外键。

外键并不是通过列名实现的,而是通过定义外键约束实现的:

//定义外键约束

ALTER TABLE student

ADD CONSTRAINT fk_class_id //外键约束的名称fk_class_id可以任意

FOREIGN KEY (class_id) //指定了class_id作为外键

REFERENCES class (id); //指定了这个外键将关联到class表的id列(即class表的主键)class_id为学生表的外键。(此时student表中的class_id与class表中的id表示的含义相同)

此时外键表是student表,主键表是class表。

要删除一个外键约束,也是通过ALTER TABLE实现的:

ALTER TABLE student

DROP FOREIGN KEY fk_class_id;由于外键约束会降低数据库的性能,大部分互联网应用程序为了追求速度,并不设置外键约束,而是仅靠应用程序自身来保证逻辑的正确性。这种情况下,class_id仅仅是一个普通的列,只是它起到了外键的作用而已。

选取设置 MySQL 外键的字段定义一个外键时,需要遵守下列规则:父表必须已经存在于数据库中,或者是当前正在创建的表。如果是后一种情况,则父表与子表是同一个表,这样的表称为自参照表,这种结构称为自参照完整性。

必须为父表定义主键。

主键不能包含空值,但允许在外键中出现空值。也就是说,只要外键的每个非空值出现在指定的主键中,这个外键的内容就是正确的。

在父表的表名后面指定列名或列名的组合。这个列或列的组合必须是父表的主键或候选键。

外键中列的数目必须和父表的主键中列的数目相同。

外键中列的数据类型必须和父表主键中对应列的数据类型相同。

外键的作用保持数据一致性,完整性。主要目的是控制存储在外键表中的数据。 使两张表形成关联,外键只能引用外表中的列的值或使用空值

外键约束MySQL外键约束(FOREIGN KEY)用来在两个表的数据之间建立链接,它可以是一列或者多列。一个表可以有一个或多个外键。

外键是表的一个字段,不是本表的主键,但对应另一个表的主键。定义外键后,不允许删除另一个表中具有关联关系的行。主表(父表)

对于两个具有关联关系的表而言,相关联字段中主键所在的表就是主表。

被引用的表叫主表(父表)。

从表(子表)

对于两个具有关联关系的表而言,相关联字段中外键所在的表就是从表。

定义了外键的表叫从表(子表)。

外键约束的作用:

阻止执行从表插入新行,其外键值不是主表的主键值便阻止插入;

从表修改外键值,新值不是主表的主键值便阻止修改;

主表删除行,其主键值在从表里存在便阻止删除(要想删除,必须先删除从表的相关行);

主表修改主键值,旧值在从表里存在便阻止修改(要想修改,必须先删除从表的相关行)。

级联执行主表删除行,连带从表的相关行一起删除;

主表修改主键值,连带从表相关行的外键值一起修改。两种方法提供给用户选择。无论选取哪种方法,从表里都不会有多余行。从另一个角度理解,用拒绝同一事物在从表中的标志与主表不一致来实现与主表中的标志一致。

两种实现方法,通过下面方式选择:界面:设级联更新、级联删除两个选择方框,选取则级联执行、不选取则阻止执行;

命令:设E)kSCM)E、RESTRICT两个可选项,CASCADE为级联执行、RESTRICT为阻止执行。

CASCADE:级联删除

在外键表的最后,加上on delete cascade 就是级联删除

再删除主表数据时和主表关联的子表数据也会删除

CREATE TABLE `student` (

`id` bigint(64) NOT NULL AUTO_INCREMENT,

`class_id` bigint(64) DEFAULT NULL,

`name` varchar(32) COLLATE utf8_bin DEFAULT NULL,

`age` int(32) DEFAULT NULL,

`sex` varchar(32) COLLATE utf8_bin DEFAULT NULL,

PRIMARY KEY (`id`),

KEY `fk_class_id` (`class_id`),

CONSTRAINT `fk_class_id` FOREIGN KEY (`class_id`) REFERENCES `class` (`id`)

on delete cascade,

)所谓的级联删除,就是删除主键表的同时,外键表同时删除。

以上面的例子将就是,假如班级表中的某个班级被删除了,那么在学生表中要想查询这个被删除的班级号所对应的班级信息就会报错,因为已经不存在这个班级了,所以,删除班级表(主键表)时必须删除其他与之关联的表,这里就说明了外键的作用,保持数据的一致性、完整性。当然反过来讲,你删除学生表中的记录,并不影响班级表中的数据,你查询班级号也能正确查询。所以删除外键表中的数据并不影响主键表。

RESTRICT:约束/限制、NO ACTION(非活动,默认)当取值为No Action或者Restrict时,则当在主键表中删除对应记录时,首先检查该记录是否有对应外键,如果有则不允许删除。(即外键表约束主键表)

SET NULL:级联置空

在在外键表的最后,加上on delete set null就是级联置空

再删除主表数据时,会把和主表关联的外键设置成NULL

CREATE TABLE `student` (

`id` bigint(64) NOT NULL AUTO_INCREMENT,

`class_id` bigint(64) DEFAULT NULL,

`name` varchar(32) COLLATE utf8_bin DEFAULT NULL,

`age` int(32) DEFAULT NULL,

`sex` varchar(32) COLLATE utf8_bin DEFAULT NULL,

PRIMARY KEY (`id`),

KEY `fk_class_id` (`class_id`),

CONSTRAINT `fk_class_id` FOREIGN KEY (`class_id`) REFERENCES `class` (`id`)

on delete set null,

)当取值为Set Null时,则当在主键表中删除对应记录时,首先检查该记录是否有对应外键,如果有则设置子表中该外键值为null,(一样是外键表约束主键表,不过这就要求该外键允许取null)。

NO ACTION和RESTRICT的区别:只有在及个别的情况下会导致区别,前者是在其他约束的动作之后执行,后者具有最高的优先权执行。

注意

删除表时,应该先删子表,后删父表,除非使用casecade constraints 解除关联。

先删除父表时会报错:有一个被foreign keys关联的 key的字段在子表中

查询:drop table class

错误代码: 3730

Cannot drop table 'class' referenced by a foreign key constraint 'fk_class_id' on table 'student'.

如果一定要先删除父表

使用casecade constraints解除关联就可以删掉父表。

mysql外键必须连接主键_MySQL数据库的主键和外键详解3相关推荐

  1. mysql 主键长度_MySQL 数据库,主键为何不宜太长长长长长长长长?

    回答星球水友提问:沈老师,我听网上说,MySQL数据表,在数据量比较大的情况下,主键不宜过长,是不是这样呢?这又是为什么呢? 这个问题嘛,不能一概而论: (1)如果是InnoDB存储引擎,主键不宜过长 ...

  2. mysql数据库帐户_MySQL数据库用户帐号管理基础知识详解

    MySQL管理员应该知道怎样通过指定哪些用户可连接到服务器.从哪里进行连接,以及在连接 时做什么,来设置MySQL用户账号.MySQL3.22.11引入了两个更容易进行这项工作的语句:GRANT 语句 ...

  3. mysql行转列和列转行_mysql 行转列和列转行实例详解

    mysql行转列.列转行 语句不难,不做多余解释了,看语句时,从内往外一句一句剖析 行转列 有如图所示的表,现在希望查询的结果将行转成列 建表语句如下: create table `test_tb_g ...

  4. mysql将权限分为几个层级_MySQL多层级结构-区域表使用树详解

    1.1. 前言 前面我们大概介绍了一下树结构表的基本使用.在我们项目中有好几块有用到多层级的概念.下面我们哪大家都比较熟悉的区域表来做演示. 1.2. 表结构和数据 区域表基本结构,可能在你的项目中还 ...

  5. CentOS 7下载安装MySQL 5.7以及连接虚拟机CentOS 7数据库教程

    CentOS 7下载安装MySQL 5.7以及连接虚拟机CentOS 7数据库教程 文章目录 CentOS 7下载安装MySQL 5.7以及连接虚拟机CentOS 7数据库教程 创建一个mysql 文 ...

  6. MySQL隔离级别--未提交读,提交读,可重复读,序列化--详解(有示例)

    原文网址:MySQL隔离级别--未提交读,提交读,可重复读,序列化--详解(有示例)_IT利刃出鞘的博客-CSDN博客 简介          本文介绍MySQL的事务隔离级别的含义,并用示例说明各个 ...

  7. 玉米社:外链、反链、内链、友链的区别与联系详解

    外链.反链.内链.友链的区别与联系详解 1.外链 外链指从站外链向本站点某页面的链接,主要强调站外.我们常说的发外链,即在外部博客.论坛.自媒体等平台发布的带有自身网站链接的软文或者视频内容,但凡是从 ...

  8. mysql选择主键的原则_如何选择数据库的主键

    我们现在在思考一下,应该采用什么来作表的主键比较合理,申明一下,主键的设计没有一个定论,各人有各人的方法,哪怕同一个,在不同的项目中,也会采用不同的主键设计原则. 第一:编号作主键 此方法就是采用实际 ...

  9. linux mysql主主复制_MySQL主从复制与主主复制

    1.简介 MySQL作为世界上使用最为广泛的数据库之一,免费是其原因之一.但不可忽略的是它本身的功能的确很强大.随着技术的发展,在实际的生产环境中,由单台MySQL数据库服务器不能满足实际的需求.此时 ...

  10. linux中mysql主主搭建_mysql 主从配置 主主配置

    MySQL 主从( MySQL Replication) ,主要用于 MySQL 的时时备份或者读写分离.在配置之前先做一下准备工作,配置两台 mysql 服务器,如果你的机器不能同时跑两台 Linu ...

最新文章

  1. 《敏捷迭代开发:管理者指南》—第2章2.5节渐进开发和自适应开发
  2. 基于BERT的多模学习——VL-BERT篇
  3. 阿里测试环境运维及研发效率提升之道
  4. 云上救命APP!——e代驾手机客户端!
  5. python关于二手房的课程论文_python之数据清理-以二手房信息为例
  6. Css3旋转、位移、缩放、倾斜动画
  7. 随想录(octave软件)
  8. leetcode[94]Binary Tree Inorder Traversal
  9. java的Apollo的功能_Apollo配置中心
  10. NWT失败反省:不想办法开展业务,天天想着让别人不能用
  11. java编程练习题三
  12. C#毕业设计——基于C#+asp.net+SQL server的房地产信息管理系统设计与实现(毕业论文+程序源码)——房地产信息管理系统
  13. 高通WCNSS驱动简析
  14. 【滤波器】4. 反相输入有源低通滤波器
  15. 东芝服务器硬盘参数,性能媲美万转 东芝8TB MG05硬盘体验
  16. 道指30只成分股的股价及历史股价抓取分析
  17. c语言高斯法解方程,用C语言实现解线性方程组的高斯消去法
  18. python怎么判断质数和合数_用java如何写代码去判断质数和合数
  19. Nuxt.js 如何做SEO
  20. python对月饼数据进行可视化,看看哪家最划算

热门文章

  1. onTouch事件分发
  2. 【转】小结登录的几种交互方式
  3. 第二十四章 异常和错误处理 6异常类与模板的关系
  4. scott用户对象维护
  5. 防范项目中人员频繁变动的风险
  6. matlab:randn函数产生图像高斯噪声
  7. 图像缩放之双线性插值
  8. linux下 复制文件显示进度 alias cp
  9. f3 fatfree小型php,F3-fatfree小型php框架教程(三)
  10. 字符串函数sprintf / sprintf_s 容易出错的地方