给数据“立规矩” —— MySQL 新手必学的表约束全指南

给数据“立规矩” —— MySQL 新手必学的表约束全指南

                🔥海棠蚀omo个人主页

                ❄️个人专栏《初识数据结构》《C++:从入门到实践》《Linux:从零基础到实践》《Linux网络:从不懂到不会》《MySQL:新手入门指南》

                ✨追光的人,终会光芒万丈

博主简介:

目录

一.为什么要有表的约束?

二.表的约束

2.1空属性

2.2默认值

2.3列描述

2.4zerofill

2.5主键

2.5.1复合主键

2.6自增长

2.7唯一键

5.8外键

前言:



在上一篇文章中我们讲解了MySQL中的各种数据类型,那么正是因为有了各种数据类型,才会有今天我们要讲的表的约束相关知识,那么这中间到底是怎么回事呢?下面我们就一起来看看吧。

一.为什么要有表的约束?

在上一篇文章中,我们认识了很多的数据类型,并在它们的下面我们也通过例子进行了演示,而在这些例子中我们不乏向表中插入一些不合法,或者说超出范围的数据。

而结果我们当时也看到了,MySQL是会拦截我们的,那么MySQL为什么会拦截我们呢?

答案就是我们要插入的数据是不符合当前数据类型的,那么换句话说数据类型在无形中对我们程序员就形成了一种" 约束 ",只要插入的数据不在" 约束 "之内,那么MySQL就会进行拦截。

所以我们就可以回答上面的问题了:为什么要有表的约束?



答案就是通过约束,可以保证我们未来插入数据库表中的数据是符合预期的。而约束的本质就是通过技术手段,倒逼程序员插入正确的数据。



那么反过来,站在MySQL的角度,凡是插入进来的数据,都是符合数据约束的!!!

二.表的约束

那么上面在介绍了为什么要有表的约束之后,我们也要知道:单单只通过数据类型来进行" 约束 "是不够的,还需要有更多的约束条件。

所以下面我们就来讲解一些常见的约束条件。

2.1空属性

一般有两个值:null(默认的)和not null(不为空)

与之相关的其实就是我们使用desc指令查看表的属性中Null这一列,默认情况下这一列的内容都是:YES,表示的就是这一行所对应的那个属性数据可以为空。

那么怎么让一个属性的数据不能为空,即not null,并且设置为not null后又有什么表现呢?下面我们通过一个例子来演示:

我们这里创建一个表,在表的属性后面加上not null就可以将该属性设置为not null(不为空),并且我们再次通过desc指令来查看表的属性,可以看到Null这一列的内容就不再是YES,而是NO,即该属性对应的数据不能为null。

那么下面我们就来验证一下:

那么当我们向其中添加数据的时候可以看到,如果我们想要插入的数据是NULL,也就是为空,那么MySQL是会拦截我们的,并且报的错误说明的也很明显:name,id这一列不能为空。

2.2默认值

默认值:某一种数据会经常性的出现某个具体的值,可以在一开始就指定好,在需要真实数据的时候,用户可以选择性地使用默认值。

这个默认值我们其实就可以将其认为是C++语法中缺省值,当我们没有传入该参数的实参时,就会使用我们在声明或者定义时所设定的缺省值,对于这点相信大家都能理解。

而默认值这一选项在表的属性中也是出现的了,我们来看:

Default这一列表示的就是默认值,可以看到再上一个我们创建的表中,name和id属性都没有设置默认值,所以这一列的内容全部都是NULL。

那么下面我们通过一个例子来看看默认值是怎么设置的以及设置之后又有什么表现:

那么这里我们创建了一张表,设置默认值的方法就是在属性后面加上:default + 默认值,通过这种方式我们就能够设置默认值。

那么下面我们插入一些数据来看一下:

在上面我们插入了不同的数据,有的属性我们在插入时并没有显示的传入,但是从结果来看我们也成功地插入了数据,并且那些没有显示插入的数据,用的就是我们在创建表的时候设置的默认值。

而在上面我们其实也看到了最后一个属性number我们在设置的时候用的是:not null default 123456,那么这里可能有人就有疑问了:not null和default这两个不冲突吗?



其实是不冲突的,反而它们两个是互补的,这里我们既要说一下它们两者之间的区别:not null的前提是向表中插入数据,但是插入的数据不能为空,而default是不向表中插入数据,那么才会使用default。



并且MySQL是支持我们上面的那种写法的,即not null + default,这种写法就是如果要插入数据,那么插入的数据不能为空,如果不插入数据,那么就使用默认值。

