MySQL 学习笔记之约束与外键

2024-08-25 05:28

本文主要是介绍MySQL 学习笔记之约束与外键,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

文章目录

      • MySQL 约束与外键
        • 1. 约束(Constraints)
          • 示例代码:
          • 插入数据:
        • 2. 外键约束与操作
          • 示例代码:
          • 外键的删除与更新行为:
          • 示例:
      • 完整代码

MySQL 约束与外键

在数据库设计中,约束(Constraints)和外键(Foreign Keys)是保证数据完整性和一致性的重要工具。本文将结合代码示例详细介绍MySQL中的主要约束类型以及外键的使用。


1. 约束(Constraints)

约束是对数据库表中列的规则,用于限制数据的类型和范围,确保数据的准确性和可靠性。常见的约束包括:

  • 非空约束(NOT NULL)
    非空约束用于确保列的值不能为空,即列的每一行数据都必须有值。
    语法:column_name data_type NOT NULL

  • 唯一约束(UNIQUE)
    唯一约束保证列中的所有值都是唯一的,即不能有重复值。
    语法:column_name data_type UNIQUE

  • 主键约束(PRIMARY KEY)
    主键用于唯一标识表中的一条记录,主键要求列的值既唯一又不能为空。每个表只能有一个主键。
    语法:column_name data_type PRIMARY KEY

  • 默认约束(DEFAULT)
    默认约束为列设置一个默认值,当插入数据时如果没有为该列指定值,则使用默认值。
    语法:column_name data_type DEFAULT default_value

  • 检查约束(CHECK)
    检查约束用于确保列的值满足特定条件。
    语法:column_name data_type CHECK (condition)

  • 外键约束(FOREIGN KEY)
    外键用于建立两张表之间的连接,确保子表中的值在父表中存在,以保证数据的完整性。
    语法:FOREIGN KEY (column_name) REFERENCES parent_table(column_name)


示例代码:
create table user
(id     int primary key auto_increment comment '主键',name   varchar(10) not null unique comment '姓名',age    int check ( age > 0 and age <= 120 ) comment '年龄',status char(1) default '1' comment '状态',gender char(1) comment '性别'
) comment '用户表';

在这个 user 表的定义中:

  • id 列被设置为主键,且自动递增。
  • name 列要求非空且唯一。
  • age 列有一个检查约束,要求年龄在0到120岁之间。
  • status 列有一个默认值 '1'
  • gender 列可以为空。

插入数据:
insert into user (name, age, status, gender)
values ('Tom1', 19, '1', '男');

该代码插入一条符合约束条件的记录。
如果尝试插入违反约束的记录,如 name 列为空或 age 列的值超出0到120的范围,将会导致插入失败并抛出错误。




2. 外键约束与操作

外键是用于在两张表之间建立关系的关键,它确保子表中的值在父表中存在,从而维护数据的完整性。

示例代码:

首先,我们创建了两个表 deptempl,分别表示部门表和员工表。


创建部门表

create table dept
(id   int auto_increment comment ' ID' primary key,name varchar(50) not null comment ' 部门名称 '
) comment ' 部门表 ';

创建员工表

create table empl
(id        int auto_increment comment ' ID' primary key,name      varchar(50) not null comment ' 姓名 ',age       int comment ' 年龄 ',job       varchar(20) comment ' 职位 ',salary    int comment ' 薪资 ',entrydate date comment ' 入职时间 ',managerid int comment ' 直属领导 ID',dept_id   int comment ' 部门 ID'
) comment ' 员工表 ';

添加外键约束
empl 表中的 dept_id 列与 dept 表中的 id 列关联:

alter table empladd constraint fk_emp_dept_id foreign key (dept_id) references dept (id);

这个外键约束确保了 empl 表中的 dept_id 必须在 dept 表中存在对应的 id

外键的删除与更新行为:

MySQL支持在父表记录被删除或更新时对子表中的相关记录进行相应的操作,常见行为包括:

  • NO ACTION: 当在父表中删除或更新记录时,如果子表中存在关联的外键记录,则不允许删除或更新。
  • RESTRICT: 与 NO ACTION 类似,不允许删除或更新。
  • CASCADE: 当在父表中删除或更新记录时,子表中相关的外键记录也会被相应删除或更新。
  • SET NULL: 当在父表中删除记录时,子表中的相关外键列会被设置为NULL。

示例:
alter table empladd constraint fk_emp_dept_id foreign key (dept_id) references dept (id) on update cascade on delete cascade;

