MySQL表的约束

MySQL表的约束

  • 约束的概念
  • 空属性
  • 默认值
  • 列描述
  • zerofill
  • 主键
  • 自增长
  • 唯一键
  • 外键

约束的概念

在正式谈MySQL表的约束之前,我们先来简单理解一下约束这个概念;
约束:意思是指带有束缚、限制、管束等意思;
大白话就是说:规定了那些事情你不能干,那些事情你可以干,那些事情你干了就会出问题,那些事情你干了不会出问题,这也就倒逼我们办事的人只有按照“规则”才能将事情办好,这相对于我们办事的人来说,我们们就不能随心所欲的办事了,时时刻刻都得考虑"规则"来办事,这样的话,我们最后得到的结果一定是规范化、有规律的一组数据!

MySQL表的约束也是如上面所说,MySQL通过限制列的各种属性,从而来保证插入MySQL数据库的数据一定是有规律的、规范的、可预期的,这样的话MySQL的管理成本自然也就没那大,这也是MySQL数据库高效的原因.

空属性

两个值:

  1. null(默认的)和not null,这两组关键字是用来限制当前列,再插入数据时是否允许插入null值!
  2. 数据库列属性的这一字段默认都是null,允许插入null值的!但是在实际开发过程中,竟可能保证字段不为空,因为数据为空,没办法参与运算:
    eg:
    在这里插入图片描述

下面我们用具体的案例来讲解一下:null和not null:
eg:
在这里插入图片描述
现在我们创建另一个表结构,其中classId和className字段我们都带上了not null的限制,也就是说不允许插入null值,接着我们来试试插入正常值:
在这里插入图片描述
然后我们在试着插入一些空值试试:
在这里插入图片描述
我们可以看到无论是classId插入空置或者className插入空值MySQL都会抱一个错误:
ERROR 1048 (23000): Column 'classId' cannot be null这个错误就是在告诉我们当前值不允许插入空值,这也就要求我们要插入一个合法的数据,不能插入null,这也就保证了MySQL数据库里面的插入的数据一定是可预期的、合法的!
当然上面是not null的约束,接着我们来试一试null 的约束,null的约束就是表示当前列允许插入null值,于是我们可以将classID这一列的属性改为null,表示当前列允许插入null值:
在这里插入图片描述
接着我们再来向classId这一列插入null值试一试:
在这里插入图片描述

注意:

  1. 一般情况下,如果我们不显示的指定当前列是否允许插入Null值的话,MySQL会默认允许我们当前列插入null值。验证:
    在这里插入图片描述
  2. 这里我们还有一点需要特别注意,就是not null和null的约束是针对用户执行 “插入操作” 时是否允许插入null!而当用户不对这一列进行插入操作的时候就另外一个约束了!也就是下文的default缺省值!因为not null和null这个约束与default这个约束非常容易混淆!这里我们需要提前了解一下;只要记住not null和null约束是针对用户执行插入操作时起作用的!而default约束是针对用户不执行插入操作的时候起作用的就可以了!

默认值

默认值:也就是当用户不给我们这一列传入数据的时候,所使用的值,与C++的缺省参数类似!
如果用户给我们这一列插入了数据,那么就是用用户插入的数据!
如果用户没有给我们这一列插入数据,那么就用该列的缺省值来进行插入!

eg:
现在我们要建一个程序员交友网站,需要一个数据表来记录用户信息
那么由于程序员男性居多,当用户不输入自己的性别的时候,默认在性别一列插入男;
在这里插入图片描述
现在我们来正常插入:
在这里插入图片描述

