当前位置: 首页 > news >正文

MySQL 约束知识体系:八大约束类型详细讲解

MySQL系列


文章目录

  • MySQL系列
  • 前言
  • 一、NULL(空属约束)
  • 二、default(默认值约束)
  • 三、comment(注释约束)
  • 四、zerofill(零填充约束)
  • 五、primary key(主键约束)
  • 六、auto_increment(自增长约束)
  • 七、unique key(唯一约束)
  • 八、froeign key(外键)
  • 总结


前言

本篇文章将为你详细介绍 MySQL 中常见的几种约束,内容较为丰富,建议耐心阅读。

通过上篇文章的讲解我们已经了解到,MySQL 中的数据类型本身具备一定约束能力,但这种约束极为单一,无法满足实际业务场景的复杂需求。因此,本章将重点聚焦于 MySQL 的约束机制——约束是保障表数据正确性与合法性的关键技术手段

数据类型是约束字段的基础,但仅靠数据类型无法实现全面的约束。为了从业务逻辑层面确保数据合法、符合业务规则,必须引入额外的约束机制对数据进行多重校验。
本章主要围绕以下核心约束展开介绍:null/not null(空值约束)、default(默认值约束)、comment(注释约束)、zerofill(零填充约束)、primary key(主键约束)、auto_increment(自增约束)、unique key(唯一约束)


一、NULL(空属约束)

null(允许空值)和 not null(禁止空值)是基础且常用的约束类型

  • null:表示字段允许存储空值,这是数据库字段的默认设置。
  • not null:强制字段必须存储具体值,不允许为空。

在 MySQL 中,NULL‘’(空串) 是两个截然不同的概念,需严格区分:NULL 代表“未知”,表示该字段未被定义或未录入数据,逻辑上属于“无值”;而 ‘’(空串) 是长度为 0 的有效字符串,代表“存在但内容为空”,属于“有值”。

在大学生活中,我们经常会被要求填写一些表格,这些表格中一定存在一些必须要填的,这种情况下我们就可以将该字段设置为not null(不可为空),接下来我就以下面为例创建表格:

创建一个班级表,包含班级名和班级所在的教室。

此时就面临着,如果班级没有名字,你不知道你在哪个班级;如果教室名字可以为空,就不知道在哪上课。

 create table myclass(student_name varchar(8) not null,class_name varchar(20) not null,class_room varchar(10) not null,other varchar(20));

在这里插入图片描述
可以看到,当我向表中插入数据忽略class_name字段时,MySQL会阻止报错。表中Null列表示,表中对应列是否允许为空。

在这里插入图片描述
我们未对其设置的列,默认为允许为空。

二、default(默认值约束)

默认值:为字段预先设定的高频重复值,当用户未输入数据时,系统自动填充该预设值。

 create table t10(name varchar(20) not null,age tinyint unsigned default 0,gender char(2) default '男');

在这里插入图片描述
可以看到,当对于某列的默认值设置后,插入数据忽略该字段,系统就会使用默认值来填充。表格中Default列,表示对应列设置的默认值,若没有设置默认为null
当把一个属性设置为非空约束,并且同时设置默认值约束。

在 MySQL 中,非空约束(NOT NULL)默认值约束(DEFAULT) 是两个独立但可协同工作的机制,其核心工作逻辑如下:

  • 优先级顺序

    1. 用户显式赋值:优先使用用户提供的值。
    2. 默认值:用户未提供值时,使用 DEFAULT 指定的值。
    3. 报错:若既无用户输入,又无默认值,且字段被标记为 NOT NULL,则抛出错误。
  • 非空约束确保字段始终有值,而 默认值约束 提供了“无输入时的备选值”。

三、comment(注释约束)

comment没有实际含义,专门用来描述字段,会根据表创建语句保存,是用来给程序员或DBA来进行了解。

create table t11(
name varchar(20) not null comment '名字',
age tinyint unsigned default 0 comment '年龄',
gender char(2) default '男' comment '性别');

在这里插入图片描述在这里插入图片描述

这里你知道如何设置、如何查看就可以了。

四、zerofill(零填充约束)

在上篇介绍数据类型时,我并没有介绍int类型,在使用int类型时你有可能会看到int(10),将int类型设置为unsigned时就会变为int(11)(这个不一定,视环境而定),而这就是int类型最大显示的位数(10位可以表示42亿多的值,刚好足够表示int类型数据),当对int类型字段设置位zerofill时,数据就会以最大位数显示不足就会在前面补0

