数据库必学的五大核心约束

前言

在之前我整理了一篇关于数据库在对表的一些常用操作:增删改查,大家有兴趣可以去看看,这篇文章来梳理一下SQL约束,这是数据库表设计的根基

一、什么是约束?为什么要用?

约束=给数据表加的"规则"

为了确保表中的数据的完整性(准确性、正确性),为表添加一些限制。是数据库中表设计的一个最基本规则。使用约束可以使数据更加准确,从而减少冗余数据(脏数据)

主要分为五大类:

二、主键约束 PRIMARY KEY

1.定义

每一个数据表都必须有一个唯一主键作为数据的唯一标识,设置主键的列不允许为空,主键习惯 id 表示,可以在创建数据时直接指定,也可以通过修改表结构直接添加,设置为主键的列在添加数据时不能重复,即唯一性。

2.示例

当插入两条相同id的数据时,会报错:

sql 复制代码
INSERT INTO student(id,name,age,email)
VALUES (1,'张三',18,'11111111@qq.com');

INSERT INTO student(id,name,age,email)
VALUES (1,'李四',20,'12222222@qq.com');

3.主键自增

手动维护主键太麻烦了,使用MySQL时,可以使用提供的自增功能,该功能时每次找到数据表中最大的ID值+1

(1)特点

  • 只有整型数据列可以设置为自增
  • 必须是主键
  • 插入时不用给值
  • 默认从 1 开始,每次 +1
  • 用过的数字不会复用(删了也不回退)

(2)示例

三、唯一约束 UNIQUE

1.定义

唯一约束(可以为空+可以多个)用来保护表中某列数据不允许重复,与主键约束(非空+唯一)类似,但级别没有主键高。一份表中唯一约束可以创建多个,并且唯一约束的列允许为空。

注意varchar长度为255时,无法设置唯一约束。

唯一约束一般用于约束手机号、账户、邮箱等信息。

(2)示例

给email加上UNIQUE后,运行会报错

sql 复制代码
INSERT INTO student(name,age,email)
VALUES ('张三',18,'111111@qq.com');

INSERT INTO student(name,age,email)
VALUES ('李四',20,'111111@qq.com');

四、非空约束 NOT NULL

1.作用

强制这一列必须填值,不可为NULL,但是可以为空字符串'',一张表可以有多个非空字段

比如:id、姓名、手机号、用户名,都必须加 NOT NULL。

2.示例

在建表的时候可以添加非空约束:

sql 复制代码
-- 创建学生表,给姓名、手机号加非空约束
CREATE TABLE student (
    id INT PRIMARY KEY AUTO_INCREMENT,
    name VARCHAR(20) NOT NULL,   -- 姓名:非空
    phone VARCHAR(11) NOT NULL,  -- 手机号:非空
    age INT                      -- 年龄:允许为空
);

正确插入数据:

sql 复制代码
-- 给所有非空字段正常赋值,执行成功
INSERT INTO student(name, phone, age) 
VALUES ('张三','13800138000',18);

修改表,给指定字段添加/删除非空约束:

sql 复制代码
-- 给已有字段添加非空约束
ALTER TABLE student MODIFY COLUMN age INT NOT NULL;

-- 移除非空约束(变回允许为空)
ALTER TABLE student MODIFY COLUMN age INT;

五、默认约束 DEFAULT

1.定义

给字段设置默认值 ,插入数据时不主动给该字段赋值,自动使用预设的默认值。

2.适用场景

  • 用户状态默认:正常 (1)
  • 逻辑删除默认:未删除 (0)
  • 创建时间默认:当前时间

3.示例

建表语句:

sql 复制代码
CREATE TABLE user (
    id INT PRIMARY KEY AUTO_INCREMENT,
    username VARCHAR(20) NOT NULL,
    gender VARCHAR(10) DEFAULT '女',  -- 性别默认女
    status TINYINT DEFAULT 1,        -- 状态1:正常
    is_delete TINYINT DEFAULT 0      -- 逻辑删除0:未删除
);

不指定默认字段,自动填充默认值:

sql 复制代码
-- 只插用户名,gender、status、is_delete 都不赋值
INSERT INTO user(username) VALUES ('李四');