那么下面我们针对这种特殊的写法与单独的not null比较一下来看看区别:

第一条我们插入的数据就是来检测number属性的not null,可以看到是没有问题的,我们是无法传入NULL的。

第二条我们插入数据时并没有打算插入name属性的内容,可以看到报的错误变成了name属性没有默认值,而不是name属性的内容不能为空。

所以通过第二个例子我们其实就证明了not null和default二者是不冲突的,并且是互相补充的。

2.3列描述

列描述:comment,没有实际含义,专门用来描述字段,会根据表创建语句保存,用来给程序员或DBA来进行了解。

这个列描述其实我们在之前就已经见过了,下面我们再来回忆一下:

就是我们在创建表的时候后面加的comment,通过comment描述,我们其实就能知道所对应的属性是干什么的。

并且通过desc指令我们是看不到属性所对应的comment描述的,那么我们要想看到该怎么做呢?我们来看:

我们可以通过show指令来查看一个表被创建的相关语句,那么在上图我们就可以看到每个属性的comment描述。

但是经过我们上面的描述也可以发现列描述并没有像not null,default那种不满足条件时MySQL会拦截我们报错的情况,而只是给程序员描述该属性是什么含义。

2.4zerofill

zerofill其实跟我们上一篇文章讲解数据类型有些关系,我们先来看一种现象:

当我们通过show指令再次查看创建表时的信息的时候,我们可以看到int类型的后面跟了一个(10),那么这个10代表什么意思呢?

那么要想知道这个问题的答案,我们就需要来介绍一下zerofill关键字。

首先我们先更改一下a属性的类型,在其后面加上zerofill关键字,目前我们还看不到有什么区别,下面我们向其中插入一些数据再来看看:

那么当我们向里面插入一些数据后,查看表中的数据,可以发现a的数据从123变为了0000000123,下面的1234也是如此。

出现这种现象的原因正是因为zerofill起作用了,int后面括号中的10,表示的是宽度为10,而zerofill的作用就是:如果插入的数据宽度小于10,那么就会在前面的空位上自动补0。

对于这点我们要注意,这只是最后显示的结果,实际在MySQL中存储的依旧是123和1234,所以我们不必担心使用zerofill后实际存储的值会发生变化。

那么这里就会有一个问题了:如果插入的数据宽度超过了int后面括号中的数字呢?



那么对于这个问题,我们下面再通过一个例子来观察:







那么在上面我们手动修改a属性的类型,将其int后面括号内的数字改为4,那么下面我们再向其中插入一些数据看看:







从结果中我们可以看到当我们插入的数据的宽度>=int括号中的数字的时候,就不再自动补0了,此时就和我们不加zerofill是一样的效果了。

那么相信大家心中还会有一个疑惑:为什么int类型括号后面的数字默认是10呢?

我们只要思考int类型的范围是多少其实答案就已经出来了,即-2的31次方到2的31次方-1,也就是-21亿~21亿,那么21亿这个数字的宽度是多少呢?

答案就是10位,这个10对应的正是int括号中的10,所以此时我们就能理解这个10是怎么来的了。

最后补充一点,在上面我们设置a和b的类型的时候,我们在后面加上了unsigned,所以int后面括号中的数字是10,如果我们把unsigned去掉,那么括号中的数字将会变为11。

原因就是加上unsigned表示无符号,而去掉unsigned后将变为有符号,所以会多个符号位,也就从10变为了11。

2.5主键

主键:primary key用来唯一的约束该字段里面的数据,不能重复,不能为空,一张表中最多只能有一个主键;主键所在的列通常是整数类型。

那么下面我们直接通过一个例子来看一看主键是如何进行设置的以及设置之后会有什么效果:

设置的方式很简单,在属性的后面加上:primary key即可将该属性设置为主键,并且我们通过desc指令查看表的属性,可以看到id属性在设置了主键后,就不能再为空了。

那么下面我们向其中插入一些数据来看看:

从上面的结果中我们可以看到当我们想要插入相同id的数据的时候,MySQL就会拦截我们了,因为主键属性是不能重复的!!!

那么如果我们创建表的时候并没有设置主键,在后面要想将表中的某个属性设置为主键该怎么做呢?我们来看:

这里我们创建一张表,通过desc指令我们可以看到此时的表中没有主键属性,那么下面我们就来将id属性设置为主键:

要想完成这个操作我们就要用到alter指令,并且后面要使用add,表示要向表中添加一个主键,在括号中填入我们要设置的属性。