在这里插入图片描述在这里插入图片描述

五、primary key(主键约束)

  • 主键primary key: 用来唯一的约束该字段里面的数据,不能重复,不能为空,一张表中最多只能有一个。
  • 主键通常所在的列通常是整数类型
create table test_key(
id int unsigned primary key ,
name varchar(20) not null);

在这里插入图片描述
将某列设置为主键后,该列将不再允许插入列中存在的数据,并且作为主键的列,默认设为非空(设置非空约束)。
对某行设置为主键,有以下几种方式:

  • 建建表时直接设置为primary key
  • 建表完成后,再设置主键alter table db_name add primary key(列名)

要将所选字段修改为主键,那么该字段就必须满足主键的要求(删除重复行),否则就无法修改为主键。

删除主键: alter table db_name drop primary key;

在这里插入图片描述

复合主键

在创建 MySQL 表时,主键可以在所有字段定义之后通过 PRIMARY KEY(主键字段列表) 语法声明。这种方式既支持单一字段作为主键(如 PRIMARY KEY(id)),也支持将多个字段组合为复合主键(如 PRIMARY KEY(name, age),即多个字段共同唯一标识一条记录)。需要明确的是:一张表中最多只能定义一个主键,但这并不限制主键仅对应单个字段——复合主键通过将多个属性合并为一个逻辑上的“联合标识”,同样满足主键的唯一性约束。

create table t13(
id int unsigned,
name char(10),
primary key (id,name));

在这里插入图片描述
可以看到,只有当这个主键“组合”重复插入时,MySQL才会拦截操作。

六、auto_increment(自增长约束)

当对应的字段,不给值,会自动的被系统触发,系统会从当前字段中已经有的最大值+1操作,得到一个新的不同的值。通常和主键搭配使用,作为逻辑主键。

自增长的特点:

  • 任何一个字段要做自增长,前提是本身是一个索引(key一栏有值)
  • 自增长字段必须是整数
  • 一张表最多只能有一个自增长
create table t14(
id int primary key auto_increment,
name char(10));

在这里插入图片描述
当将某个字段设置为自增长时,在插入数据时即使忽略该字段,MySQL也会在该列当前最大值的基础上+1,作为新的数据插入。
在这里插入图片描述
该字段记录的就是,下次默认插入的数据。
在建表时,可以直接设置自增长开始值:

CREATE TABLE t14 (id INT PRIMARY KEY AUTO_INCREMENT,name CHAR(10)
) AUTO_INCREMENT = 100;  

在这里插入图片描述

七、unique key(唯一约束)

在实际生活中,手机号、身份证号等许多属性都具有唯一性,对应到数据库表中,往往需要多个字段满足“数据不重复”的约束。但由于一张表只能有一个主键,唯一键(UNIQUE) 成为解决多字段唯一性需求的关键机制。

唯一键的核心作用与主键类似——确保字段值不重复,但二者存在关键差异:唯一键允许字段值为 NULL,且允许多条记录的该字段为 NULL(因为 NULL 不参与唯一性比较);而主键则严格禁止 NULL 值,且一张表只能定义一个主键。

create table t16(
id int primary key,
name char(10),
phone_number varchar(10) unique);

在这里插入图片描述
可以看到唯一键不允许插入重复数据,但是允许插入NULL值(可以配合非空约束,使得唯一键不能为空),此外唯一键也可以配合自增长使用。

在数据库设计中,有一个重要原则需要注意:建议将主键设计为与当前业务无关的字段(例如纯数字自增 ID)。这样做的核心优势是,当业务逻辑发生调整(如规则变更、需求迭代)时,主键不会因业务属性变化而被迫修改,从而减少对数据结构和关联逻辑的影响。而对于那些在业务层面必须保证唯一性的字段(例如员工工号、用户手机号等),更适合通过 唯一键(UNIQUE)约束 来实现——既满足“业务上不能重复”的核心需求,又避免将业务属性与主键强绑定。

八、froeign key(外键)

在关系型数据库中,外键(FOREIGN KEY) 是定义 主表从表 关联关系的核心机制。其核心规则如下:外键约束必须定义在从表上,用于关联主表的特定字段;而对应的主表必须为该字段设置主键约束PRIMARY KEY)或唯一约束(UNIQUE),以保证被引用值的唯一性。当外键约束生效后,从表外键列的取值需严格遵循规则:要么是主表对应主键/唯一键列中已存在的值,要么为 NULL(前提是外键列未被限制为非空)。这一机制确保了主从表之间的数据一致性。

