【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)

相关推荐
数据狐(Datafox)15 分钟前
京东商品列表API接口解析(附 JSON 样例)
数据库·爬虫·json
troy12811 小时前
向量数据库选型指南:Milvus / Qdrant / Chroma / pgvector
数据库·milvus
彧azz12 小时前
Redis 全面指南:从核心概念到高可用架构实战
数据库·redis·架构
DBA小马哥12 小时前
MongoDB 数据同步怎么做?oplog、Change Streams、同步工具 4 种方案一次讲清(附踩坑清单)
数据库·mongodb
香菜TTT14 小时前
Redis的哨兵机制
java·数据库·redis
风哥2号15 小时前
数据库教程FGMT13‑Oracle性能优化之数据仓库与分区表
数据库·oracle·性能优化
玉宇夕落15 小时前
Docker + Milvus,数据库永久存放记忆,让对话历史永不丢失
数据库·docker·llm
子非鱼a15 小时前
【WEB】[GXYCTF2019]BabySQli
sql
程序员清风15 小时前
FastAPI 入门:用 Python 快速开发现代后端服务
python·oracle·fastapi