通过这个指令我们就可以成功地将id属性设置为了主键,那么既然我们能够添加主键,未来我们要想将主键从我们的表中剔除掉呢?或者说如何删除主键呢?

同样是通过alter指令,不过后面的add要变为drop,通过这个指令我们就可以成功删除一个表中的主键。

2.5.1复合主键

那么在主键这一块我们再补充一点知识,那么就是复合主键,那么复合主键是什么意思呢?

复合主键就是在创建表的时候,在所有字段之后,使用primary key(主键字段)来创建主键,如果有多个字段作为主键,可以使用复合主键。

那么不废话,下面我们直接通过例子来看一看:

那么设置复合主键的方式就是在创建表的最后加上:primary key(属性名),在上面我们就将id和course属性一同设置为了主键,那么下面我们来插入一些数据来观察一下:

看了上面的结果,相信大家心中都会有疑惑:在上面的例子中,id重复了,course也重复了,但是却都能成功插入数据,主键不是不能重复吗?

答案就是如果设置了复合主键,那么只有当全部属性都重复了才会触发主键不能重复的机制,那时MySQL才会去拦截我们,从上图我们也能看到确实是如此。

那么对于复合主键相信大家还有一个最大的问题:主键不是只能有一个吗,怎么还能将多个属性设置为主键呢?



答案就是确实主键只能有一个,但是谁说主键所指向的属性只能有一个了?

2.6自增长

auto_increment:当对应的字段,不给值,会自动地被系统触发,系统就会从当前字段中已经有的最大值+1操作,得到一个新的不同的值。通常和主键搭配使用,作为逻辑主键。

那么下面在演示之前我们先了解一下auto_increment的特点:

1.任何一个字段要做自增长,前提是本身是一个索引(key一栏有值)



2.自增长字段必须是整数



3.一张表最多只能有一个自增长

那么在上面知道了auto_increment的特点后,下面我们就直接来通过一个例子来看看它该怎么是使用:

在上面我们在创建表的时候,就将id属性设置为主键,并在其后面加上了auto_increment。而下面我们通过desc指令来查看表的属性的时候,可以看到在id属性后面的Extra一栏中多了auto_increment。

那么下面我们就向其中插入一些数据来看看效果:

从上图可以看到,我们只向表中插入了name这一列的数据,但是从结果来看,id这一列不仅有数据,而且还进行了自动+1的操作,可以看到我们插入了五个数据,id也是从1到5。

那么这个时候我们就有疑问了:那我要是主动插入id这一列的数据呢?下面我们就来试一试:

当我们手动插入了一个id数据1000后,后面我们依旧只传name属性的值,但是从上图中我们可以看到后面我们再插入值,就不再从6开始了,而是从1001开始,那么自增长的起始数据到底该怎么查看呢?

我们通过show指令就可以知道答案,可以看到在上图中AUTO_INCREMENT=1004,这就是答案,下个id属性的值就是1004,就是根据这个信息来获取的。

2.7唯一键

一张表中往往有很多字段都需要唯一性,数据不能重复,但是一张表中只能有一个主键,所以我们该如果保证其他字段的唯一性呢?

答案就是通过唯一键,唯一键和主键差不多,但是唯一键允许为空,而且可以多个为空,空字段不做唯一性比较 。

那么下面我就通过一个例子来带大家理解何为唯一键:

在上面创建的表中,我们将telephone属性设置为了唯一键,因为每个人的电话号码都是不一样的,所以我们要维护telephone的唯一性。

那么下面我们就向其中插入一些数据来观察一下:

在上图中我们向表中插入了几组数据,可以看到telephone属性在设置为唯一键后,确实不能重复,并且也确实可以为空,为空不做唯一性判断也是证明了的。

5.8外键

我们要知道MySQL是关系型数据库,那么这个关系体现在哪儿呢?

答案就是体现在表与表之间的关系,而用于表与表之间关系的就有我们要讲的外键,那么什么叫做外键呢?

外键用于定义主表和从表之间的关系:外键约束主要定义在从表上,主表则必须是有主键约束或unique约束。当定义外键后,要求外键列数据必须在主表的主键列存在或为null。

这么说可能不太好理解,下面我们来看一张图:

在上图中有两张表,第一张学生表中的class_id和第二张班级表中的id指的都是同一个内容,那么stu和myclass这两张表就有外键关系了,并且班级表是主表,学生表是从表。

但是只有外键关系是完全不够的,只有外键之名,并没有外键之实,也就是没有外键约束,举个很简单的例子:如果我们向学生表中插入了一组数据,class_id是30,那不就出问题了吗?

