MySQL单表约束超详细实战用法(主键 / 非空 / 唯一 / 默认)
作者:Westward-sun.
一、前言
在前几篇文章中,我们系统学习了 SQL 的 DDL、DML 和 DQL 核心用法,掌握了数据库、表、数据的增删改查。但在实际开发中,仅靠数据类型无法保证数据的完整性和有效性 —— 比如学号不能为空且不能重复、姓名必须填写、手机号不能重复等,这就需要约束(Constraint) 来实现。
本文将聚焦 SQL 中的单表约束,详细讲解主键、非空、唯一、默认约束的语法格式与实战用法,结合案例帮你彻底掌握,让数据更规范!
二、约束基础认知
2.1 约束概述
约束是在数据类型基础上,对数据表中列的值进行进一步的限定,目的是保证数据的完整性、唯一性、有效性,避免脏数据产生。
2.2 约束分类
表格
| 约束类型 | 作用域 | 具体约束 | 核心特点 |
|---|---|---|---|
| 单表约束 | 单张表内 | primary key(主键约束) | 非空 + 唯一,可结合 auto_increment 自增 |
| not null(非空约束) | 列值不能为 NULL | ||
| unique(唯一约束) | 列值必须唯一,可 NULL | ||
| default(默认约束) | 未赋值时使用默认值 | ||
| 多表约束 | 多张表间 | foreign key(外键约束) | 关联多表,保证数据一致性(后续单独讲解) |
三、核心约束实战(单表约束)
3.1 环境准备
-- 重置演示数据库(避免干扰) DROP DATABASE IF EXISTS day02; CREATE DATABASE day02; USE day02;
📌 执行效果:删除已存在的 day02 数据库,重新创建并切换到该数据库。
3.2 主键约束(primary key)★★★
3.2.1 主键约束核心特点
- 非空(NOT NULL):主键列的值不能为 NULL;
- 唯一(UNIQUE):主键列的值不能重复;
- 标识性:通常用于唯一标识表中的一条记录(如学号、员工 ID);
- 自增配合:一般结合
auto_increment(自增)使用,简化数据插入。
3.2.2 主键约束语法格式
表格
| 应用场景 | 语法格式 | 说明 |
|---|---|---|
| 建表时列级定义 | 列名 数据类型 PRIMARY KEY | 直接在列后添加,简洁常用 |
| 建表时表级定义 | PRIMARY KEY (列名 1, 列名 2...) | 支持复合主键(多列联合主键) |
| 建表后添加 | ALTER TABLE 表名 ADD PRIMARY KEY (列名); | 适用于已有表补充主键 |
| 删除主键 | ALTER TABLE 表名 DROP PRIMARY KEY; | 单表仅能有一个主键,删除无需指定列名 |
| 添加自增 | ALTER TABLE 表名 MODIFY 列名 数据类型 AUTO_INCREMENT; | 自增仅支持整型列,且需绑定主键 |
3.2.3 实操案例
场景 1:建表时添加主键约束
-- 创建学生表(sid:学号,主键;name:姓名;age:年龄)
DROP TABLE IF EXISTS student;
CREATE TABLE student(
sid INT PRIMARY KEY, -- 方式1:列级定义主键(推荐)
name VARCHAR(10),
age INT
-- PRIMARY KEY(sid) -- 方式2:表级定义主键(效果相同)
);📌 执行效果:删除已存在的 student 表,创建新表并将 sid 列设为主键。
-- 查看表结构(可看到sid的Key列显示PRI,代表主键) DESC student;
📌 执行效果:展示 student 表的字段结构,sid 字段的 Key 列显示「PRI」,标识为主键。
-- 插入测试数据 INSERT INTO student VALUES(1, '张三', 18); -- 正常插入
📌 执行效果:成功插入 1 条数据,sid=1、name = 张三、age=18。
INSERT INTO student VALUES(1, '张三', 18); -- 报错:主键重复(Duplicate entry)
📌 执行效果:执行报错,提示「Duplicate entry '1' for key'student.PRIMARY'」,主键值不能重复。
INSERT INTO student VALUES(NULL, '张三', 18); -- 报错:主键非空(Column 'sid' cannot be null)
📌 执行效果:执行报错,提示「Column'sid' cannot be null」,主键列不能为 NULL。
-- 查看数据 SELECT * FROM student;
📌 执行效果:仅展示 sid=1 的那条学生数据。
场景 2:建表后添加主键 + 自增
-- 先删除已有的主键约束 ALTER TABLE student DROP PRIMARY KEY;
📌 执行效果:成功删除 student 表的主键约束。
-- 重新添加主键约束,并增加自增功能 ALTER TABLE student ADD PRIMARY KEY(sid); ALTER TABLE student MODIFY sid INT AUTO_INCREMENT;
📌 执行效果:为 sid 列重新添加主键约束,并开启自增特性。
-- 再次插入数据(自增特性生效) INSERT INTO student VALUES(2, '李四', 20); -- 正常插入
📌 执行效果:成功插入 sid=2 的李四数据。
INSERT INTO student VALUES(2, '李四', 20); -- 报错:主键重复
📌 执行效果:执行报错,主键值 2 已存在,无法重复插入。
INSERT INTO student VALUES(NULL, '李四', 20); -- 正常插入(sid自动递增为3)
📌 执行效果:成功插入数据,sid 自动递增为 3。
INSERT INTO student VALUES(10, '王五', 20); -- 插入sid=10
📌 执行效果:成功插入 sid=10 的王五数据。
INSERT INTO student VALUES(NULL, '赵六', 66); -- sid自动递增为11
📌 执行效果:成功插入数据,sid 自动递增为 11(基于上一个最大值 10)。
-- 查看最终数据 SELECT * FROM student;
📌 执行效果:展示 sid 为 1、2、3、10、11 的 5 条学生数据。
场景 3:实际开发推荐写法(建表时直接加主键 + 自增)
-- 重建学生表(推荐写法)
DROP TABLE IF EXISTS student;
CREATE TABLE student(
sid INT PRIMARY KEY AUTO_INCREMENT, -- 主键+自增一步到位
name VARCHAR(10),
age INT
);📌 执行效果:删除旧表,创建新表,sid 列同时设置为主键并开启自增。
-- 插入数据(主键列传NULL即可自动递增) INSERT INTO student VALUES(NULL, '乔峰', 38); INSERT INTO student VALUES(NULL, '虚竹', 30);
📌 执行效果:成功插入 2 条数据,sid 自动递增为 1、2。
-- 查看数据 SELECT * FROM student;
📌 执行效果:展示 sid=1(乔峰)、sid=2(虚竹)的两条数据。
关键补充:DELETE vs TRUNCATE 对主键自增的影响
表格
| 操作 | 语法格式 | 对主键自增的影响 | 本质 |
|---|---|---|---|
| DELETE | DELETE FROM 表名; | 不重置自增 ID | 仅删除数据行 |
| TRUNCATE | TRUNCATE TABLE 表名; | 重置自增 ID 为 1 | 删表后重建同名表 |
-- DELETE:删除数据,不重置主键自增ID DELETE FROM student; INSERT INTO student VALUES(NULL, '段誉', 25); -- sid会从3开始(而非1)
📌 执行效果:删除所有数据后插入新数据,sid 从 3 开始(原自增最大值为 2)。
-- TRUNCATE:清空表并重置主键自增ID(相当于删表重建) TRUNCATE TABLE student; INSERT INTO student VALUES(NULL, '阿朱', 20); -- sid从1开始
📌 执行效果:清空表并重置自增 ID,插入新数据时 sid 从 1 开始。
3.3 非空 / 唯一 / 默认约束(not null/unique/default)
3.3.1 核心特点与语法格式
表格
| 约束类型 | 语法格式 | 核心规则 |
|---|---|---|
| not null | 建表时:列名 数据类型 NOT NULL 建表后添加:ALTER TABLE 表名 MODIFY 列名 类型 NOT NULL 建表后删除:ALTER TABLE 表名 MODIFY 列名 类型 NULL | 列值必须填写,不能为 NULL |
| unique | 建表时:列名 数据类型 UNIQUE 建表后添加:ALTER TABLE 表名 ADD UNIQUE (列名) 建表后删除:ALTER TABLE 表名 DROP INDEX 列名 | 列值必须唯一,可 NULL(多个 NULL 不冲突) |
| default | 建表时:列名 数据类型 DEFAULT ' 默认值' 建表后添加:ALTER TABLE 表名 MODIFY 列名 类型 DEFAULT ' 默认值' | 插入数据时未赋值,则使用默认值 |
3.3.2 实操案例
-- 创建员工表(整合非空、唯一、默认约束)
CREATE TABLE employee(
eid INT PRIMARY KEY AUTO_INCREMENT, -- 员工ID:主键+自增
name VARCHAR(10) NOT NULL, -- 姓名:非空约束
mobile VARCHAR(11) UNIQUE, -- 手机号:唯一约束
address VARCHAR(50) DEFAULT '北京' -- 住址:默认约束(默认值为北京)
);📌 执行效果:创建 employee 表,为不同字段分别设置主键 + 自增、非空、唯一、默认约束。
-- 查看表结构(可看到对应约束标识) DESC employee;
📌 执行效果:展示 employee 表结构,name 列 Null 显示「NO」(非空),mobile 列 Key 显示「UNI」(唯一),address 列 Default 显示「北京」。
-- 插入测试数据 -- 案例1:正常插入(所有字段赋值) INSERT INTO employee VALUES(NULL, '乔峰', '13800138000', '南院大王府');
📌 执行效果:成功插入 1 条员工数据,eid 自动递增为 1。
-- 案例2:姓名为空(报错:非空约束) -- INSERT INTO employee VALUES(NULL, NULL, '13800138001', '缥缈峰');
📌 执行效果:执行报错,提示「Column 'name' cannot be null」,非空约束生效。
-- 案例3:手机号重复(报错:唯一约束) -- INSERT INTO employee VALUES(NULL, '乔峰', '13800138000', '缥缈峰');
📌 执行效果:执行报错,提示「Duplicate entry '13800138000' for key 'employee.mobile'」,唯一约束生效。
-- 案例4:手机号不重复,正常插入 INSERT INTO employee VALUES(NULL, '阿紫', '13800138001', '星宿海');
📌 执行效果:成功插入 1 条数据,eid 自动递增为 2。
-- 案例5:未指定列名,值个数不足(报错) -- INSERT INTO employee VALUES(NULL, '段誉', '13800138002');
📌 执行效果:执行报错,提示「Column count doesn't match value count」,字段数量不匹配。
-- 案例6:指定列插入,住址使用默认值 INSERT INTO employee(eid, name, mobile) VALUES(NULL, '段誉', '13800138002');
📌 执行效果:成功插入数据,address 列自动填充默认值「北京」,eid 递增为 3。
-- 查看最终数据(段誉的address会显示默认值“北京”) SELECT * FROM employee;
📌 执行效果:展示 3 条员工数据,段誉的 address 字段值为「北京」(默认值)。
四、约束实操避坑指南
- 主键自增注意:自增列只能是整型,且一张表只能有一个自增列(通常和主键绑定);
- 唯一约束与 NULL:unique 约束允许多个 NULL 值(因为 NULL 不等于任何值);
- 默认约束生效条件:仅当插入数据时未给该列赋值,才会使用默认值;
约束修改 / 删除速查表
表格
| 操作 | 语法示例 |
|---|---|
| 删除主键 | ALTER TABLE student DROP PRIMARY KEY; |
| 添加非空约束 | ALTER TABLE employee MODIFY name VARCHAR(10) NOT NULL; |
| 删除非空约束 | ALTER TABLE employee MODIFY name VARCHAR(10) NULL; |
| 添加唯一约束 | ALTER TABLE employee ADD UNIQUE(mobile); |
| 删除唯一约束 | ALTER TABLE employee DROP INDEX mobile; |
| 添加默认约束 | ALTER TABLE employee MODIFY address VARCHAR (50) DEFAULT ' 上海 '; |
五、总结
核心要点回顾
- 约束是对列值的额外限定,单表约束核心包括主键、非空、唯一、默认,均有明确的语法格式;
- 主键约束是最核心的单表约束,具备非空 + 唯一特性,结合
auto_increment可自动递增,建表时「列名 类型 PRIMARY KEY」是最常用写法; not null强制列值非空,unique强制列值唯一,default为列设置默认值,三者均支持建表时定义、建表后修改;- DELETE 删除数据不重置主键自增,TRUNCATE 会重置(删表重建)。
下一步学习预告
本文掌握了单表约束的语法格式与核心用法,后续将讲解多表约束(外键约束) 和多表查询,这是 SQL 进阶的关键,关注我,持续解锁 SQL 实战技能!
拓展练习
- 创建一张商品表(goods),按格式定义字段:
- 商品 ID(gid):INT 类型,主键 + 自增;
- 商品名(gname):VARCHAR (20),非空约束;
- 商品编号(gcode):VARCHAR (32),唯一约束;
- 库存(stock):INT,默认约束(默认值 0);
- 分类 ID(cid):VARCHAR (32);
- 向商品表插入 5 条测试数据,验证各约束是否生效;
- 使用 ALTER 语句给商品表添加 “单价(price)” 字段,设置为 DECIMAL (10,2) 类型,默认值 0.00。
关键点回顾
- 主键约束核心是「非空 + 唯一」,结合自增可简化主键赋值,是单表最核心的约束;
- 非空约束强制字段必填,唯一约束保证字段值不重复(允许 NULL),默认约束在未赋值时填充默认值;
- 约束支持建表时定义、建表后修改 / 删除,不同约束的操作语法需区分记忆。
到此这篇关于MySQL单表约束超详细实战用法(主键 / 非空 / 唯一 / 默认)的文章就介绍到这了,更多相关mysql单表约束内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
