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

前言

在之前我整理了一篇关于数据库在对表的一些常用操作:增删改查,大家有兴趣可以去看看,这篇文章来梳理一下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.建议

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

相关推荐
2301_782040452 小时前
JavaScript中类 Class 语法的可读性与维护性优势
jvm·数据库·python
2401_871492852 小时前
HTML函数在旧版Windows跑得动吗_系统版本与硬件协同影响【指南】
jvm·数据库·python
kexnjdcncnxjs3 小时前
如何利用宝塔面板进行数据迁移_使用宝塔整机备份功能
jvm·数据库·python
人道领域3 小时前
【黑马点评日记】RedisGEO实战:黑马点评附近商铺功能
java·数据库·redis·adb
LuDvei3 小时前
ubuntu环境下qt打包
linux·数据库·qt·ubuntu
iuvtsrt3 小时前
C#怎么获取当前所在的函数名_C#如何使用MethodBase读取【代码】
jvm·数据库·python
阿Y加油吧3 小时前
RAG 必学:ANN 检索、HNSW 算法与 Milvus 核心概念详解
数据库·mysql·json
anew___4 小时前
从教科书到实战:深入剖析MySQL数据库恢复机制
数据库·mysql
_376271535 小时前
Cgo回调函数中处理 const char- 类型参数的正确方法
jvm·数据库·python