数据库---Day6 数据库约束

本系列可作为数据库学习系列的笔记,文中提到的一些练习的代码,小编会将代码复制下来,大家复制下来就可以练习了,方便大家学习。

点赞关注不迷路!您的点赞、关注和收藏是对小编最大的支持和鼓励!

系列文章目录

JAVA初阶---------已更完

JAVA数据结构---------已更完

数据库---Day 1 数据库基础

数据库---Day2 数据库操作

数据库---Day3 数据类型

数据库---Day4 数据表的操作

数据库---Day5 数据表的增删改查

数据库---Day6 数据库约束

数据库---Day7 数据表设计


目录

目录

系列文章目录

目录

前言

[0. 本节学习目标](#0. 本节学习目标)

[1. 什么是数据库约束](#1. 什么是数据库约束)

[2. 六大约束类型总览(完整版对照表)](#2. 六大约束类型总览(完整版对照表))

[3. NOT NULL 非空约束(超详细)](#3. NOT NULL 非空约束(超详细))

[3.1 作用](#3.1 作用)

[3.2 无约束时的问题(数据不完整)](#3.2 无约束时的问题(数据不完整))

[3.3 添加非空约束](#3.3 添加非空约束)

[3.4 插入 NULL 报错](#3.4 插入 NULL 报错)

[3.5 正常插入](#3.5 正常插入)

[3.6 查看非空约束](#3.6 查看非空约束)

[4. DEFAULT 默认约束(超详细)](#4. DEFAULT 默认约束(超详细))

[4.1 作用](#4.1 作用)

[4.2 无默认约束时](#4.2 无默认约束时)

[4.3 添加默认约束](#4.3 添加默认约束)

[4.4 不指定 age → 自动用默认值](#4.4 不指定 age → 自动用默认值)

[4.5 手动赋 NULL → 依然是 NULL](#4.5 手动赋 NULL → 依然是 NULL)

[4.6 查看默认约束](#4.6 查看默认约束)

[5. UNIQUE 唯一约束(超详细)](#5. UNIQUE 唯一约束(超详细))

[5.1 作用](#5.1 作用)

[5.2 无唯一约束 → 可重复](#5.2 无唯一约束 → 可重复)

[5.3 添加唯一约束](#5.3 添加唯一约束)

[5.4 插入重复值 → 报错](#5.4 插入重复值 → 报错)

[5.5 查看唯一约束](#5.5 查看唯一约束)

[6. PRIMARY KEY 主键约束(最重点)](#6. PRIMARY KEY 主键约束(最重点))

[6.1 主键是什么](#6.1 主键是什么)

[6.2 主键三大规则](#6.2 主键三大规则)

[6.3 单列主键(最常用)](#6.3 单列主键(最常用))

[6.4 主键 + 自增 AUTO_INCREMENT](#6.4 主键 + 自增 AUTO_INCREMENT)

[6.5 自增主键插入](#6.5 自增主键插入)

[6.6 自增细节](#6.6 自增细节)

[6.7 主键冲突处理(高级用法)](#6.7 主键冲突处理(高级用法))

[6.7.1 存在则更新:ON DUPLICATE KEY UPDATE](#6.7.1 存在则更新:ON DUPLICATE KEY UPDATE)

[6.7.2 存在则替换:REPLACE](#6.7.2 存在则替换:REPLACE)

[6.8 复合主键(多列联合)](#6.8 复合主键(多列联合))

[7. FOREIGN KEY 外键约束(表关系核心)](#7. FOREIGN KEY 外键约束(表关系核心))

[7.1 外键作用](#7.1 外键作用)

[7.2 核心概念](#7.2 核心概念)

[7.3 步骤 1:创建主表(班级)](#7.3 步骤 1:创建主表(班级))

[7.4 步骤 2:创建从表(学生 + 外键)](#7.4 步骤 2:创建从表(学生 + 外键))

[7.5 查看外键](#7.5 查看外键)

[7.6 外键约束规则(必背)](#7.6 外键约束规则(必背))

[7.7 插入不存在的班级 → 报错](#7.7 插入不存在的班级 → 报错)

[7.8 删除被引用班级 → 报错](#7.8 删除被引用班级 → 报错)

[7.9 删除表顺序](#7.9 删除表顺序)

[8. CHECK 约束(自定义数据规则)](#8. CHECK 约束(自定义数据规则))

[8.1 说明](#8.1 说明)

[8.2 学生表 CHECK 示例](#8.2 学生表 CHECK 示例)

[8.3 违反 CHECK → 报错](#8.3 违反 CHECK → 报错)

[8.4 跨列比较 CHECK](#8.4 跨列比较 CHECK)

[9. 全套约束高频面试题(背会稳过)](#9. 全套约束高频面试题(背会稳过))

[10. 全文总结(极简记忆版)](#10. 全文总结(极简记忆版))

总结


前言

小编作为新晋码农一枚,会定期整理一些写的比较好的代码,作为自己的学习笔记,会试着做一下批注和补充,如转载或者参考他人文献会标明出处,非商用,如有侵权会删改!欢迎大家斧正和讨论!

0. 本节学习目标

  1. 掌握约束的使用场景
  2. 掌握以下 6 种约束的创建与使用:
    • NOT NULL 非空约束
    • DEFAULT 默认约束
    • UNIQUE 唯一约束
    • PRIMARY KEY 主键约束
    • FOREIGN KEY 外键约束
    • CHECK 约束

1. 什么是数据库约束

数据库约束 :对数据库表中的数据施加的强制规则 / 条件 。作用:确保数据准确、可靠、完整、一致,从数据库层面拦截非法数据。

数据库约束是数据库的一个重要功能,主要作用是保证数据的完整性,也可能理解数据的正确性(数据本身是否正确,关联关系是否正确)。人工检查数据完整性的工作量非常大,在数据表中定义一些约束,那么数据库写入数据的时候,数据库会帮我们做校验工作。

约束一般是指定在列上的

约束可以基于:

  • 数据是否为空
  • 值是否唯一
  • 默认值
  • 关联关系
  • 自定义值范围

一句话:约束 = 数据库的守门员。

2. 六大约束类型总览(完整版对照表)

约束名称 关键字 核心作用 特点
非空约束 NOT NULL 列不能存储 NULL 保证关键字段必须有值
默认约束 DEFAULT 未赋值时自动填充默认值 手动写 NULL 仍为 NULL
唯一约束 UNIQUE 列值不能重复 允许多个 NULL
主键约束 PRIMARY KEY 唯一标识表中每一行 非空 + 唯一,一张表只能一个
外键约束 FOREIGN KEY 建立两表关联关系 保证引用完整性
CHECK 约束 CHECK 限制值的范围 / 规则 MySQL 8.0.16+ 真正生效

3. NOT NULL 非空约束(超详细)

3.1 作用

指定列不允许为 NULL,保证数据完整性。例如:学生姓名、用户名、手机号不应该为 NULL。

没有指定非空约束时,当前的列是可以写入一个NULL值的,如果要把某一列定义为一个必填项,那么就可以使用not null非空约束。

3.2 无约束时的问题(数据不完整)

sql 复制代码
DROP TABLE IF EXISTS student;
CREATE TABLE student(
    id BIGINT,
    name VARCHAR(20)
);

-- 可以插入 NULL,数据无意义
INSERT INTO student VALUES (1, NULL);

SELECT * FROM student;
-- 结果:name 为 NULL,记录不完整

NO 表示当前列不能为空, YES表示当前列可以为空。

如果此时插入数据时,id为空,会显示报错,提示不能写入null值,数据库帮我们做了一次校验。

sql 复制代码
insert into student values (NULL,'张三');

当我们的id修改后,可以正常插入。

3.3 添加非空约束

sql 复制代码
DROP TABLE IF EXISTS student;
CREATE TABLE student (
    id BIGINT,
    name VARCHAR(20) NOT NULL -- 非空约束
);

3.4 插入 NULL 报错

复制代码
INSERT INTO student VALUES (1, NULL);

报错信息:

sql 复制代码
ERROR 1048 (23000): Column 'name' cannot be null

3.5 正常插入

sql 复制代码
INSERT INTO student VALUES (1, '张三');

3.6 查看非空约束

sql 复制代码
DESC student;

查看规则:

  • Null 列显示 NO → 不允许 NULL
  • Null 列显示 YES → 允许 NULL

4. DEFAULT 默认约束(超详细)

4.1 作用

插入数据时没有给列赋值 ,自动使用默认值 。注意:手动明确写 NULL,依然是 NULL

4.2 无默认约束时

sql 复制代码
DROP TABLE student;
CREATE TABLE student (
    id BIGINT,
    name VARCHAR(20) NOT NULL,
    age INT
);

INSERT INTO student(id, name) VALUES (1, '张三');
-- age 为 NULL

4.3 添加默认约束

sql 复制代码
DROP TABLE student;
CREATE TABLE student (
    id BIGINT,
    name VARCHAR(20) NOT NULL,
    age INT DEFAULT 18 -- 默认 18 岁
);

4.4 不指定 age → 自动用默认值

sql 复制代码
INSERT INTO student(id, name) VALUES (1, '张三');
-- age = 18

4.5 手动赋 NULL → 依然是 NULL

sql 复制代码
INSERT INTO student(id, name, age) VALUES (2, '李四', NULL);
-- age = NULL

4.6 查看默认约束

sql 复制代码
DESC student;

Default 列会显示默认值。

5. UNIQUE 唯一约束(超详细)

5.1 作用

列的值必须唯一,不能重复。适用场景:身份证号、学号、工号、手机号。

5.2 无唯一约束 → 可重复

sql 复制代码
DROP TABLE student;
CREATE TABLE student (
    id BIGINT,
    name VARCHAR(20) NOT NULL,
    age INT DEFAULT 18,
    sno VARCHAR(10)
);

INSERT INTO student(id, name, sno) VALUES (1, '张三', '100001');
INSERT INTO student(id, name, sno) VALUES (2, '李四', '100001');
-- 重复学号,依然成功

5.3 添加唯一约束

sql 复制代码
DROP TABLE student;
CREATE TABLE student (
    id BIGINT,
    name VARCHAR(20) NOT NULL,
    age INT DEFAULT 18,
    sno VARCHAR(10) UNIQUE -- 唯一约束
);

5.4 插入重复值 → 报错

sql 复制代码
INSERT INTO student(id, name, sno) VALUES (1, '张三', '100001');
INSERT INTO student(id, name, sno) VALUES (2, '李四', '100001');

报错:

sql 复制代码
ERROR 1062 (23000): Duplicate entry '100001' for key 'student.sno'

5.5 查看唯一约束

sql 复制代码
DESC student;

Key 列显示 UNI → 唯一约束。

6. PRIMARY KEY 主键约束(最重点)

6.1 主键是什么

主键 = NOT NULL + UNIQUE

作用:唯一标识表中的每一条记录

6.2 主键三大规则

  1. 必须非空、唯一
  2. 一张表只能有一个主键
  3. 可以是单列多列(复合主键)

6.3 单列主键(最常用)

sql 复制代码
DROP TABLE IF EXISTS student;
CREATE TABLE student (
    id BIGINT NOT NULL UNIQUE,
    name VARCHAR(20) NOT NULL,
    age INT DEFAULT 18,
    sno VARCHAR(10) UNIQUE
);

DESC student;Key 列显示 PRI

6.4 主键 + 自增 AUTO_INCREMENT

开发标准写法:

sql 复制代码
DROP TABLE IF EXISTS student;
CREATE TABLE student (
    id BIGINT PRIMARY KEY AUTO_INCREMENT, -- 自增主键
    name VARCHAR(20) NOT NULL,
    age INT DEFAULT 18,
    sno VARCHAR(10) UNIQUE
);

6.5 自增主键插入

表示在当前表中上一条记录的基础上加1

sql 复制代码
desc student;
insert into student VALUES (NULL,'张三',18,2020060845);
insert into student VALUES (NULL,'李四',18,2020060846);
SELECT * from student;

让数据库帮我们维护主键的增长,不用程序员自己去计算了,在插入的时候先找到最大的值,然后在这个基础上加1,生成一个新的值,做为新一个数据行主键(id列)的值

当设置了自增主键是,发现了写入null时,也可以成功的插入数据,这里并不是说把这个NULL写入数据库了,而是说让数据库帮我们处理这个键的值。

当id值指定为100也是可以的,只要主键值不重复即可。

当再次插入时,找到ID最大的值是100+1,所以下一个值是101.

6.6 自增细节

  1. 插入失败,自增值会作废(不回滚)
  2. 手动指定大 id,下次自增从最大值开始
  3. 主键值可以不连续

6.7 主键冲突处理(高级用法)

6.7.1 存在则更新:ON DUPLICATE KEY UPDATE

sql 复制代码
INSERT INTO student(id,name,sno) 
VALUES (100,'赵六','100100')
ON DUPLICATE KEY UPDATE 
name='赵六', sno='100100';

6.7.2 存在则替换:REPLACE

sql 复制代码
REPLACE INTO student(id,name,sno) 
VALUES (101,'钱七','100101');

6.8 复合主键(多列联合)

sql 复制代码
DROP TABLE IF EXISTS student;
CREATE TABLE student (
    id BIGINT,
    name VARCHAR(20),
    PRIMARY KEY (id, name) -- 联合主键
);

规则:两列组合不能重复

一个表中不允许有两个主键,一个主键可包含多个列(符合主键)

此时KEY列中出现了两个PRI,表示当前表定义了复合主键,在唯一校验时,只有复合主键中所有的列都相同才被判定为相同。

编号相同但是名字不同,也可以插入。

7. FOREIGN KEY 外键约束(表关系核心)

7.1 外键作用

定义两个表之间的关联关系 ,保证引用完整性

表中某个列的值,必须是别一张表中的主键列,或是唯一约束列的值,也就是当前表中的值在另一张表中必须存在,且满足主键或唯一约束。

7.2 核心概念

  • 主表:被引用的表(如班级表 class)
  • 从表:使用外键的表(如学生表 student)
  • 外键列必须引用主表的主键或唯一键

7.3 步骤 1:创建主表(班级)

sql 复制代码
DROP TABLE IF EXISTS class;
CREATE TABLE class (
    id BIGINT PRIMARY KEY AUTO_INCREMENT,
    name VARCHAR(20) NOT NULL
);

INSERT INTO class(name) 
VALUES ('java01'),('java02'),('java03'),('C++01'),('C++02');

7.4 步骤 2:创建从表(学生 + 外键)

sql 复制代码
DROP TABLE IF EXISTS student;
CREATE TABLE student(
    id BIGINT PRIMARY KEY AUTO_INCREMENT,
    name VARCHAR(20) NOT NULL,
    age INT DEFAULT 18,
    class_id BIGINT,
    FOREIGN KEY (class_id) REFERENCES class(id) -- 外键
);

7.5 查看外键

sql 复制代码
DESC student;

Key 列显示 MUL → 外键。

7.6 外键约束规则(必背)

  1. 从表插入的 class_id 必须在主表存在,否则失败
  2. 外键可以为 NULL(表示未分配)
  3. 主表记录被从表引用时,不能删除
  4. 删表必须先删从表,再删主表

7.7 插入不存在的班级 → 报错

sql 复制代码
INSERT INTO student(name, class_id) VALUES ('王五', 100);

报错:

sql 复制代码
ERROR 1452 (23000): Cannot add or update a child row

7.8 删除被引用班级 → 报错

sql 复制代码
DELETE FROM class WHERE name='java01';

7.9 删除表顺序

sql 复制代码
DROP TABLE student; -- 先删从表
DROP TABLE class;   -- 再删主表

8. CHECK 约束(自定义数据规则)

8.1 说明

MySQL 8.0.16 版本开始真正支持,低版本会忽略。作用:自定义列的值范围、条件、规则。

8.2 学生表 CHECK 示例

sql 复制代码
DROP TABLE IF EXISTS student;
CREATE TABLE student(
    id BIGINT PRIMARY KEY AUTO_INCREMENT,
    name VARCHAR(20) NOT NULL,
    age INT DEFAULT 18,
    gender CHAR(1),
    CHECK (age >= 16),        -- 年龄 ≥16
    CHECK (gender IN ('男','女')) -- 性别只能男/女
);

8.3 违反 CHECK → 报错

sql 复制代码
-- 年龄太小
INSERT INTO student(name,age,gender) VALUES ('张三',15,'男');

-- 性别非法
INSERT INTO student(name,age,gender) VALUES ('张三',17,'1');

报错:

复制代码
ERROR 3819 (HY000): Check constraint violated

8.4 跨列比较 CHECK

sql 复制代码
CREATE TABLE t_check (
    c1 INT CHECK(c1 <> 0),
    c2 INT CHECK(c2 > 0),
    c3 INT,
    CHECK(c3 >= c2) -- 列之间比较
);

9. 全套约束高频面试题(背会稳过)

  1. 主键和唯一约束的区别?
    • 主键非空,唯一允许 NULL
    • 一张表只能一个主键,可多个唯一
  2. 自增主键不连续正常吗?
    • 正常,失败 / 回滚会占用自增值
  3. 外键有什么用?
    • 保证引用完整性,防止脏数据
  4. MySQL 什么时候 CHECK 生效?
    • 8.0.16 及以上
  5. 默认约束和 NULL 的关系?
    • 不赋值用默认,手动写 NULL 还是 NULL
  6. 复合主键是什么?
    • 多列联合作为主键,组合不可重复

10. 全文总结(极简记忆版)

  • NOT NULL:不许为空
  • DEFAULT:不赋值用默认
  • UNIQUE:不许重复
  • PRIMARY KEY:非空 + 唯一,表的唯一标识
  • FOREIGN KEY:表关联,保证引用合法
  • CHECK:自定义规则,8.0.16+ 生效

所有约束都是为了一件事:让数据库数据更干净、更可靠


总结

以上就是今天要讲的内容,本文简单记录了数据库学习内容,仅作为一份简单的笔记使用,大家根据注释理解,您的点赞关注收藏就是对小编最大的鼓励!

相关推荐
空太Jun2 小时前
Spring Security 自定义数据库认证(初尝试)
java·数据库·spring
sinat_255487812 小时前
泛型·学习笔记
java·jvm·数据库·windows·python
wregjru2 小时前
【MySQL】4. 数据约束详解
数据库·sql·oracle
枕书2 小时前
Oracle 19c RAC 双机高可用底座部署手册(PVE 架构版)
数据库·oracle·pve
一个有温度的技术博主2 小时前
Redis RDB持久化原理:一次快照背后的“分身术”与“读心术”
数据库·redis·缓存
小孤月2 小时前
关系型数据库:(eg:mysql)支持事务 ACID 特性
数据库
辰风沐阳2 小时前
MySQL 联合索引
数据库·mysql
Yvonne爱编码2 小时前
数据库---Day7 数据表设计
数据库·oracle