mysql 约束

学习 MySQL 的约束 (Constraint) ,最直观的理解就是:它是数据库的"安检员"或"规则守护者"

如果没有约束,你的 emp 表可能会出现:两个员工工号一样、年龄是负数、或者入职日期是 3000 年。约束的存在,就是为了保证数据的完整性、一致性和有效性


1. 什么是约束?

约束是作用于表中字段上的规则。

  • 目的:限制存储在表中的数据,确保数据的正确。

  • 时机 :在创建表(CREATE TABLE)或修改表(ALTER TABLE)时添加。


2. 常见的六种约束(由浅入深)

我们可以结合你的 emp 表,看看这些规则是如何保护数据的:

约束关键字 中文名称 描述 场景举例 (基于你的 emp 表)
NOT NULL 非空约束 限制该字段的数据不能为 NULL 姓名 (name) 必须填写,不能是空的。
UNIQUE 唯一约束 保证该字段的所有数据都是唯一的 身份证号 (idcard) 不能重复。
PRIMARY KEY 主键约束 主键是一行数据的唯一标识,非空且唯一 你的 id 字段,它是每个人的"身份证"。
DEFAULT 默认约束 保存数据时,若未指定值,则使用默认值 workaddress 如果不填,默认是"上海"。
CHECK 检查约束 保证字段值满足某一个条件 (8.0版本支持) age 必须在 0 到 120 岁之间。
FOREIGN KEY 外键约束 让两张表的数据建立连接,保证数据一致性 员工所属的"部门ID"必须在部门表里存在。

逐个精讲(由浅入深 + 例子)

🔴 1. 非空约束 NOT NULL

定义

规定:这个字段必须填值,不能为空(NULL)

用来干嘛

防止关键信息空着:姓名、手机号、密码 不能为空

复制代码
CREATE TABLE student(
    id INT,
    name VARCHAR(20) NOT NULL  -- 姓名不能为空
);

❌ 错误:插数据不写 name

复制代码
INSERT INTO student(id) VALUES(1); -- 直接报错

✅ 正确:必须给 name 赋值

🟡 2. 唯一约束 UNIQUE

定义

规定:这个字段的值,整张表里不能重复

用来干嘛

手机号、身份证、邮箱 ------ 每个人只能有一个

复制代码
CREATE TABLE student(
    id INT,
    phone VARCHAR(11) UNIQUE  -- 手机号不能重复
);

🟢 3. 默认值约束 DEFAULT

定义

不填这个字段时,自动给一个默认值

用来干嘛

性别默认未知、地址默认保密、创建时间默认当前时间

复制代码
CREATE TABLE student(
    id INT,
    name VARCHAR(20),
    gender VARCHAR(10) DEFAULT '未知'
);

插入不写性别:

sql

复制代码
INSERT INTO student(id,name) VALUES(1,'Tom');

自动变成:性别 = 未知

🔵 4. 主键约束 PRIMARY KEY(最重要!)

定义

  1. 一张表只能有一个主键
  2. 主键:非空 + 唯一 双重保证
  3. 用来唯一标识每一行数据

用来干嘛

精准找到某一条数据(学号、员工 ID、订单 ID)

例子

sql

复制代码
CREATE TABLE student(
    id INT PRIMARY KEY,  -- 主键:不空、不重复
    name VARCHAR(20) NOT NULL
);
  • id 不能空
  • id 不能重复
  • 通过 id 就能精准定位一个学生

🟣 5. 自增约束 AUTO_INCREMENT(配合主键)

定义

主键数字不用自己填,数据库自动往上加 1、2、3...

用来干嘛

新增数据不用管 ID,系统自动排号

例子

sql

复制代码
CREATE TABLE student(
    id INT PRIMARY KEY AUTO_INCREMENT,
    name VARCHAR(20) NOT NULL
);

插入数据:

sql

复制代码
INSERT INTO student(name) VALUES('Tom'),('Rose');

id 自动变成:1、2、3......

🟠 6. 检查约束 CHECK(限制范围)

定义

规定字段值必须在某个范围里

用来干嘛

成绩只能 0~100年龄不能负数

例子

sql

复制代码
CREATE TABLE score(
    id INT PRIMARY KEY AUTO_INCREMENT,
    math INT CHECK(math >=0 AND math <=100)
);

❌ 插数学成绩 105 → 直接报错

⚫ 7. 外键约束 FOREIGN KEY(进阶)

定义

两张表绑在一起,子表数据必须依赖主表

外键用来让两张表的数据之间建立连接,从而保证数据的一致性和完整性。

用来干嘛

成绩表的学生 ID,必须在学生表里真实存在防止出现 "不存在学生的成绩"

简单例子

主表:student(学生)子表:score(成绩)成绩表里 student_id 必须来自 student 的 id

复制代码
CREATE TABLE student(
    id INT PRIMARY KEY AUTO_INCREMENT,   -- 主键 + 自增
    name VARCHAR(20) NOT NULL,           -- 非空
    phone VARCHAR(11) UNIQUE,            -- 唯一
    gender VARCHAR(10) DEFAULT '未知',   -- 默认值
    age INT CHECK(age>0)                 -- 检查约束
);
约束 作用 口诀
NOT NULL 不能为空 必填项
UNIQUE 不能重复 独一份
DEFAULT 不填给默认 自动补
PRIMARY KEY 非空 + 唯一,定位数据 身份证号
AUTO_INCREMENT 数字自动涨 自动排号
CHECK 限制范围 不乱填
FOREIGN KEY 两张表关联 绑在一起

3. 实战演练:创建一个带约束的表

假设我们要重新创建一张像你截图中那样的 emp 表,我们会这样写:

SQL

复制代码
CREATE TABLE emp (
    id INT PRIMARY KEY AUTO_INCREMENT,          -- 主键,且自动增长
    workno VARCHAR(10) NOT NULL UNIQUE,         -- 工号:不能为空且唯一
    name VARCHAR(10) NOT NULL,                  -- 姓名:不能为空
    gender CHAR(1) DEFAULT '男',                -- 性别:默认"男"
    age TINYINT CHECK (age > 0 AND age < 120),  -- 年龄:必须在0-120之间
    idcard CHAR(18) UNIQUE,                     -- 身份证:唯一
    entrydate DATE NOT NULL                     -- 入职日期:不能为空
);
相关推荐
人道领域4 分钟前
【黑马点评日记】Redis分布式锁终极方案:Redisson全面解析(含源码解析)
java·数据库·redis·分布式·缓存
m0_741173335 分钟前
MySQL导入大SQL文件报错怎么办_拆分文件与优化系统参数
jvm·数据库·python
BullSmall7 分钟前
Redis AOF 文件损坏报错:完整修复方案
数据库·redis·缓存
Amnesia0_08 分钟前
磁盘文件系统
linux·运维·数据库
数据库知识分享者小北8 分钟前
智能运维+多模型服务能力,阿里云 RDS AI 助手旗舰版正式上线!
运维·数据库·阿里云·阿里巴巴·rds·智能运维
m0_5887584814 分钟前
如何解决Oracle启动ORA-00119错误_网络服务名与listener相关性
jvm·数据库·python
PSLoverS15 分钟前
MySQL如何利用防火墙限制MySQL端口_使用iptables或安全组防御
jvm·数据库·python
qq_4142565715 分钟前
Go语言如何用strings.Builder_Go语言strings.Builder教程【总结】
jvm·数据库·python
阿坤带你走近大数据18 分钟前
Oracle-表空间temp
数据库·oracle
Navicat中国18 分钟前
数据库事务隔离级别的实践指南
数据库·navicat