在这个例子中,当 `dept` 表中的 `id` 被更新或删除时,`empl` 表中的 `dept_id` 将自动进行相应的更新或删除。

如果我们改为:

alter table empladd constraint fk_emp_dept_id foreign key (dept_id) references dept (id) on update set null on delete set null;

那么在 dept 表中的 id 被更新或删除时,empl 表中的 dept_id 则会被设置为 NULL




完整代码

/*
约束     描述                                          关键字
非空约束  限制该字段的数据不能为null                        not null
唯一约束  保证该字段的所有数据都是唯一的、不重复的              unique
主键约束  主键使一行数据的唯一标识,要求非空且唯一              primary key
默认约束  保存数据时,如果未指定该字段的值,则采用默认值         default
检查约束  保证字段值满足某一个条件                          check
外键约束  用来让两张表的数据之间建立连接,保证数据一致性和完整性  foreign key
*/-- ------------------------------------------ 约束演示 -----------------------------------------
-- 准备数据
create table user
(id     int primary key auto_increment comment '主键',name   varchar(10) not null unique comment '姓名',age    int check ( age > 0 and age <= 120 ) comment '年龄',status char(1) default '1' comment '状态',gender char(1) comment '性别'
) comment '用户表';-- 插入数据
insert into user (name, age, status, gender)
values ('Tom1', 19, '1', '男'),('Tom2', 25, '0', '男');
insert into user (name, age, status, gender)
values ('Tom3', 19, '1', '男');insert into user (name, age, status, gender)
values (null, 19, '1', '男');
insert into user (name, age, status, gender)
values ('Tom3', 19, '1', '男');insert into user (name, age, status, gender)
values ('Tom4', 80, '1', '男');
insert into user (name, age, status, gender)
values ('Tom5', -1, '1', '男');
insert into user (name, age, status, gender)
values ('Tom5', 121, '1', '男');insert into user (name, age, gender)
values ('Tom5', 120, '男');-- ------------------------------------------- 约束(外键)---------------------------------------
-- 准备数据
create table dept
(id   int auto_increment comment ' ID' primary key,name varchar(50) not null comment ' 部门名称 '
) comment ' 部门表 ';
INSERT INTO dept (id, name)
VALUES (1, ' 研发部 '),(2, ' 市场部 '),(3, ' 财务部 '),(4, ' 销售部 '),(5, ' 总经办 ');create table empl
(id        int auto_increment comment ' ID' primary key,name      varchar(50) not null comment ' 姓名 ',age       int comment ' 年龄 ',job       varchar(20) comment ' 职位 ',salary    int comment ' 薪资 ',entrydate date comment ' 入职时间 ',managerid int comment ' 直属领导 ID',dept_id   int comment ' 部门 ID'
) comment ' 员工表 ';INSERT INTO empl (id, name, age, job, salary, entrydate, managerid, dept_id)
VALUES (1, ' 金庸 ', 66, ' 总裁 ', 20000, ' 2000-01-01', null, 5),(2, ' 张无忌 ', 20, ' 项目经理 ', 12500, ' 2005-12-05', 1, 1),(3, ' 杨逍 ', 33, ' 开发 ', 8400, ' 2000-11-03', 2, 1),(4, ' 韦一笑 ', 48, ' 开发 ', 11000, ' 2002-02-05', 2, 1),(5, ' 常遇春 ', 43, ' 开发 ', 10500, ' 2004-09-07', 3, 1),(6, ' 小昭 ', 19, ' 程序员鼓励师 ', 6600, ' 2004-10-12', 2, 1);-- 添加外键
/*
create table 表名(字段名 数据类型,...[cinstraint] [外键名称] foreign key(外键字段名) references 主表(主表列名)
);alter table 表名 add constraint 外键名称 foreign key (外键名称) references 主表(主表列名);
*/
alter table empladd constraint fk_emp_dept_id foreign key (dept_id) references dept (id);-- 删除外键
-- alter table 表名 drop foreign key 外键名称;
alter table empldrop foreign key fk_emp_dept_id;-- 删除/更新行为
/*
行为          说明
no action    当在父表中删除/更新对应记录时,首先检查该记录是否有对应外键,如果有则不允许删除/更新。(与 RESTRICT 一致)
restrict     当在父表中删除/更新对应记录时,首先检查该记录是否有对应外键,如果有则不允许删除/更新。(与 NO ACTION 一致
cascade      当在父表中删除/更新对应记录时,首先检查该记录是否有对应外键,如果有,则也删除/更新外键在子表中的记录。
set null     当在父表中删除对应记录时,首先检查该记录是否有对应外键,如果有则设置子表中该外键值为nul.(这就要求该外键允许取u1)。
set default  父表有变更时,子表将外键列设置成一个默认的值(Innodb不支持)ALTER TABLE 表名 ADD ONSTRANT 外键名称 FOREIGN KEY 外字) REFERENCES 丰表名(主表字段名) ON UPDATE CASCADF ON DFIFTF CASCADFI;
*/alter table empladd constraint fk_emp_dept_id foreign key (dept_id) references dept (id) on update cascade on delete cascade;alter table empladd constraint fk_emp_dept_id foreign key (dept_id) references dept (id) on update set null on delete set null;