现在我们来搞一点容易混淆的东西,我们将sex这一列约束属性设置为not null 和default ‘男’;
在这里插入图片描述
现在sex既有not null属性也有default属性,是不是有一点混淆了
我们只需要永远记住not null和null约束是针对插入操作的是否起效的就行!
default约束是正对用户不执行插入操作的时候起效的就行!
这两者是相互补充的互不干扰的!
eg:

  1. mysql> insert into person (name,sex) values(null,'女'); ERROR 1048 (23000): Column 'name' cannot be null
    我们来解释第一个报错,第一个报错的主要原因就是我们给name列插入了null值,而name列是带上了not null的约束,也就是说明这一列不允许插入null值,因此MySQL直接报错!
  2. insert into person (sex) values('女'); ERROR 1364 (HY000): Field 'name' doesn't have a default value
    这个报错的组要原因是因为我们在插入数据的时候没有给name列插入值,因此name列就会触发default的约束!但是啊,name列没有设置缺省值啊!因此就没有数据来进行插入啊,因此最后就会爆报出没有缺省值的错误,可是这是有读者就有疑问了,desc查person列的是否这个表结构中的default列不是显示name列的默认值为NULL吗?怎么会没有缺省值呢?
    在这里插入图片描述
    怎么说呢,实际上name的default确实是没有缺省值的,它这里写个NULL的意思是表示name没有缺省值的意思,具体的话我们要以创建person表的创建语句为主,可以利用show create table person来查看:
    在这里插入图片描述
    很明显创建语句中并没有为name列带上缺省值,因此这里会出现没有缺省值的错误!!
  3. mysql> insert into person (name) values(null); ERROR 1048 (23000): Column 'name' cannot be null
    这一列出现错误的主要原因就是我们再给name列插入数据的时候,插入了null值,这是不被允许的因为,name字段带上了not null约束!与此同时这一次插入中我们忽略了sex这一列数据的插入,那么就会触发default缺省值的约束,因此sex这一列的插入最终是由sex的缺省值来完成的,这一点没问题!

总结:

  1. 只要记住not null和null约束是针对用户执行插入操作时起作用的!而default约束是针对用户不执行插入操作的时候起作用的就可以了!
  2. 当用户将某一列设置为not null的话,MySQL不会为该列带默认上缺省值!
  3. 如果用户讲某一列设置为 null的话 ,MySQL是会为该列默认带上缺省值的!缺省值给的就是NULL,所以说一旦desc查表查出来的时候发现default列的值为NULL,我们并不能确定这个NULL是真的表示没有缺省值的意思,还是表示有缺省值只不过这个缺省值为NULL,为此我们需要通过查看当前表结构时的创建语句来判断!

列描述

列描述:comment,没有实际含义,专门用来描述字段,会根据表创建语句保存,用来给程序员或DBA来进行了解。
这个就相当于C/C++中的注释,是用来给数据库管理员看到,相当于是一种软性约束,告诉数据库管理员应该插入那种规则的值,如果用户非要插入不合法的值,那么MySQL数据库方面也没有办法阻拦,比较comment只是一种提示,不能硬性拦截!

在这里插入图片描述

细节:
在MySQL中单引号也可以用来引用一个字符串,双引号也可以!

zerofill

如果学过C语言的格式化打印,那么这个zerofill就非常好理解;
zerofill通常都是用来约束整数类型的!

在这里插入图片描述

就比如上图:我们知道char括号里面的数字表示这个char类型的大小!
float(m,n)中的m和n分别表示指定长度和精度;
那么int(num) 中这个num是什么意思?
是表示num个字节吗?那么上图中的int(11)是表示int占11个字节吗?显然不是!
实际上整型括号后面的数字表示的是这个字段输出必须是num位;
就比如上图中的int(11)就表示id字段的输出必须以11位的方式来进行输出;
那如果实际位数不足11位呢?
就比如123,很明显不够11位啊!怎么能按造11位输出?
针对不满规定位数的数字MySQL会用空格将其补到11位在输出,就比如:
123 会被MySQL不成 123然后进行输出!
位数刚好够就不说了,直接进行输出!
那么如果位数要是超过规定位数?
直接原样输出就好了,这时候就无视这个输出位数的限制了!
比如:int (3) ,现在我有一个12345要输出,很明显12345的实际位数已经超过了规定的3位标准,那么MySQL直接输出就好了!
eg:
在这里插入图片描述在这里插入图片描述
什么?你说补空格不好看?想要补0?
安排!zerofill闪亮登场,我们将id的属性改一下:
在这里插入图片描述

