MySQL系列
文章目录
前言
本篇文章将为你详细介绍 MySQL 中常见的几种约束,内容较为丰富,建议耐心阅读。
通过上篇文章的讲解我们已经了解到,MySQL 中的数据类型本身具备一定约束能力,但这种约束极为单一,无法满足实际业务场景的复杂需求。因此,本章将重点聚焦于 MySQL 的约束机制——约束是保障表数据正确性与合法性的关键技术手段。
数据类型是约束字段的基础,但仅靠数据类型无法实现全面的约束。为了从业务逻辑层面确保数据合法、符合业务规则,必须引入额外的约束机制对数据进行多重校验。
本章主要围绕以下核心约束展开介绍:null/not null(空值约束)、default(默认值约束)、comment(注释约束)、zerofill(零填充约束)、primary key(主键约束)、auto_increment(自增约束)、unique key(唯一约束)。
一、NULL(空属约束)
null(允许空值)和 not null(禁止空值)是基础且常用的约束类型:
- null:表示字段允许存储空值,这是数据库字段的默认设置。
- not null:强制字段必须存储具体值,不允许为空。
在 MySQL 中,NULL 和 ‘’(空串) 是两个截然不同的概念,需严格区分:NULL 代表“未知”,表示该字段未被定义或未录入数据,逻辑上属于“无值”;而 ‘’(空串) 是长度为 0 的有效字符串,代表“存在但内容为空”,属于“有值”。
在大学生活中,我们经常会被要求填写一些表格,这些表格中一定存在一些必须要填的,这种情况下我们就可以将该字段设置为not null
(不可为空),接下来我就以下面为例创建表格:
创建一个班级表,包含班级名和班级所在的教室。
此时就面临着,如果班级没有名字,你不知道你在哪个班级;如果教室名字可以为空,就不知道在哪上课。
create table myclass(
student_name varchar(8) not null,
class_name varchar(20) not null,
class_room varchar(10) not null,
other varchar(20));
可以看到,当我向表中插入数据忽略class_name
字段时,MySQL
会阻止报错。表中Null
列表示,表中对应列是否允许为空。
我们未对其设置的列,默认为允许为空。
二、default(默认值约束)
默认值:为字段预先设定的高频重复值,当用户未输入数据时,系统自动填充该预设值。
create table t10(
name varchar(20) not null,
age tinyint unsigned default 0,
gender char(2) default '男'
);
可以看到,当对于某列的默认值设置后,插入数据忽略该字段,系统就会使用默认值来填充。表格中Default
列,表示对应列设置的默认值,若没有设置默认为null
。
当把一个属性设置为非空约束,并且同时设置默认值约束。
在 MySQL 中,非空约束(NOT NULL) 和 默认值约束(DEFAULT) 是两个独立但可协同工作的机制,其核心工作逻辑如下:
优先级顺序:
- 用户显式赋值:优先使用用户提供的值。
- 默认值:用户未提供值时,使用
DEFAULT
指定的值。 - 报错:若既无用户输入,又无默认值,且字段被标记为
NOT NULL
,则抛出错误。
非空约束确保字段始终有值,而 默认值约束 提供了“无输入时的备选值”。
三、comment(注释约束)
comment
没有实际含义,专门用来描述字段,会根据表创建语句保存,是用来给程序员或DBA
来进行了解。
create table t11(
name varchar(20) not null comment '名字',
age tinyint unsigned default 0 comment '年龄',
gender char(2) default '男' comment '性别');
这里你知道如何设置、如何查看就可以了。
四、zerofill(零填充约束)
在上篇介绍数据类型时,我并没有介绍int
类型,在使用int
类型时你有可能会看到int(10)
,将int
类型设置为unsigned
时就会变为int(11)
(这个不一定,视环境而定),而这就是int
类型最大显示的位数(10位可以表示42亿多的值,刚好足够表示int
类型数据),当对int
类型字段设置位zerofill
时,数据就会以最大位数显示不足就会在前面补0
;
五、primary key(主键约束)
- 主键primary key: 用来唯一的约束该字段里面的数据,不能重复,不能为空,一张表中最多只能有一个。
- 主键通常所在的列通常是整数类型
create table test_key(
id int unsigned primary key ,
name varchar(20) not null);
将某列设置为主键后,该列将不再允许插入列中存在的数据,并且作为主键的列,默认设为非空(设置非空约束)。
对某行设置为主键,有以下几种方式:
- 建建表时直接设置为primary key
- 建表完成后,再设置主键alter table db_name add primary key(列名)
要将所选字段修改为主键,那么该字段就必须满足主键的要求(删除重复行),否则就无法修改为主键。
删除主键: alter table db_name drop primary key;
复合主键
在创建 MySQL 表时,主键可以在所有字段定义之后通过 PRIMARY KEY(主键字段列表)
语法声明。这种方式既支持单一字段作为主键(如 PRIMARY KEY(id)
),也支持将多个字段组合为复合主键(如 PRIMARY KEY(name, age)
,即多个字段共同唯一标识一条记录)。需要明确的是:一张表中最多只能定义一个主键,但这并不限制主键仅对应单个字段——复合主键通过将多个属性合并为一个逻辑上的“联合标识”,同样满足主键的唯一性约束。
create table t13(
id int unsigned,
name char(10),
primary key (id,name));
可以看到,只有当这个主键“组合”重复插入时,MySQL才会拦截操作。
六、auto_increment(自增长约束)
当对应的字段,不给值,会自动的被系统触发,系统会从当前字段中已经有的最大值+1操作,得到一个新的不同的值。通常和主键搭配使用,作为逻辑主键。
自增长的特点:
- 任何一个字段要做自增长,前提是本身是一个索引(key一栏有值)
- 自增长字段必须是整数
- 一张表最多只能有一个自增长
create table t14(
id int primary key auto_increment,
name char(10));
当将某个字段设置为自增长时,在插入数据时即使忽略该字段,MySQL也会在该列当前最大值的基础上+1,作为新的数据插入。
该字段记录的就是,下次默认插入的数据。
在建表时,可以直接设置自增长开始值:
CREATE TABLE t14 (
id INT PRIMARY KEY AUTO_INCREMENT,
name CHAR(10)
) AUTO_INCREMENT = 100;
七、unique key(唯一约束)
在实际生活中,手机号、身份证号等许多属性都具有唯一性,对应到数据库表中,往往需要多个字段满足“数据不重复”的约束。但由于一张表只能有一个主键,唯一键(UNIQUE) 成为解决多字段唯一性需求的关键机制。
唯一键的核心作用与主键类似——确保字段值不重复,但二者存在关键差异:唯一键允许字段值为 NULL,且允许多条记录的该字段为 NULL(因为 NULL 不参与唯一性比较);而主键则严格禁止 NULL 值,且一张表只能定义一个主键。
create table t16(
id int primary key,
name char(10),
phone_number varchar(10) unique);
可以看到唯一键不允许插入重复数据,但是允许插入NULL
值(可以配合非空约束,使得唯一键不能为空),此外唯一键也可以配合自增长使用。
在数据库设计中,有一个重要原则需要注意:建议将主键设计为与当前业务无关的字段(例如纯数字自增 ID)。这样做的核心优势是,当业务逻辑发生调整(如规则变更、需求迭代)时,主键不会因业务属性变化而被迫修改,从而减少对数据结构和关联逻辑的影响。而对于那些在业务层面必须保证唯一性的字段(例如员工工号、用户手机号等),更适合通过 唯一键(UNIQUE)约束 来实现——既满足“业务上不能重复”的核心需求,又避免将业务属性与主键强绑定。
八、froeign key(外键)
在关系型数据库中,外键(FOREIGN KEY) 是定义 主表 与 从表 关联关系的核心机制。其核心规则如下:外键约束必须定义在从表上,用于关联主表的特定字段;而对应的主表必须为该字段设置主键约束PRIMARY KEY)或唯一约束(UNIQUE),以保证被引用值的唯一性。当外键约束生效后,从表外键列的取值需严格遵循规则:要么是主表对应主键/唯一键列中已存在的值,要么为 NULL(前提是外键列未被限制为非空)。这一机制确保了主从表之间的数据一致性。
foreign key (字段名) references 主表(列)
假设班级只有两个,学生数量增加只需添加一个class_id字段即可,通过这种方式可以大大减少空间消耗。
- 主键表
create table myclass (
id int primary key,
name varchar(30) not null comment'班级名'
);
- 从键表
create table stu (
id int primary key,
name varchar(30) not null comment '学生名',
class_id int,
foreign key (class_id) references myclass(id)
);
可以看到当插入一个班级号为30的学生,因为没有这个班级,所以插入不成功
上图打算展示的是,stu表的内容,结果sql语句输错了,你知道就好
当从表键不知道要存储何值时,允许存入空。
外键特点
- 对于设置了外键约束的字段来说,它关联的外键值,必须是在关联表中是存在的/为null
- 设置外键约束,能很好的保证某一些特别值(需要保证存在的值)不出现不存在的情况
- 设置外键还能让两个表有一定的关联性(主从表的关联关系)
- 其中关联的外键字段必须是关联表的主键/唯一键列
设置外键名
在未设置外键名时,系统使用默认名
CREATE TABLE employees (
emp_id INT PRIMARY KEY,
emp_name VARCHAR(50),
dept_id INT,
// 自定义外键名:fk_employees_departments
CONSTRAINT fk_employees_departments
FOREIGN KEY (dept_id) REFERENCES departments(dept_id)
);
总结
数据表必须合理设置各类约束。借助约束机制,能够强制未来插入数据库的数据严格符合预设规则与预期标准。从本质上讲,约束是通过技术规则倒逼开发者输入正确数据;而站在 MySQL 的角度,所有成功写入数据库的数据,都必然满足了预设的全部约束条件,归根结底,约束的核心价值在于确保数据的正确性与可预期性,为数据质量提供坚实保障。
本篇内容就到这里了,若在文中发现错误,可以私信博主,希望本文能对你有帮助,感谢支持。