文章目录
在 SQL
中,表的约束是用于限制表中数据的规则,目的是保证数据的完整性、一致性和有效性。通过约束,可以防止不合理或错误的数据进入表中,确保数据库中数据的质量,约束特性在SQL
中一般在创建的时候定义,或者后续使用ADD
添加
一,非空
指定一个字段,每次添加数据时,这个字段的数据都不能为空,否则报错,使用关键字NOT NULL
演示代码
sql
CREATE TABLE student(
id INT,
name varchar(50) NOT NULL
);
标识name
字段不能为空,我们想表中插入一个name
为空的数据
sql
INSERT INTO student (id,name) VALUES(2,NULL);
SELECT * FROM student;
演示结果
提示这里的name
的值不能为空
二,唯一
指定一个字段,使表中的这个字段里面的数据都不相同,使用关键字为UNIQUE
sql
CREATE TABLE grade(
id int UNIQUE,
point int
);
演示代码
sql
INSERT INTO grade(id,point) VALUES(1,85);
INSERT INTO grade(id,point) VALUES(1,90);
演示结果
提示这个1
作为key输入了两次,报了错误
三,主键约束
主要是使用PRIMARY KEY
,一般用于标记一个表中的唯一标识符数据
sql
CREATE TABLE students(
id INT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(50)
)
唯一标识表中的每条记录,确保记录不重复,且不为空,一个表只能有一个主键,主键字段的值必须唯一且非空,每次我们想插入一个数据,都会校验一下插入行的PRIMARY_KEY
标记的数据,数据的要求是再表中不能有重复的,并且不能为空同时拥有UNIQUE
和NOT NULL
两个特性。
在实际项目当中用于数据库当中作为数据行的唯一标识符,一般在业务代码中和AUTO INCREASE
一起使用,这样我们插入数据直接需要的数据就可以。但是这里有个前提,就是表中的主键字段的个数只能有一个
sql
INSERT INTO students(name) VALUES('小红'),('小刚');
SELECT * FROM students;
演示结果
四,默认值
当我们插入数据时,没有指定数据,那么数据表就会采用我们在创建表的时候设置的默认值,主要使用的关键字是DEFAULT
使用格式
sql
CREATE TABLE NUMBERS(
id INT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(50) DEFAULT '学生'
);
演示代码
sql
INSERT INTO numbers VALUES(),();
演示结果
我们没有插入name
数据,这里数据表直接采用默认值
五,FOREIGN KEY
简单来讲,FOREIGN KEY
(外键)就是用来连接两个数据表的"桥梁",让它们通过共享的ID进行映射和引用。
想象一下,一本书的目录和正文:目录里列出章节号
(ID),对应正文的实际内容。只有通过这个"对应关系",我们才能快速翻到想看的部分,让整本书变得井井有条、好用简便。外键就是数据库里的"目录机制"------它确保子表(比如订单表)里的引用ID
,总能准确指向父表(比如用户表)里的真实记录,避免数据"孤儿"或混乱。
再举个学校学生的例子:一个学生的完整信息,包括基本资料(姓名、ID)、家庭背景、成绩单、个人经历和奖项。如果把所有这些都塞进一张大表,会不会乱成一锅粥?数据冗余、查询慢,还难维护。
这就是为什么我们用关系型数据库设计:将相似的数据分类存入不同表,再通过外键建立连接。
父表:学生基本表(id PRIMARY KEY, name)。
子表:成绩表(student_id FOREIGN KEY REFERENCES 学生表(id), score)。
其他子表:家庭表(student_id FOREIGN KEY...)、奖项表(student_id FOREIGN KEY...)。
这样,学生信息就"模块化"了!查询时超级方便:只需拿到学生的ID,就能轻松"跳"到相关表拉数据。比如,用SQL
的JOIN
查询,就能一键拼出"学生A的成绩+家庭背景"------高效又不乱。
总之,外键不是魔法,但它是数据库"防乱神器",帮你从杂乱数据中构建清晰的"整体画像"。
演示代码:创建两个表,分别是成绩表和学生表,需要注意的是外键对应的值必须要有唯一性,比如PRIMARY KEY
和UNIQUE
sql
CREATE TABLE student(
id int PRIMARY KEY,
name VARCHAR(50)
);
CREATE TABLE grades(
id int PRIMARY KEY AUTO_INCREMENT,
math int,
english int,
user_id int,
FOREIGN KEY(user_id) REFERENCES student(id) ON DELETE CASCADE
)
这里我们多加了一个ON DELETE CASCADE
,逻辑意义就是当删除grades
中对应的student
的数据时,外键对应的数据grades
的数据也会被删除.
我们来在student
中插入几个数据行
sql
INSERT INTO student (id,name) VALUES (1'小甘'),(2,'小红'),(3,'小刚'),(4,'小新'),(5,'小锦');
演示结果:有五行数据
我们再在grades
中添加数据
sql
INSERT INTO grades (id,math,english,user_id)
VALUES (2,90,80,2),(3,70,50,3),(4,68,85,4),(5,95,75,5);
演示结果
不过这里我们需要注意的是,如果我们的user_id
的值选择student
的id
之外的值,那么就会报错
演示代码
sql
INSERT INTO grades (id,math,english,user_id)
VALUES (6,90,80,6);
演示结果
因为外键没有找到需要对应的值,所以发生了一个报错
删除问题
想象一下,在电商网站上,你下了一个单(订单记录),但后来你注销了账号(用户被删)。这个订单该怎么办?跟着一起消失,还是留下来"孤零零"?这就是主表(用户表)和从表(订单表)的删除关系------订单里的user_id外键引用用户的主键,确保"订单不离用户"。
用ON DELETE CASCADE
关键字创建外键,就能提供保障:删除用户(主表)时,系统自动把所有相关订单(从表)一并删除。简单高效,避免手动追删。
如果不用CASCADE
,会怎样:默认情况下(不指定ON DELETE
),MySQL
用RESTRICT
规则:尝试删用户时,如果订单还引用它,会抛异常Cannot delete or update a parent row: a foreign key constraint fails
。这阻止了删除,保护数据完整性------防止"孤儿订单":用户没了,但订单还挂着无效的user_id
,查询时我们不知道订单属于谁,数据就乱套了。
业务上,怎么破?有三种常见策略:
先删从表,再删主表:手动清订单,然后删用户(适合审计需求)。
一起删:用CASCADE
,一键搞定(你的电商场景首选)。
都不删,或软删:用ON DELETE SET NULL
把user_id
设空(订单匿名保留),或干脆不删用户,只标记"注销"。
这样,数据库像个严谨的"仓库管理员"------不会让货单"认错爹"!
演示代码:这里我们删除一个主表的数据试试哦
sql
DELETE FROM student WHERE id = 1;
演示结果
student:
grades:
这里我们删除了一个student
的数据,它对应的grades
的数据也被一并删除了
六,CHECK
CHECK
是一个约束条件哦,就像我们在参加招聘会一样,面试官要求学历不低于本科,年龄不低于20岁,不高于35岁,否则不允许投递简历(数据),但是CHECK
这个表约束特性只在MySQL8.0
版本才存在
我们来演示一下:为表添加约束条件,然后添加数据
sql
ALTER TABLE student ADD CONSTRAINT age CHECK(age<35);
INSERT INTO student (id,name ,age) VALUES(7,'小平',80);
演示结果
这里添加限制条件需要记住,使用CONSTRAINT
关键字,因为age
大于35
,所以CHECK
不允许此数据添加通过