数据库的约束

数据库的约束

数据库约束(Constraints):数据库管理系统中用于保证数据完整性 、一致性 和准确性的规则

数据库的分类

约束类型 作用 是否允许 NULL 是否唯一 一个表的数量
PRIMARY KEY 唯一标识行 ❌ 不允许 ✅ 是 1 个
FOREIGN KEY 建立表间关系 ✅ 允许 (可配置) ❌ 否 多个
UNIQUE 值唯一 ✅ 允许 (通常一个) ✅ 是 多个
NOT NULL 值非空 ❌ 不允许 ❌ 否 多个
CHECK 值满足条件 取决于条件 ❌ 否 多个
DEFAULT 提供默认值 可指定 ❌ 否 多个

非空约束 (NOT NULL)

非空约束作用:确保某列不含NULL值

特点:

  • 强制要求该列必须有值

由于name列有⾮空约束,插⼊NULL值时报错

查看表结构,NULL列为NO表⽰值不允许为NULL,YES表⽰值可以为NUL值

SQL 中对 NULL 值的正确判断方式

NULL 表示未知或缺失的值,不是任何具体的数据(比如不是空字符串、也不是0),因此不能用普通的比较运算符(如 =、!=)来判断

✅ 正确:name IS NOT NULL、name IS NULL、NOT (name IS NULL)

❌ 错误:name = NULL

DEFALUT默认值约束

默认约束作用:为列指定一个默认值,当插入新记录时,如果没有为该列提供值,数据库将自动使用默认值

特点:

  • 默认值可以是常量、系统函数(如 CURRENT_DATE)等

唯一约束 (UNIQUE)

唯一约束作用:确保一列或多列的组合中的数据在表中是唯一的

特点:

  • 与主键不同,唯一约束允许 NULL 值,但通常只允许一个 NULL
  • 一个表可以有多个唯一约束
  • 数据库为唯一约束创建唯一索引

主键约束 (PRIMARY KEY)

关系数据库中的实体完整性约束 和 候选关键字(Candidate Key)

实体完整性(Entity Integrity) :主键(Primary Key)不能为 NULL,且必须唯一

  • 主键是从"候选关键字"中选择的一个
  • 候选关键字(Candidate Key):能够唯一标识关系中每一行的属性或属性组合,且不含多余属性(即最小性)
  • 一个关系中可以有多个候选关键字,但只能选一个作为主键

主键约束作用:唯一标识表中的每一行数据,主键列的值必须唯一 且非空(NOT NULL)

特点:

  • 一个表只能有一个主键
  • 主键可以由一个列构成,也可以由多个列组合构成(复合主键)
  • 数据库会自动为主键创建唯一索引,以提高查询效率
  • 通常为每张表都指定⼀个主键,主键列建议使⽤BIGINT类型

not null unique=primary key

如果某条记录写⼊失败,新⽣成的主键值将会作废

主键值不连续的情况

如果插入数据时发生主键或唯一键冲突,则执行更新操作;否则,执行插入操作

替换,存在冲突替换否则插入

写入新的数据

更新数据

表中不能存在多个主键

复合主键:由多个列共同组成的主键,主键是否冲突以多个列的组成进⾏判定

外键约束(FOREIGN KEY)

作用:维护表与表之间的引用完整性,确保一个表中的列(外键)匹配另一个表中的主键值

特点:

  • 外键值必须在被引用表的主键中存在,或者为 NULL
  • 用于建立表之间的关联关系(如一对多、多对多)
  • 父表(主表):被引用的表,通常是包含主键的表
  • 子表(从表):包含外键的表,它引用父表的主键
  • 外键(Foreign Key):子表中的一个或多个字段,它指向父表的主键或唯一键

删除主表首先要删除从表

CHECK约束

作用:限制列中可接受的值范围

特点:

  • 定义逻辑表达式来验证数据

