MySQL-约束Constraint详解

news2024/10/12 6:14:09

文章目录

    • 约束简介
    • 非空约束
    • 检查约束
    • 唯一约束
    • 列级约束与表级约束
    • 给约束起名字
    • 主键约束

约束简介

约束是我们在创建表的时候, 我们可以给表中的字段添加约束确保我们的数据的完整性和有效性, 比如大家平时上网时注册用户常见的 : 用户名不能为空, 对不起, 用户名已经存在等提示信息
约束通常包括下面的这6种

约束类型约束关键字
非空约束not null
默认约束default
检查约束check
唯一约束unique
主键约束primary key
外键约束foreign key

下面我们会详细的剖析这几种约束(默认约束省略, 就是一个简单的在不插入这个字段的数据时插入默认值)

非空约束

这个约束比较好理解, 就是插入的数据不能为空, 当我们设置这一个约束的时候, 我们使用desc展示表结构的时候, 表的Null那一行就会设置为NO, 允许为空就会为YES, 下面是我们的一个实例

+--------+-------------+------+-----+---------+-------+
| Field  | Type        | Null | Key | Default | Extra |
+--------+-------------+------+-----+---------+-------+
| DEPTNO | int         | NO   | PRI | NULL    |       |
| DNAME  | varchar(14) | YES  |     | NULL    |       |
| LOC    | varchar(13) | YES  |     | NULL    |       |
+--------+-------------+------+-----+---------+-------+

尝试完成下面的一个需求, 创建一个学校表, 有编号, 学校名称(不能为空), 建校时间, 这时候就需要给name字段加上一个非空约束not null
我们尝试执行下面的SQL语句

-- 创建一个学校表
create table school(
    sno int comment '学校编号',
    name varchar(255) not null comment '学校名称',
    est_time date comment '建校时间'
);

-- 插入几条数据来进行测试(关于日期类型的插入, 其实底层会进行str_to_date函数的调用, 把字符串转化为日期)
insert into school (sno, name, est_time) values (1, '北京101中学', '1910-08-11');
insert into school (sno, name, est_time) values (2, '南开附中', '1912-04-13');
insert into school (sno, name, est_time) values (3, '清华附中', '1915-03-12');

-- select 查询一下当前的信息
select * from school;

-- 执行结果如下
+------+-----------------+------------+
| sno  | name            | est_time   |
+------+-----------------+------------+
|    1 | 北京101中学     | 1910-08-11 |
|    2 | 南开附中        | 1912-04-13 |
|    3 | 清华附中        | 1915-03-12 |
+------+-----------------+------------+

由于我们添加了非空约束, 也就是我们的name不可以为null, 如果插入一条数据没有name就会报错

-- 尝试执行下面的SQL
insert into school (sno, est_time) values (4, '1899-11-06');
-- 会直接报错, 报错信息如下
ERROR 1364 (HY000): Field 'name' doesn't have a default value

检查约束

其实就是在创建一张表的时候添加一定的检查信息, 这个约束时MySQL8版本之后新添加的, 在先前的版本中是不存在的
基础语法

create table [表名](
	...字段信息
	check(约束条件)
);

我们尝试建一张学生表, 要求添加学生的年龄必须大于18岁, 这种情况就可以使用检查约束

-- 创建一张学生表
create table t_stu(
    sno int,
    name varchar(255),
    age int,
    check(age > 18)
);

-- 执行DML语句
insert into t_stu(sno, name, age) values (1, 'hh', 19);
insert into t_stu(sno, name, age) values (2, 'xx', 18);
-- 第一条是执行成功的, 但是第二条 18 == 18, 不满足check约束, 所以失败

唯一约束

对一个字段添加unique约束, 这个字段就具有了唯一性, 唯一性的字段是可以为null, 但不可以重复, 如果是null的话, 是可以重复的, 我们拿下面的t_stu表作为一个例子说明