主动赋值,覆盖默认值:

sql 复制代码
-- 主动指定性别为男,会覆盖默认值
INSERT INTO user(username,gender) VALUES ('王五','男');

修改表,添加/删除默认约束:

sql 复制代码
-- 给已有字段设置默认值
ALTER TABLE user MODIFY COLUMN status TINYINT DEFAULT 1;

-- 删除默认约束
ALTER TABLE user ALTER COLUMN status DROP DEFAULT;

六、外键约束 FOREIGN KEY

1.定义

外键约束:让子表字段关联主表主键 ,强制保证参照完整性

  • 主表(父表):被引用的表,如班级表 class
  • 子表(从表):引用别人的表,如学生表 student
  • 外键字段:子表中关联主表主键的字段,如 student.cid 关联 class.id

规则:子表外键的值,必须在主表主键中存在,不能随便写不存在的数据

2.适用场景

  • 学生归属班级:学生表关联班级表
  • 订单关联用户:订单表关联用户表
  • 商品关联分类:商品表关联分类表

3.示例

先建立主表:班级表

sql 复制代码
-- 主表:班级表
CREATE TABLE class (
    cid INT PRIMARY KEY AUTO_INCREMENT,
    cname VARCHAR(20) NOT NULL COMMENT '班级名称'
);

再建子表:学生表,并添加外键

sql 复制代码
-- 子表:学生表,cid 关联 class 表的 cid
CREATE TABLE student (
    sid INT PRIMARY KEY AUTO_INCREMENT,
    sname VARCHAR(20) NOT NULL,
    age INT,
    cid INT COMMENT '所属班级id',
    -- 定义外键
    FOREIGN KEY (cid) REFERENCES class(cid)
);

测试:

sql 复制代码
-- 先插入班级数据
INSERT INTO class(cname) VALUES ('一班'),('二班');

--正常插入:cid存在的例子
INSERT INTO student(sname,age,cid) VALUES ('张三',18,1);

--违规插入:cid不存在的例子,会报错
INSERT INTO student(sname,age,cid) VALUES ('李四',19,99);

4.外键规则(重点)

当主表删除/修改主键时,子表怎么处理,有四种规则:

(1)RESTRICT / NO ACTION(默认)

子表有关联数据,主表禁止删除 / 修改,保护数据安全。

(2) CASCADE 级联操作

主表改 id,子表自动跟着改;主表删记录,子表自动删关联记录。

sql 复制代码
FOREIGN KEY (cid) REFERENCES class(cid) ON DELETE CASCADE ON UPDATE CASCADE

(3)SET NULL 置空

主表删除 / 修改后,子表外键字段自动设为 NULL。

要求:外键字段不能加 NOT NULL

(4)SET DEFAULT

设置为默认值,InnoDB 引擎基本不支持,工作中不用记。

5.建议

在实际开发应用中,不会设置外键,因为设置外键会对性能有较大的影响

相关推荐
夏贰四13 分钟前
数据建模工具如何筑牢数据根基?数据建模工具怎样落实标准体系?
数据库·数学建模·数据建模工具
程序猿阿伟1 小时前
《一套完整方法论:搞定图形应用的Docker镜像优化》
数据库·docker·容器
二等饼干~za8986682 小时前
geo优化源码开发搭建技术分享
大数据·网络·数据库·人工智能·音视频
数据库小学妹2 小时前
HTAP混合负载架构:如何用一个数据库同时搞定交易和分析
数据库·经验分享·架构·dba
wuxinyan1232 小时前
工业级大模型学习之路029:解决双智能体调用数据库报错问题
数据库·人工智能·python·学习·智能体
Elastic 中国社区官方博客2 小时前
Elastic 线下 Meetup 将于 2026 年 7 月 26 号下午在深圳举行
大数据·数据库·人工智能·elasticsearch·搜索引擎·ai·全文检索
YL200404262 小时前
【Redis实战篇】秒杀实现方案(以优惠券秒杀为例)
数据库·redis
DIY源码阁2 小时前
JavaSwing宿舍管理系统 - MySQL版
java·数据库·mysql·eclipse
cfm_29142 小时前
MySQL8.0 InnoDB Cluster
数据库·mysql