【MySQL】4. 数据约束详解

目录

一、约束概述

二、空属性

[三、DEFAULT 默认值](#三、DEFAULT 默认值)

[四、列描述 COMMENT](#四、列描述 COMMENT)

[五、ZEROFILL 零填充](#五、ZEROFILL 零填充)

六、主键

[七、AUTO_INCREMENT 自动增长](#七、AUTO_INCREMENT 自动增长)

八、唯一键(UNIQUE)

[九、外键(FOREIGN KEY)](#九、外键(FOREIGN KEY))


一、约束概述

约束的作用:用约束让未来插入数据库中的数据符合预期,即通过倒逼程序员插入更规范的数据来保证数据质量。

二、空属性

  • NULL:允许数据为空

  • NOT NULL:不允许数据为空

    -- 创建表:name 列不允许为空
    CREATE TABLE t13 (name VARCHAR(10) NOT NULL, id INT);

    -- 以下插入都会报错
    INSERT INTO t13 (name, id) VALUES (NULL, 1); -- 错误:Column 'name' cannot be null
    INSERT INTO t13 (id) VALUES (1); -- 错误:Field 'name' doesn't have a default value

三、DEFAULT 默认值

当插入时不显式指定值时,就会插入默认值。

复制代码
CREATE TABLE t15 (age TINYINT NOT NULL DEFAULT 18, name VARCHAR(10));

此时 DEFAULT 列会显示为 18

复制代码
-- 不指定 age,使用默认值 18
INSERT INTO t15 (name) VALUES ('1');

-- 显式插入 NULL 会报错(age 不允许为 NULL)
INSERT INTO t15 (age, name) VALUES (NULL, '1');
-- 错误:Column 'age' cannot be null

原因 :每一列都有一个默认值,当不指定插入时默认使用 DEFAULT 值。但 VALUES (NULL, '1') 是显式插入了 NULL,而 age 不允许为 NULL,因此报错。

结论:空属性和默认值是互补的,并不冲突。

四、列描述 COMMENT

相当于注释,作为一个软约束,让使用者更易懂。

复制代码
CREATE TABLE t14 (
    id INT COMMENT '用户ID',
    name VARCHAR(20) COMMENT '用户名'
);

五、ZEROFILL 零填充

复制代码
CREATE TABLE t16 (a INT, b INT ZEROFILL);

使用 DESC 查看,b 显示为 int(10)

插入数据 (1, 1) 后,b 会显示为 10 位,前面补零:

说明

  • 老版本中括号里的数表示最少显示几位,不够补零(如 ALTER TABLE t16 MODIFY b INT(4) 表示最少显示 4 位)

  • 新版本中此功能已废弃,因为误导性极强

六、主键

  • 特点:不能重复,一张表只能有一个主键

  • 自动变为 NOT NULL

    CREATE TABLE t17 (id INT PRIMARY KEY, course_id INT, score INT);

由于学生 id 是唯一的,因此将其设置为主键,不能插入两个 id 为 1 的记录。

主键操作

复制代码
-- 删除主键(主键只有一个,不用指定)
ALTER TABLE t17 DROP PRIMARY KEY;

-- 添加复合主键(类似于 pair)
ALTER TABLE t17 ADD PRIMARY KEY (id, course_id);

复合主键的效果:

  • 学号为 1 的人可以学编号 1、2 的课程

  • 学号为 2 的人也可以学编号 1、2 的课程

  • 但学号为 1 的人不能学习两次编号为 1 的课程

七、AUTO_INCREMENT 自动增长

复制代码
CREATE TABLE t18 (id INT PRIMARY KEY AUTO_INCREMENT, name CHAR(20));

插入数据:

复制代码
INSERT INTO t18 (name) VALUES ('a');
INSERT INTO t18 (name) VALUES ('b');

id 会自动补全,从 1 开始。

指定起始值

复制代码
INSERT INTO t18 (id, name) VALUES (100, 'c');

后续插入的 id 会从 101 开始。

注意事项

  • 自动增长的列必须设为主键或 UNIQUE

查看自动增长值

复制代码
SHOW CREATE TABLE t18 \G;

查询时,AUTO_INCREMENT 会自动补为对应的数值。

创建时指定起始值

复制代码
CREATE TABLE t19 (id INT PRIMARY KEY AUTO_INCREMENT, name CHAR(20)) AUTO_INCREMENT = 200;

八、唯一键(UNIQUE)

复制代码
CREATE TABLE t20 (id INT PRIMARY KEY, name CHAR(20) UNIQUE);

创建学生表时,名字不可重复,但 id 已经设置为主键了。

唯一键的特点

  • 指定数据不能重复

  • 数据可以为 NULL,且 NULL 可重复

唯一键与主键的区别

  • 可以加上 NOT NULL,此时表面上看功能确实和主键一样,但逻辑上不一样

  • 主键:在很多唯一值中选择的最具代表性的作为身份象征

  • 唯一键:仅仅是禁止重复

唯一键和主键是互补的,可以用唯一键报错来约束程序员的行为。

九、外键(FOREIGN KEY)

场景:两张表------班级表(1班、2班)和学生表。向学生表录入时,班级那一栏不能出现不存在的班级号(如 3 班)。

因此需要外界的约束,称作外键

  • 主表:班级表

  • 从表:学生表

    -- 创建主表(班级表)
    CREATE TABLE t21 (class INT PRIMARY KEY, name CHAR(20));

    -- 创建从表(学生表),class_id 引用 t21 的 class 列
    CREATE TABLE t22 (
    id INT PRIMARY KEY,
    name CHAR(20),
    class_id INT,
    FOREIGN KEY (class_id) REFERENCES t21(class)
    );

外键的说明

  • FOREIGN KEY 指明自己表中的哪个字段

  • REFERENCES 指明与外部表的哪个字段关联

  • 作为外键的对象需要指定为主键UNIQUE,总之不能重复

删除约束:如果已经有学生关联上了某个班级,那么删除该班级之前,需要先删除关联的学生。

查看表结构

复制代码
SHOW CREATE TABLE t22 \G;

会显示:

  • PRIMARY KEY (id)

  • KEY class_id (class_id)

  • CONSTRAINT t22_ibfk_1 FOREIGN KEY (class_id) REFERENCES t21 (class)

相关推荐
枕书2 小时前
Oracle 19c RAC 双机高可用底座部署手册(PVE 架构版)
数据库·oracle·pve
l1t2 小时前
修改OraDB-DUMP-Viewer-3.1.1的windows dll 版本test_export示例为Linux
linux·人工智能·windows·oracle
一个有温度的技术博主2 小时前
Redis RDB持久化原理:一次快照背后的“分身术”与“读心术”
数据库·redis·缓存
小孤月2 小时前
关系型数据库:(eg:mysql)支持事务 ACID 特性
数据库
辰风沐阳2 小时前
MySQL 联合索引
数据库·mysql
Yvonne爱编码2 小时前
数据库---Day7 数据表设计
数据库·oracle
知识分享小能手2 小时前
MongoDB入门学习教程,从入门到精通,MongoDB的分片简介(14)
数据库·学习·mongodb
小则又沐风a2 小时前
类和对象----最终篇
java·前端·数据库
liliangcsdn2 小时前
LLM如何以ReAct Agent方式统计分析去重后数据
数据库·人工智能·全文检索