int 默认以11作为输出位数,因为int的最大长度是需要11位来表示(INT_MIN)
unsigned int 默认以10作为输出位数,因此unsigned int的做大长度就是10位;

主键

主键:primary key用来唯一的约束该字段里面的数据,不能重复,不能为空,一张表中最多只能有一个主键;主键所在的列通常是整数类型,当然也可以为其它类型!
就比如说一个表中有很多条数据,为了确保能够辨识不同的数据,我们需要用某一列或者多列共同组成一条数据的唯一标识,通过这个唯一标识我们可以快速定位指定数据!

eg:
创建表的时候直接在字段上指定主键:
在这里插入图片描述
使用primary key来指定主键
插入数据:
在这里插入图片描述
主键约束:主键对应的字段中不能重复,一旦重复,操作失败:
在这里插入图片描述
一旦某个字段被设为了主键,那么这个字段也就不能被插入null值,也就是not null约束,那么自然也就不能使用缺省值插入:
在这里插入图片描述
当表创建好以后但是没有主键的时候,可以再次追加主键(但是这是否必须保证你要设置为主键的那一列没有冲突值):
在这里插入图片描述
如果这个表中有数据,并且要被设置为主键的那一列还有重复数据,那么主键会设置失败:
alter table tablename drop primary key;取消主键属性!
在这里插入图片描述
复合主键
在创建表的时候,在所有字段之后,使用primary key(主键字段列表)来创建主键,如果有多个字段
作为主键,可以使用复合主键。这并不违背一个表中只有一个主键的原则,主键可以是单一的一列作为主键,也可以是多列合起来作为一个主键!
在这里插入图片描述

自增长

auto_increment:当对应的字段,不给值,会自动的被系统触发,系统会从当前字段中已经有的最大值+1操作,得到一个新的不同的值。通常和主键搭配使用,作为逻辑主键。(但是实际再测的时候在MySQL中auto_increment只能给主键使用)
自增长的特点:

  1. 任何一个字段要做自增长,前提是本身是一个索引(key一栏有值)
  2. 自增长字段必须是整数(auto_increment默认从1开始biaojiegou1)
  3. 一张表最多只能有一个自增长

eg:
在这里插入图片描述
插入数据:
在这里插入图片描述

