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 empl
    add 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 empl
    add 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 empl
    add 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 empl
    add constraint fk_emp_dept_id foreign key (dept_id) references dept (id);

-- 删除外键
-- alter table 表名 drop foreign key 外键名称;
alter table empl
    drop 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 empl
    add constraint fk_emp_dept_id foreign key (dept_id) references dept (id) on update cascade on delete cascade;

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

你可能感兴趣的:(mysql,笔记)