就没有id为30这个班级,又怎么会有这个学生呢?

所以为了维持这种合理的外键关系,需要我们通过外键约束来进行实现,那么该如何做呢?

对应的语法就如上图所示,那么下面我们就根据上面的例子来演示一下:

那么在上面我们创建了这两张表,并建立了外键约束,那么下面我们就向表中插入一些数据看看:

可以看到,当双方的信息保持一致的时候,是可以正常插入数据的,那下面我们就来试一试外键约束到底行不行:

从结果可以看到当我们插入的数据class_id超出了范围之后,MySQL就开始拦截我们了,就没有教室名为3和4的,哪儿会有王五和赵六这两个学生呢?

并且我们此时如果想要删除myclass表中id为1的这一列数据是不行的,MySQL依旧会拦截我们,因为教室id为1的还有学生呢。

我们如果想要删除的话就要先把student表中class_id为1的数据先删除完了,才能够删除myclass表中id为1的信息。

所以外键约束其实并不只是主表对从表的约束,而是双方互相约束:主表约束从表不能无中生有,而从表约束主表不能" 始乱终弃 "!!!

以上就是给数据“立规矩” —— MySQL 新手必学的表约束全指南的全部内容。

Read more

零代码上手!用 Rokid 灵珠平台,5 步搭建专属旅游 AR 智能体

零代码上手!用 Rokid 灵珠平台,5 步搭建专属旅游 AR 智能体

零代码上手!用 Rokid 灵珠平台,5 步搭建专属旅游 AR 智能体 灵珠平台简介 okid 自研 AI 开发平台,基于多模态大模型与轻量化架构,打造零门槛、全栈化 AI 开发体系。平台提供可视化编排、预置能力组件,支持原型到云端、端侧一站式敏捷部署,并深度适配 Rokid Glasses 智能眼镜,通过专属硬件接口与低功耗优化,实现 AI 应用高效端侧落地,助力开发者快速打造视觉识别、语音交互等穿戴式 AI 应用,拓展 AI + 物理世界的交互边界可视化编排工具,拖拽式快速搭建应用预置丰富能力组件库,涵盖对话引擎、视觉识别等核心模块支持从原型设计到云端、端侧的一站式敏捷部署提供设备专属适配接口,实现硬件深度协同搭载低功耗运行优化方案,保障端侧持久稳定运行 实战:搭建旅游类AR智能体 1、进入灵珠平台 登录灵珠平台后,你将看到简洁直观的工作台界面 点击创建智能体按钮,

By Ne0inhk
【CANN】Pi0机器人大模型 × 昇腾A2 测评

【CANN】Pi0机器人大模型 × 昇腾A2 测评

【CANN】Pi0机器人大模型 × 昇腾A2 测评 * 写在最前面 🌈你好呀!我是 是Yu欸🚀 感谢你的陪伴与支持~ 欢迎添加文末好友🌌 在所有感兴趣的领域扩展知识,不定期掉落福利资讯(*^▽^*) 写在最前面 版权声明:本文为原创,遵循 CC 4.0 BY-SA 协议。转载请注明出处。 Pi0机器人VLA大模型测评 哈喽大家好呀!我是 是Yu欸。 最近人形机器人和具身智能真的太火了,大家都在聊 Pi0、聊 VLA 大模型。但是,兄弟们,不管是搞科研还是做落地,咱们始终绕不开一个问题——算力。 今天,我们一起把当下最火的 Pi0 机器人视觉-语言-动作大模型,完完整整地部署在国产算力平台上,也就是华为的昇腾 Atlas 800I A2 服务器上。 在跑通仓库模型的基础上,我们做一次性能测评。 我们要测三个最核心的指标:

By Ne0inhk

OpenClaw实战系列01:OpenClaw接入飞书机器人全接入指南 + Ollama本地大模型

文章目录 * 引言 * 第一步:环境准备与核心思想 * 第二步:部署Ollama——把大模型“养”在本地 * 1. 安装 Ollama * 2. 拉取并运行模型 * 3. 确认API可用性 * 第三步:安装OpenClaw——AI大脑的“躯干” * 1. 安装Node.js * 2. 一键安装 OpenClaw * 3. 验证安装 * 第四步:打通飞书——创建并配置机器人 * 1. 创建飞书应用 * 2. 配置机器人能力 * 3. 发布应用 * 第五步:OpenClaw与飞书“握手” * 方法一:使用 onboard 向导重新配置(推荐最新版) * 方法二:手动添加渠道 * 批准配对 * 第六步:实战测试与玩法拓展

By Ne0inhk