在插入后获取上次插入的 AUTO_INCREMENT 的值(批量插入获取的是第一个值
在这里插入图片描述

注意:
auto_increment与default的功能有点像,都是在用户不输入的时候使用默认值,这也就注定了auto_incremen与default是水火不容的!
一个列有了default属性就不能有auto_increment属性;有了auto_increment就不能有default!

唯一键

一张表中有往往有很多字段需要唯一性,数据不能重复,但是一张表中只能有一个主键:唯一键就可以解决表中有多个字段需要唯一性约束的问题。
唯一键的本质和主键差不多,唯一键允许为空,而且可以多个为空,空字段不做唯一性比较。
关于唯一键和主键的区别:
我们可以简单理解成,主键更多的是标识唯一性的。而唯一键更多的是保证在业务上,不要和别的信息出现重复。乍一听好像没啥区别,我们举一个例子
就比如生活中:
一个学生:有身份证号、姓名、性别、学号、手机号、qq号、家庭住址吧!
如果我们学校要构建一个表结构把这些学生的基本信息管理起来的话,那么可以采用学号来充当该表的主键吧,因为学号肯定是唯一的(别杠为什么不用身份证号…),这样的话我们在插入数据的时候不可能插入两个学号的相同数据,可是有没有可能我们插入数据时失误了,确实是插入了两条学号不一样的数据,但是这两条数据的身份证号却相同、qq号、手机号也相同,这样在数据库层面是没办法识别的,数据库会直接让我们进行插入,但是站在实际的角度这是不合理的!在现实中不可能有两个身份证一样的人、也不可能有两个手机号一样的人、也不可能有两个qq号一样的人!为此,我们在设计数据库时除了要保证主键的列的唯一性,也要保证其它列的合法性!当出现主键列不同,但其它身份证一列相同的情况我们需要在数据库层面做出拒绝!
这样才能保证插入数据库中的信息的合法性,符合实际需要;
这不唯一键的概念不就出来了:

eg:
设计一个带有唯一键的表:
在这里插入图片描述
插入数据:
在这里插入图片描述
上面的都是正常插入,接下来我们来试一试各种错误插入:
在这里插入图片描述
有了唯一键我们就能保证插入数据库中的合法性和显示性了!

注意:
唯一键如果不设置not null的话是可以插入null值的,null值不参与运算:
在这里插入图片描述

外键

语法:
foreign key (字段名) references 主表(列)
外键用于定义主表和从表之间的关系:外键约束主要定义在从表上,主表则必须是有主键约束或唯一键约束。当定义外键后,要求外键列数据必须在主表的主键列存在或为null。
举个例子:
在这里插入图片描述
现在上面两张独立表结构,表中已经存在了一定的数据;
好,现在假设来了一个新同学,这个新同学的信息如下(102,“王五”,10);
然后的话我们就要把这个同学的信息保存进学生表中这个没问题,
好,现在又来了一个同学,这个同学的信息如下(103,“赵六”,30)
然后我们也按照流程将这个同学的信息插入进学生表中,可是不对啊,这个学生所属班级是30班,我们这个学校里面没有30班啊!我们学校只有10班、20班啊!这个学生的信息有误啊,我们不应该将这个学生的信息插入进学生表啊!当我们将这名学生的信息插入进学身表的是否数据库应该报错啊!可是实际上数据库允许你插入,并且什么也不告诉你,这就有点扯了!
然后现在又来了一个同学,这个同学的基本信息如下(104,“田七”,null),这个同学是我们学校的但是还暂时未给他分配班级,所以班级一栏暂时为null,因此我们按照流程将数据插入进学生表中,这没问题!
可是啊某一天这个学校快不行了,办的不咋样,于是他就像关闭一个班级!就比如20班吧!于是他就去学校的班级表数据库里面哐呲哐呲删除了班级号为20的班级的所有信息,可是某一天新老师在维护学生表数据库的是否发现李四同学属于我们学校的20班,可是这个新老师会认为我们学校没有20班啊,是不是录学生信息的时候把学生信息录错了,于是它哐呲哐呲的就将李四同学的基本信息从学生表中删除了,这就导致李四同学一下成为的学校黑户!而我们可怜的李四同学什么也没做,无缘无故就成了黑户…这不扯吗!要是当初那个在班级表中删除20号班级的人能够检查一下学生表中是否还有20号班级的学生的话就不会出现这种情况了;
实际上说白了,还是审核的问题,要是在向学生表中添加数据时考虑一下班级表,而删除班级表中的数据时考虑一下生表,就不会出现上面所说的问题了!

而外键约束的出现就是来帮我们自动审核这一关系的!
想要形成外键约束,那么就必须在多个表之间找到公共的字段,也就是能够将多张表联系起来的字段,这个公共字段在主表中必须时唯一的(可以是主键、也可以时唯一键),在从表中可以不是唯一的,像以上这样在从表中的公共字段就叫做外键!而这多个表之间的联系和束缚就叫做外键约束!
从表中的外键数据在插入时会先考虑在主表中该外键数据是否存在;
而主表在删除数据时,也会考虑从表中是否还存在要删除的外键数据!

以上面的例子为例:
学生表和班级表的公共字段就是班级号,因此再根据实际应用场景,可以考虑将班级表设计为主表,学生表设计为从表:
在这里插入图片描述
现在分别向两张表里面插入一点数据:
在这里插入图片描述
现在我我们再在学生表中插入一个(103,“王五”,20)的数据:
在这里插入图片描述
插入成功…
接着插入一个(104,“赵六”,40)的学生信息:
在这里插入图片描述
直接报错!
再插入一个(105,“田七”,null)的学生信息:
在这里插入图片描述
插入成功!
现在我们再来班级表中删除一下30号班级:
在这里插入图片描述
报错!
那如果我先在学生表中将30班的学生的数据全部删光呢?
在这里插入图片描述

如何理解外键约束:
首先我们承认,这个世界是数据很多都是相关性的。
理论上,上面的例子,我们不创建外键约束,就正常建立学生表,以及班级表,该有的字段我们都有。
此时,在实际使用的时候,可能会出现什么问题?
有没有可能插入的学生信息中有具体的班级,但是该班级却没有在班级表中?
比如新东方只开了新东方100班,新东方101班,但是在上课的学生里面竟然有新东方102班的学生(这个班目前并不存在),这很明显是有问题的。
因为此时两张表在业务上是有相关性的,但是在业务上没有建立约束关系,那么就可能出现问题。
解决方案就是通过外键完成的。建立外键的本质其实就是把相关性交给mysql去审核了,提前告诉mysql表之间的约束关系,那么当用户插入不符合业务逻辑的数据的时候,mysql不允许你插入;

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

如何大幅提高遥感影像分辨率(Python+MATLAB)

前言: 算法:NSCT算法(非下采样变换) 数据:Landsat8 OLI 遥感图像数据 编程平台:MATLABPython 论文参考:毛克.一种快速的全色和多光谱图像融合算法[J].测绘科学,2016,41(01):151-15398.DOI:10.1…

k8s deployment创建pod流程图

参考 k8s 创建pod和deployment的流程 - SoulChild随笔记

TCP的可靠性之道:确认重传和流量控制

TCP 全称为 Transmission Control Protocol(传输控制协议),是一种面向连接的、可靠的、基于字节流的传输层通信协议,其中可靠性是相对于其他传输协议的优势点。TCP 为了确保数据传输的可靠性主要做了以下几点: 发送确…

【vue3+ts项目】配置husky+配置commitlint

上一篇文章中配置了eslint校验代码工具 【vue3ts项目】配置eslint校验代码工具,eslintprettierstylelint 1、配置husky 每次手动执行命令才能格式化代码,如果有人没有格式化就提交到远程仓库,这个规范就起不到作用了,所有需要强…

Java日志框架概览

SLF4J 提供统一的日志门面API,即图中紫色部分,实现中立的日志记录API 桥接功能,蓝色部分,把各种日志框架API(绿色部分)桥接到SLF4J API。这样即便你的程序中使用各种日志API记录日志,最终都可桥…

带你了解SpringBoot---开启Durid 监控

文章目录 数据库操作--开启Durid 监控整合Druid 到Spring-Boot官方文档基本介绍Durid 基本使用代码实现 Durid 监控功能-SQL 监控需求:SQL 监控数据SQL 监控数据-测试页面 Durid 监控功能-Web 关联监控需求:Web 关联监控配置-Web 应用、URI 监控重启项目 Durid 监控功能-SQL 防…

进程调度和进程切换——《王道考研》

一、王道书咋说 二、chatgpt咋说 进程调度和进程切换是多道程序操作系统中两个关键的概念,它们在处理多个进程时起着不同的作用。 2.1进程调度是指: 操作系统根据一定的调度算法,从就绪态的进程队列中选择一个进程来占用CPU资源&#xff0…

最新消息:谷歌将在Chromebook上运用UWB技术,无线通信更上一层

超宽带(UWB)技术是一种创新的短距离无线通信技术,具有高速数据传输和精确定位物体位置的优势。尽管该技术已经存在一段时间,但最近开始广泛应用于各种设备中。据最新报道,Pixel Watch 2可能会搭载UWB模块,这…

商城-学习整理-高级-性能压测缓存问题(十一)

目录 一、基本介绍1、性能指标2、JMeter1、JMeter 安装2、JMeter 压测示例1、添加线程组2、添加 HTTP 请求3、添加监听器4、启动压测&查看分析结果 3、JMeter Address Already in use 错误解决 二、性能监控1、jvm 内存模型2、堆3、jconsole 与 jvisualvm1、jvisualvm 能干…

20230822 Windows上使用find_package引入OpenCV报错

报错信息 打开Cmake项目时,find_package 报错: Found OpenCV Windows Pack but it has no binaries compatible with yourconfiguration.You should manually point CMake variable OpenCV_DIR to your build of OpenCVlibrary.原因 大概率原项目是在 …

发布完体验版以后,出现接口调用失败,但是在本地开发环境中可以正常访问的情况,解决办法

1.一般解决办法 通过打开微信小程序调试模式 进行调用,但这会有些许问题,出现vConsole按钮**,影响美观** 如图所示: 1.1.进入小程序 点击右上角的3个点儿 1.2.点击开发调试 1.3.点击打开调试 1.4.显示出vconsole按钮&#xf…

Fastadmin框架 聚合数字生活抵扣卡系统v2.8.6

【2.8.6更新公告】 1.【优化】优化已知问题。 2.【新增 】新增区县影院。

Docker入门

1. 什么是docker docker的英文意思是 码头工人,意思就是搬运东西的意思,其实这和docker的特点是一样的,docker提供的就是一种容器化搬运东西(我们的软件、程序)的过程。docker自己本来是运行在操作系统上一个程序软件…

软考高级系统架构设计师(二)计算机操作系统

【原文链接】软考高级系统架构设计师(二)计算机操作系统 2.1 进程管理 2.1.1 操作系统的三个重要作用 管理计算机中运行的程序和分配各种软硬件资源为用户提供友善的人机界面为应用程序的开发和运行提供一个高效的平台 2.1.2 操作系统的四个特征 并…

jmeter HTTP请求默认值

首先,打开JMeter并创建一个新的测试计划。 右键单击测试计划,选择"添加" > “配置元件” > “HTTP请求默认值”。 在HTTP请求默认值中,您可以设置全局的HTTP请求属性,例如: 服务器地址&#xff1a…

加速乐(__jsl_clearance_s)动态cookie生成分析实战

文章目录 一、写在前面二、抓包分析三、逆向分析 一、写在前面 加速乐(JSL)是阿里推出的一项反爬虫服务,其生成cookie的原理基于浏览器的行为特征 我们知道普通网站生成cookie是在请求时生成,而它先生成cookie,然后向服…

allegro输出.IPC文件

1、ipc文件的导出 板厂会使用cam软件生产一个网表文件;如果传递给板厂的数据中也有一个IPC文件,板厂将对两个网表文件进行对比;提高生产的安全性,准确性; 1,PCB软件输出的光绘文件,有时会变异&a…

JUC--线程池

目录 一、线程池的介绍 二、线程池的创建 三、特殊线程池 3.1.CompletionService异步处理 3.2.ThreadPoolExecutor 3.3 ForkJoinPool 虽然多线程的技术大大帮助了程序运行的效率,但是在太多的线程的创建与销毁下,系统的开销也将会是非常庞大的。所以…

stack和queue的模拟实现

stack和queue的模拟实现 容器适配器什么是适配器STL标准库中stack和queue的底层结构deque的简单介绍deque的缺陷 stack模拟实现queue模拟实现priority_queuepriority_queue的使用priority_queue的模拟实现 容器适配器 什么是适配器 适配器是一种设计模式(设计模式是一套被反复…

Python土力学与基础工程计算.PDF-隧道涌水量

Python 求解代码如下: 1. # 定义参数 2. A 2000 # 地表面积,单位:平方米 3. S 10 # 截面积,单位:平方米 4. h 500 # 年地下径流深度,单位:毫米 5. 6. # 转换单位 7. h h / 1000 # 单…