# 创建了一个学生表, 这个表的email字段是唯一的, 不可以重复
create table t_stu(
	no int,
	name varchar(255),
	email varchar(255) unique
);
# 我们尝试执行下面的DML语句, 执行成功成功的标明 √, 否则为 ×
insert into t_stu (no, name, email) values (1, 'hh', 'hh@163.com');
insert into t_stu (no, name, email) values (2, 'xx', 'xx@163.com');
insert into t_stu (no, name) values (3, 'xx'), (4, 'wx');
# 查看一下当前的信息
select * from t_stu;
+------+------+------------+
| no   | name | email      |
+------+------+------------+
|    1 | hh   | hh@163.com |
|    2 | xx   | xx@163.com |
|    3 | xx   | NULL       |
|    4 | wx   | NULL       |
+------+------+------------+
# 尝试插入一条重复的数据
insert into t_stu (no, name, email) values (5, 'sf', 'hh@163.com');
# 直接报错, 因为email的位置重复了

unique约束也可以和not null 同时使用表示非空且唯一

create table t_stu(
	no int,
	name varchar(255),
	email varchar(255) not null unique
);

列级约束与表级约束

如果一个约束紧紧的跟在字段后面, 那这个字段仅仅作用于这一个字段, 我们称之为列级约束, 如果一个约束位于表定义的结尾位置, 那么这个约束我们称之为表级约束, 这种约束可以约束多种字段

unique, primary key, foreign key 可以作为表级约束存在, not null 不可以作为表级约束

我们比较一下下面的SQL语句

# unique的列级约束
create table t_stu(
	no int,
	name varchar(255),
	email varchar(255),
	unique(email)
);
# unique的表级约束
create table t_stu(
	no int,
	name varchar(255),
	email varchar(255),
	unique(name,email)
);

那么上述列级和表级的约束有什么区别呢?
答案是 : 表级可以联合联合多个字段而列级只能约束一个字段

给约束起名字

约束是以对象的形式存在的, 所有的约束对象对象都存在一个系统表中
information_schema(四个系统数据库之一)中的table_constraints这个表中, 这张表保存的所有的约束名称信息
这里注意, 列级约束是不能起名字的, 但是有系统默认分配的名字, 只有表级别才可以起名字, 如果不起名字的话, 也会自动分配一个
找到约束的名字我们就可以对约束进行删除, 从而消除对某些字段的约束
首先找到这张表
在这里插入图片描述

使用这个information_schema数据库
在这里插入图片描述
这里面有79张表, 找到这个TABLE_CONSTRAINTS表, 这个表存储的所有的约束对象的信息
在这里插入图片描述
desc查看一下表结构, 我们找到刚才的 t_stu 学生表的约束名称
先用DDL语句查看一下创建 t_stu 这张表时的建表语句
在这里插入图片描述
我们可以看到, 我们创建表的时候对email字段进行了unique约束, 但是没有给约束起名字, 所以系统会自动分配名字
下面我们查看一下这个约束的名称
在这里插入图片描述
这里可以看到这个约束的名称时email

下面我们创建一张新的表, 从新添加一个约束并给约束起名字
基础的语法如下

# 表级约束起名的语法
constraint [约束名称] [表级约束的主体];
# 起约束名的标准
表名_约束的字段_约束的简称(unique/pk/fk)

创建一个班级表进行测试


-- 创建一个班级表(设置班级编号为主键, 班级名称为唯一键)
create table class(
    cno int comment '班级编号',
    cname varchar(255) comment '班级名称',
    constraint class_cno_pk primary key(cno),
    constraint class_cname_unique unique(cname)
);

用上面我们找到约束的名称的流程进行演示…

# 使用一下这个系统库
use information_schema;
# 找到class表的约束名称
select constraint_name from table_constraints where table_name = 'class';

在这里插入图片描述
这里可能会有疑问为什么给主键起的名字没有生效呢?
下面是我查阅的资料

MySQL版本限制:从MySQL8.0版本开始,主键的名字不再可以直接修改。这是由于 MySQL的内部存储引擎(如InnoDB)实现方式导致的,InnoDB存储引擎中主键的名字是以索引的形式存储的,修改主键名字实际上是修改索引的名字,会对存储引擎的内部数据结构产生影响,因此MySQL禁止直接修改主键的名字。

主键约束