sql 复制代码
use student;
drop table student;
create table student(id int,name varchar(10),age int);
insert into student (id,name,age) values (1,'Lars',null);
select * from student;
drop table if exists student;
create table student(id bigint,name varchar(10) not null,age int);#添加非空约束
insert into student (id,name,age) values (1,'Lars',null),(2,'Amy',20);
select * from student;
desc student;
insert into student(id,name,age) values(3,'张三',null); 
drop table if exists student;
create table student(id bigint,name varchar(10) not null,age int default 20);
insert into student(id,name) values (1,'张张'),(2,'王王'),(3,'邹邹')
;
insert into student (id,name,age) 
select * from student;
desc student;
drop table if exists student;
create table student(id bigint,name varchar(10) not null,age int default 20,student_number bigint unique);
insert into student (id,name,age,student_number)values (1,'zz',21,12345),
(2,'xx',22,123456);
select * from student;
desc student;
drop table if exists student;
create table student(id bigint,name varchar(10) not null,age int default 20,student_number bigint not null unique);
desc student;
create table student(id bigint primary key auto_increment,name varchar(10) not null,age int default 20,student_number bigint unique );
insert into student(id,name,student_number) values (null,'zz',11);
select * from student;
insert into student(name,student_number) values ('xx',22);
desc student;
insert into student(name,student_number) values ('cc',22);
insert into student(name,student_number) values ('vv',33);
select * from student;
insert into student(id,name,student_number)values(100,'bb',66);
insert into student(name,student_number)values('nn',67);
select * from student;
insert into student(id,name,student_number)values(101,'bb',68);
insert into student(id,name,student_number)values(101,'bb',68)on duplicate key update name='mm';
replace into student(id,name,student_number)values(102,'aa',68);
select * from student;
replace into student(id,name,student_number)values(101,'ss',67);
drop table student;
create table student (
 id bigint PRIMARY KEY auto_increment,  # 定义主键
name varchar(20) PRIMARY KEY            # 定义主键
);
create table student(id int,name varchar(20),primary key(id,name));
insert into student (id,name) values(1,'zz');
insert into student(id,name)values(2,'zz');
select * from student;
drop table if exists student;
drop table if exists class;
create table class(class_id bigint primary key auto_increment ,class_name varchar(20) not null);
insert into class(class_name)values('Java'),('MySQL'),('C');
select * from class;
drop table if exists class;
create table class(class_id bigint primary key auto_increment ,class_name varchar(20) not null);
insert into class(class_name)values('Java'),('MySQL'),('C');
create table student(id int ,name varchar(20),class_id bigint, 
foreign key(class_id) references class(class_id));
desc student;
select * from class;
insert into student(id,name,class_id) values(1,'zz',1),(2,'xx',1),(3,'cc',2),(4,'vv',2),(5,'bb',3);
select*from student;
insert into student(name,class_id)values('nn',4);
insert into student(name,class_id)values('nn',null);#表示学生还没有分配班级
insert into class(class_id,class_name) values(4,'JavaEE');
delete from class where class_name='JavaEE';
delete from class where class_name='C';
drop table student;
drop table class;
create table student(
 id bigint PRIMARY KEY auto_increment, name varchar(20) not null, age int DEFAULT 20, gender char(1),
  check (age >= 16),check (gender = '男' or gender = '女'));
 insert into student(name,age,gender)values('zz',17,'男'),('xx',20,'女');
 select * from student;
insert into student(name, age, gender) values ('cc',15,'女');
insert into student(name, age, gender) values ('cc',15,'1');
相关推荐
笃行35023 分钟前
数据库性能优化的五处内核改造,KingbaseES 配了四件诊断工具
数据库
非优秀程序员2 小时前
第02章 杭电的英语老师与一台服务器|《互联网产品恩仇录》
数据库·node.js·代码规范
SelectDB7 小时前
SelectDB 是哪个公司的?是国产数据库吗?一篇讲清飞轮科技与 Apache Doris 的关系
数据库
这个DBA有点耶7 小时前
库内计算推理:一条SQL背后的算子融合,和外挂方案差了几次网络往返
数据库·人工智能·sql
这个DBA有点耶9 小时前
函数索引的“完全一致”有多苛刻:写法、字符集、类型,差一处就失效
数据库·mysql·代码规范
星恒随风9 小时前
MySQL 从零入门(三):表的约束详解
linux·服务器·数据库·笔记·mysql
Alluxio10 小时前
Alluxio + OCI:为 AI 工作负载实现亚毫秒访问延迟与可扩展吞吐
运维·数据库·人工智能·分布式·缓存·ai·语言模型
数据库急诊室_阿哲14 小时前
一次加索引建议的复核记录:从报告到签字
数据库·ai数据库
青瓦梦滋15 小时前
Redis主从复制
服务器·数据库·redis·缓存·bootstrap
慧都小妮子15 小时前
Wyn商业智能国产数据库适配:数据接入、分析缓存与审计日志验证清单
数据库·数据分析·数据可视化·审计日志·商业智能