foreign key (字段名) references 主表()

在这里插入图片描述

假设班级只有两个,学生数量增加只需添加一个class_id字段即可,通过这种方式可以大大减少空间消耗。

  • 主键表
create table myclass (
id int primary key,
name varchar(30) not null comment'班级名'
);
  • 从键表
create table stu (
id int primary key,
name varchar(30) not null comment '学生名',
class_id int,
foreign key (class_id) references myclass(id)
);

在这里插入图片描述
在这里插入图片描述
可以看到当插入一个班级号为30的学生,因为没有这个班级,所以插入不成功
上图打算展示的是,stu表的内容,结果sql语句输错了,你知道就好
在这里插入图片描述
当从表键不知道要存储何值时,允许存入空。

外键特点

  • 对于设置了外键约束的字段来说,它关联的外键值,必须是在关联表中是存在的/为null
  • 设置外键约束,能很好的保证某一些特别值(需要保证存在的值)不出现不存在的情况
  • 设置外键还能让两个表有一定的关联性(主从表的关联关系)
  • 其中关联的外键字段必须是关联表的主键/唯一键列

设置外键名
在未设置外键名时,系统使用默认名
在这里插入图片描述

CREATE TABLE employees (emp_id INT PRIMARY KEY,emp_name VARCHAR(50),dept_id INT,// 自定义外键名:fk_employees_departmentsCONSTRAINT fk_employees_departments  FOREIGN KEY (dept_id) REFERENCES departments(dept_id)
);

总结

数据表必须合理设置各类约束。借助约束机制,能够强制未来插入数据库的数据严格符合预设规则与预期标准。从本质上讲,约束是通过技术规则倒逼开发者输入正确数据;而站在 MySQL 的角度,所有成功写入数据库的数据,都必然满足了预设的全部约束条件,归根结底,约束的核心价值在于确保数据的正确性与可预期性,为数据质量提供坚实保障。
本篇内容就到这里了,若在文中发现错误,可以私信博主,希望本文能对你有帮助,感谢支持。

http://www.lryc.cn/news/609677.html

相关文章:

  • Java项目:基于SSM框架实现的电子病历管理系统【ssm+B/S架构+源码+数据库+毕业论文+远程部署】
  • Android 15.0 启动app时设置密码锁
  • 安卓264和265编码器回调编码数据写入文件的方法
  • Android进程基础:Zygote
  • 2025-08-04-零成本搭建 AI 应用!Hugging Face 免费 CPU 资源实战指南
  • Android Telephony 框架与横向支撑层
  • 如何选择一个容易被搜索引擎发现的域名?
  • 计算机网络:详解网络地址的计算步骤
  • 2.4- WPF中非 UI 线程上安全地更新 UI 控件方法
  • JVM学习日记(十六)Day16——性能监控与调优(三)
  • SpringBoot格式化数据库表格字段时间戳
  • vcpkg在vs/vscode下用法
  • 子词分词器(Byte Pair Encoding + WordPiece)
  • 深入解析SmolVLA:VLM与动作专家间的注意力机制交互
  • 深入剖析通用目标跟踪:一项综述
  • [自动化Adapt] 父子事件| 冗余过滤 | SQLite | SQLAlchemy | 会话工厂 | Alembic
  • RLCraft开服踩坑记录
  • 补:《每日AI-人工智能-编程日报》--2025年7月30日
  • AWS 可靠性工程深度实践: 从 Well-Architected 到“零失误”VPC 落地
  • 使用AWS for PHP SDK实现Minio文件上传
  • 音视频学习笔记
  • vue3入门-概览讲解
  • 使用 IntelliJ IDEA + Spring JdbcTemplate 操作 MySQL 指南
  • 基于Java的AI/机器学习库(Smile、Weka、DeepLearning4J)的实用
  • Go语言流式输出技术实现-服务器推送事件(Server-Sent Events, SSE)
  • 【银河麒麟服务器系统】自定义ISO镜像更新内核版本
  • Linux 文件与目录属性管理总结
  • Android 区块链 + CleanArchitecture + MVI 架构实践
  • IDA9.1使用技巧(安装、中文字符串显示、IDA MCP服务器详细部署和MCP API函数修改开发经验)
  • Android工程命令行打包并自动生成签名Apk