主键约束是一个比较重要的内容

  1. 主键 : primary key, 简称pk
  2. 主键约束的字段不能为NULL, 并且不可以重复
  3. 任何一张表都应该有主键(第一范式), 没有主键的表可以被视为无效表
  4. 主键值是这行记录的身份证号,是唯一标识。在数据库表中即使两条数据一模一样,但由于主键值不同,我们也会认为是两条完全的不同的数据。
  5. 主键分类:
    在这里插入图片描述
  6. 单一主键(建议使用这种方式)
create table t_student(
	id bigint primary key,
	sno varchar(255) unique,
	sname varchar(255) not null
)
  1. 联合主键(很少用, 了解)
create table t_user(
	no int,
	name varchar(255),
	age int,
	primary key(no,name)
);
  1. 主键自增
    既然主键值是一个自然的数字,mysql为主键值提供了一种自增机制,不需要我们程序员维护,mysql自动维护该字段键自增
create table t_vip(
	no int primary key auto_increment,
	name varchar(255)
);

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2207242.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【C++】用红黑树模拟实现set与map

目录 一、红黑树的完善: 1、红黑树节点模版的修改: 2、仿函数在模拟实现中的应用: 3、新增迭代器: 4、红黑树中的迭代器实现: 二、set与map的模拟实现: 1、insert: 2、map的[ ]: 三、测…

无刷直流电机工作原理:【图文讲解】