这篇关于MySQL 学习笔记之约束与外键的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1104670

相关文章

canal实现mysql数据同步的详细过程

《canal实现mysql数据同步的详细过程》:本文主要介绍canal实现mysql数据同步的详细过程,本文通过实例图文相结合给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的... 目录1、canal下载2、mysql同步用户创建和授权3、canal admin安装和启动4、canal

SQL中JOIN操作的条件使用总结与实践

《SQL中JOIN操作的条件使用总结与实践》在SQL查询中,JOIN操作是多表关联的核心工具,本文将从原理,场景和最佳实践三个方面总结JOIN条件的使用规则,希望可以帮助开发者精准控制查询逻辑... 目录一、ON与WHERE的本质区别二、场景化条件使用规则三、最佳实践建议1.优先使用ON条件2.WHERE用

MySQL存储过程之循环遍历查询的结果集详解

《MySQL存储过程之循环遍历查询的结果集详解》:本文主要介绍MySQL存储过程之循环遍历查询的结果集,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录前言1. 表结构2. 存储过程3. 关于存储过程的SQL补充总结前言近来碰到这样一个问题:在生产上导入的数据发现

MySQL 衍生表(Derived Tables)的使用

《MySQL衍生表(DerivedTables)的使用》本文主要介绍了MySQL衍生表(DerivedTables)的使用,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学... 目录一、衍生表简介1.1 衍生表基本用法1.2 自定义列名1.3 衍生表的局限在SQL的查询语句select

MySQL 横向衍生表(Lateral Derived Tables)的实现

《MySQL横向衍生表(LateralDerivedTables)的实现》横向衍生表适用于在需要通过子查询获取中间结果集的场景,相对于普通衍生表,横向衍生表可以引用在其之前出现过的表名,本文就来... 目录一、横向衍生表用法示例1.1 用法示例1.2 使用建议前面我们介绍过mysql中的衍生表(From子句

六个案例搞懂mysql间隙锁

《六个案例搞懂mysql间隙锁》MySQL中的间隙是指索引中两个索引键之间的空间,间隙锁用于防止范围查询期间的幻读,本文主要介绍了六个案例搞懂mysql间隙锁,具有一定的参考价值,感兴趣的可以了解一下... 目录概念解释间隙锁详解间隙锁触发条件间隙锁加锁规则案例演示案例一:唯一索引等值锁定存在的数据案例二:

MySQL JSON 查询中的对象与数组技巧及查询示例

《MySQLJSON查询中的对象与数组技巧及查询示例》MySQL中JSON对象和JSON数组查询的详细介绍及带有WHERE条件的查询示例,本文给大家介绍的非常详细,mysqljson查询示例相关知... 目录jsON 对象查询1. JSON_CONTAINS2. JSON_EXTRACT3. JSON_TA

MySQL 设置AUTO_INCREMENT 无效的问题解决

《MySQL设置AUTO_INCREMENT无效的问题解决》本文主要介绍了MySQL设置AUTO_INCREMENT无效的问题解决,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参... 目录快速设置mysql的auto_increment参数一、修改 AUTO_INCREMENT 的值。

MYSQL查询结果实现发送给客户端

《MYSQL查询结果实现发送给客户端》:本文主要介绍MYSQL查询结果实现发送给客户端方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录mysql取数据和发数据的流程(边读边发)Sending to clientSending DataLRU(Least Rec

MySQL分区表的具体使用

《MySQL分区表的具体使用》MySQL分区表通过规则将数据分至不同物理存储,提升管理与查询效率,本文主要介绍了MySQL分区表的具体使用,具有一定的参考价值,感兴趣的可以了解一下... 目录一、分区的类型1. Range partition(范围分区)2. List partition(列表分区)3. H