大家好,我是?WeiyiGeek,一名深耕安全运维开发(SecOpsDev)领域的技术从业者,致力于探索DevOps与安全的融合(DevSecOps),自动化运维工具开发与实践,企业网络安全防护,欢迎各位道友一起学习交流、一起进步 ,若此文对你有帮助,一定记得倒点个关注?与小红星??,收藏学习不迷路??。
0 前言简述
上一篇,我们一起学习了 MySQL 内置的一些常用函数,想必各位看友都有一定的收获吧,在此基础上,我们来继续学习 MySQL 中字段约束的相关知识,大家可能从字面意义上来看就是限制,没错就是限制,那下面我们来详细讲解一下。
温馨提示:若文章代码块中存在乱码,请通过文末的阅读原文链接,在知识星球中阅读,或者直接访问原文链接:https://articles.zsxq.com/id_ew3wx9zqteks.html
1 MySQL 约束
基础概念
概念:约束(Constraint)是作用于表中字段上的规则,用于限制存储在表中的数据。
目的:保证数据库中插入数据的正确性,有效性和完整性。
分类:在 MySQL 数据库中约束分为非空约束、默认约束、唯一约束、主键约束、外键约束、以及?检查约束(8.0.16 版本后加入)。
| 关键字 | 约束名称 | 描述 |
|---|---|---|
NOT NULL |
非空约束(Not Null Constraint) | 限制字段的数据不能为null |
DEFAULT |
默认约束(Default Constraint) | 限制保存数据时,若字段值未指定则采用默认 |
UNIQUE |
唯一约束(Unique Constraint) | 保证字段所有的字段都是唯一不重复的 |
PRIMARY |
主键约束 | 表示一行数据的唯一标识,要求非空且唯一 |
FOREIGN |
外键约束 | 用于两张或者多张表之间创建连接,保证数据的一致性和完整性 |
CHECK |
检查约束(Check Constraint) | 限制保存数据时,检查插入的数据是否满足表达式要求,支持条件以及正则匹配,特别注意在 8.0.16 版本之后,5.7.x 版本是不支持的。 |
特别注意:不同的数据库管理系统可能某些约束关键字是不一样的,不过基础的非空约束(Not Null Constraint)、唯一约束(Unique Constraint)、默认约束(Default Constraint)基本上都满足,若大家使用时报错可参考官方文档。
使用约束
牛刀小试:通过一个案例需求,完成 constraint_user 的创建,演示配置字段约束对于保证数据的有效性、完整性。
| 字段名 | 含义 | 类型 | 约束条件 | 约束关键字 |
|---|---|---|---|---|
| id | 主键标识 | INT UNSIGNED | 自增长,主键 | AUTO_INCREMENT PRIMARY KEY |
| name | 用户名称 | VARCHAR(16) | 非空 | NOT NULL |
| age | 用户年龄 | TINYINT UNSIGNED | 校验年龄大于 0 ,小于等于 120 | CHECK |
| sex | 用户性别 | ENUM('F','M') 或者 CHAR(1) | 无 | 无 |
| phone_number | 移动电话 | CHAR(11) | 非空,校验移动电话 | NOT NULL CHECK |
| id_card | 身份证 | CHAR(18) | 非空,唯一,校验身份证 | NOT NULL CHECK |
| status | 用户状态 | CHAR(1) | 默认值为E(enable) 启用 | DEFAULT |
在部署的 MySQL 8.X 数据库中执行以下建表语句:
USE TEST;-- 建表语句CREATE?TABLE?IF?NOT?EXISTS?constraint_user (? ? id?INT?UNSIGNED AUTO_INCREMENT?PRIMARY?KEY COMMENT?'用户主键ID',? ? name?VARCHAR(16)?NOT?NULL?COMMENT?'用户名称',? ? age TINYINT UNSIGNED?CHECK( age?>?0?&&?age?<=?120?) COMMENT?'年龄',? ? sex ENUM('F','M') COMMENT?'性别',? ? phone_number?CHAR(11)?NOT?NULL?CHECK?( phone_number REGEXP?'^1[3-9]d{9}$') COMMENT?'手机号',? ? id_card?CHAR(18)?NOT?NULL?UNIQUE?KEY?CHECK?(id_card REGEXP?'^d{17}[0-9Xx]$') COMMENT?'身份证号'?,? ? status?char(1)?DEFAULT?'E'?COMMENT?'状态');
查看建表语句,执行以下 SQL 查询语句:
-- 查看表结构mysql>?DESC?constraint_user;-- 查看建表语句信息mysql>?SHOW?CREATE?TABLE?constraint_user;CREATE?TABLE?`constraint_user` (? `id`?int?unsigned?NOT?NULL?AUTO_INCREMENT COMMENT?'用户主键ID',? `name`?varchar(16)?NOT?NULL?COMMENT?'用户名称',? `age` tinyint unsigned?DEFAULT?NULL?COMMENT?'年龄',? `sex` enum('F','M')?DEFAULT?NULL?COMMENT?'性别',? `phone_number`?char(11)?NOT?NULL?COMMENT?'手机号',? `id_card`?char(18)?NOT?NULL?COMMENT?'身份证号',? `status`?char(1)?DEFAULT?'E'?COMMENT?'状态',??PRIMARY?KEY (`id`),??UNIQUE?KEY `id_card` (`id_card`),??CONSTRAINT?`constraint_user_chk_1`?CHECK?(((`age`?>?0)?and?(`age`?<=?120))),??CONSTRAINT?`constraint_user_chk_2`?CHECK?(regexp_like(`phone_number`,_utf8mb4'^1[3-9]d{9}$')),??CONSTRAINT?`constraint_user_chk_3`?CHECK?(regexp_like(`id_card`,_utf8mb4'^d{17}[0-9Xx]$'))) ENGINE=InnoDB?DEFAULT?CHARSET=utf8mb4?COLLATE=utf8mb4_0900_ai_ci ??
weiyigeek.top-查看建表语句图
由上面这个小案例可知,约束之间是可以多个一起使用,使用时注意以空格进行分割,例如:NOT NULL UNIQUE,其次通过查询建表语句看到设置约束都自动格式化到了建表语句的最后,便于我们查看。
特别注意:在 MySQL 8.0.16 版本之后,CHECK 约束是支持的,但是 CHECK 约束的表达式中不能使用函数,例如:CHECK(YEAR(birthday) > 1900)?这种写法是不允许的。
加入:作者【全栈工程师修炼指南】知识星球
『?全栈工程师修炼指南』星球,主要涉及全栈工程师(Full Stack Development)实践文章,包括但不限于企业SecDevOps和网络安全等保合规、安全渗透测试、编程开发、云原生(Cloud Native)、物联网工业控制(IOT)、人工智能Ai,从业书籍笔记,人生职场认识等方面资料或文章。
363