电动机 (俗称马达) 是机械能与电能之间转换装置的通称。可以分为电动机和发电机.一般称电机时就是指电动机。这个在日常应用中,比较多见,比如机器人,手机,电动车等。 直流电机:分为有刷直流电机(BDC&#…

本地ubuntu主机搭建我的世界服务器并免费开启公网映射 结合MESM面板 chmlfrp 保姆级教学

本地ubuntu主机搭建我的世界forge服务器并免费开启公网映射 结合MESM面板 chmlfrp 这是一篇很完成的从ssh命令->配置java环境->安装MCS->部署服务器->开启公网映射的我的世界保姆级开服教程,可以慢慢食用ଘ(੭ˊ꒳ˋ)੭ 。 为什么选择forge服务器进行开服&#x…

【前车之鉴】坑啊~ RestHighLevelClient 超时时间偶尔失效问题解决方案

文章目录 show me code缘起原因分析 几点建议 结论:实际你的配置是生效的,只不过效果不明显而已,通过下面的配置放大直观效果。 show me code 核心代码 public static void main(String[] args) {RestClientBuilder builder RestClient.bu…

【M2TR】M2TR: Multi-modal Multi-scale Transformers for Deepfake Detection

文章目录 M2TR: Multi-modal Multi-scale Transformers for Deepfake Detectionkey points研究贡献方法多尺度变压器频率过滤器跨模态融合损失函数SR-DF数据集实验总结M2TR: Multi-modal Multi-scale Transformers for Deepfake Detection 会议/期刊:ICMR ’22 作者: key …

深入理解栈(Stack)(纯小白进)

目录: 一、栈是什么?1. 栈的概念2.栈的结构选择 二、栈的实现1. 栈结构体的定义2. 栈的初始化3. 栈的销毁4. 入栈5.出栈6. 取栈顶元素7. 栈中元素的个数8. 判断栈是否为空 总结 一、栈是什么? 1. 栈的概念 栈(Stack)…

游戏开发指南:使用 UOS C# 云函数快速构建与部署服务端逻辑实战教学

零基础的服务端小白,现在也可以使用 Unity 结合 C# 来轻松搞定游戏服务端啦! 在本篇文章中,我们将以游戏中的“抽卡”功能为例,展示如何使用 Unity Online Services(UOS)提供的强大 C# 云函数服务&#xf…

Elasticsearch(二)集成Spring Boot 基本的API操作

目录 一、集成Spring Boot 1、创建项目 2、pom文件 查看springboot集成的依赖 3、增加es的config类 二、索引相关API 1、创建索引 2、获取索引,判断其是否存在 3、删除索引 三、文档相关API 1、添加文档 2、获取文档,判断是否存在 3、获取文档…

Java后端面试----某团一面

美团一面 1.介绍一下你的第一个项目 这个就不多说了,主要是根据自己的简历上面的项目进行一个简短的概括使用的技术栈和什么背景解决了什么问题等等。 2.线程安全的类有哪些,平时有使用过哪些,主要解决什么问题 在Java中线程安全的类比如…

对后端返回的日期属性进行格式化(扩展 Spring MVC 的消息转换器)

格式化之前 格式化之后: 解决方式 方式一 在属性中加上注解,对日期进行格式化 JsonFormat(pattern "yyyy-MM-dd HH:mm:ss")private LocalDateTime createTime;//JsonFormat(pattern &quo…

echarts按需引入解决项目大小问题

背景: 按需加载缩减项目大小,提升项目性能和可用性 实现: 创建echarts.js main.js进行配置 页面中引用 效果 全量导入 按需加载:

Chrome清除nslookup解析记录 - 强制http访问 - 如何禁止chrome 强制跳转https

步骤: 地址栏输入 chrome://net-internals/#hsts在Delete domain 栏的输入框中输入要http访问的域名,然后点击“delete”按钮最后在Query domain 栏中搜索刚才输入的域名,点击“query”按钮后如果提示“Not found”即可! 办法来自…

Linux系统:apt upgrade与apt update 命令的作用

一.sudo apt update命令 sudo apt update命令的主要作用是更新本地软件包列表。‌ 它不会下载或安装新的软件包,而是更新本地系统中软件包的列表,以反映远程存储库中的最新可用软件包信息。这确保了软件包管理器(APT)具有最新的软…

第十六周周报:单发的目标检测系列

目录 摘要 Abstract 一、SSD 1.1 模型结构 1.2 代码 二、YOLO 三、Termius 总结 摘要 本周主要学习单阶段的目标检测算法,如SSD、YOLO模型。详细学习了每个模型的原理,以及SSD和YOLO模型之间的异同。在本篇博客中将展示SSD的PyTorch实现代码&am…

Django使用uwsgi和nginx进行手动部署

在Django项目中使用uWSGI和Nginx进行部署是一种常见的生产环境配置。以下是一个详细的步骤指南,帮助你完成这个过程。 前提条件 有一个已经开发好的Django项目。服务器已安装Python、pip、Nginx和uWSGI。有一个有效的域名(可选,但推荐)。 步骤一&#xf…

CPU指令融合技术概述

什么是指令融合? 某些指令,例如add $3,$2,0, 只会使用rd/rs两个字段,但是这条指令却占用了全部32个bit, 这样会使得代码密度不高,指令域的有效利用率不高;这样,在实现某些功能的情况下,会使得CP…

Java创建线程池和线程池的七个核心参数

线程池的工作流程是:当一个任务被提交到线程池时,线程池会根据当前的线程数量和工作队列的状态来决定如何处理这个任务。如果当前运行的线程数量小于corePoolSize,则创建新线程执行任务;如果大于等于corePoolSize,则将…

毕设开源 大数据电影数据分析与可视化系统(源码+论文)

文章目录 0 前言1 项目运行效果2 设计概要3 最后 0 前言 🔥这两年开始毕业设计和毕业答辩的要求和难度不断提升,传统的毕设题目缺少创新和亮点,往往达不到毕业答辩的要求,这两年不断有学弟学妹告诉学长自己做的项目系统达不到老师…

完全免费安卓远程安卓方案:FRP+ADB甲壳虫方案,远程手机不是问题。

引言 在当今这个数字化时代,无论是在个人项目还是商业应用中,能够从公网访问到内网设备的能力变得越来越重要,尤其是安卓终端设备,在必要的情况下,从安卓远程到安卓进行紧急指导救援是未来一种重要的趋势. 通过合理的…

Java - WebSocket

一、WebSocket 1.1、WebSocket概念 WebSocket是一种协议,用于在Web应用程序和服务器之间建立实时、双向的通信连接。它通过一个单一的TCP连接提供了持久化连接,这使得Web应用程序可以更加实时地传递数据。WebSocket协议最初由W3C开发,并于2…