[MySQL] MySQL表的约束

  在前面的文章中提到了约束,是通过数据类型对字段产生的约束。但是数据类型约束很单一,需要有一些额外的约束,更好的保证数据的合法性,从业务逻辑角度保证数据的正确性。于是就引入了表的约束。

  表的约束很多,这里主要介绍如下几个:null/not null、default、comment、zerofill、primary key、auto_increment、unique key、foreign key。

文章目录

一、空属性

二、默认值

三、列描述

四、zerofill

五、主键

六、自增长

七、唯一键

八、外键

九、综合练习


🙋‍♂️ 作者:@Ggggggtm 🙋‍♂️

👀 专栏:MySQL 👀

💥 标题:MySQL表的约束💥

 ❣️ 寄语:与其忙着诉苦,不如低头赶路,奋路前行,终将遇到一番好风景 ❣️

一、空属性

  在MySQL中,空属性约束指定了某一列是否可以包含NULL值。它们用于各种目的,例如数据验证和限制数据的输入格式。以下是空属性约束的详细解释:

  1. NOT NULL: 当使用NOT NULL属性约束时,将禁止该列包含NULL值。这意味着在插入或更新数据时,该列必须包含有效的数值或字符,不能为NULL。
  2. NULL: 如果没有显式地指定NULL或NOT NULL属性约束,那么默认情况下,列可以包含NULL值。这意味着在插入或更新数据时,如果没有提供有效的值,可以将该列的值设置为NULL。

  我们再通过具体的实例来理解一下空属性的使用和其意义。具体如下图:

  如上图所示,我们把id 和 name 均设置了 not null(不为空)。其中并没有对high设置,默认就是可以为空的。我们再插入数据进行查看,如下:

  从上图中可以看到,当对字段设置了不能为空时,插入的时候就不能再插入NULL值。当可以为空时,插入NULL值和其对应的类型的值均为可以的。

  在实际应用开发中,比如我们在插入数据并不能准确的知道数据的值,就可以暂时插入NULL值。当设置了不能为空时,这就约束着必须插入有效的值

  通过合理地应用空属性约束,可以有效地避免数据中的空值或缺失值,从而提高数据质量和可靠性。

二、默认值

  在MySQL中,默认值约束用于定义表列的默认值。当插入新记录时,如果没有为该列提供值,则可以使用默认值来填充该列。这有助于减少数据冗余并提高数据库的一致性。

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

  在上图中我们将性别默认设置成 ‘女’。当插入数据时不提插入性别时,默认就是 ‘女’。具体如下图:

  通过上图看到,当我们不再插入性别时默认给我们填充了‘女’,当然也可以自己指定。我们也可查看表结构,看其详细的默认值,如下图:

  当我们不指定其默认值时,默认给我们指定了默认值为NULL。我们再看如下的插入:

  有同学就会有疑问:我们假如设置一个字段不为空时,默认值还会自动设置为NULL吗?我们不妨通过下图看一下:

  那么 default约束 和 空属性约束 是不是冲突的呢?当我们设置了default时,这就意味着即使我们不插入数据也不为空,因为会默认使用默认值填充。default约束和not null约束同时出现并没有太大的意义。因为一但设置的default约束,就可以保证了 not null 约束。但是我们要区分的是:

  • default 是我们不显示的向指定列插入,default会自动插入。
  • NULL 是显示的向一列插入。如果插入正常值,就正常工作。如果不确定就插入NULL。但是有not null约束时,就必须插入有效值。

  其实他们之前也并不冲突,反而是相辅相成的。当我们不指定插入时,可以用到default约束。指定插入就可以选择空约束。

三、列描述

  所谓列描述,就是我们之前一直在使用的对列的注释信息。用到的关键词是comment,没有实际含义,专门用来描述字段,会根据表创建语句保存,用来给程序员或DBA来进行了

解。下面我们再来看一个实际例子:
  desc查看表结构时并不能看到注释信息,如下:
  可以通过show来查看建表时的注释信息,如下图:

四、zerofill

  在MySQL中,zerofill约束是一种用于数值字段的约束,它会在数值字段的值前面添加零,使其达到指定的长度。这通常用于保持数值字段的位数一致性,尤其对于需要显示位数对齐的情况非常有用。

  当你在MySQL中创建一个数值字段,并为其添加zerofill约束时,MySQL会自动在存储数据时将数值填充为指定长度,并在需要的情况下,自动在数值前面添加零。

  我们一直没有解释int(11)中的11的含义是什么,如下图:

  其实就是代表的整型的位数,表示的是11位。int的取值范围是大约是21亿正负,最多也就是十位数字,负数的话再加上符号相当于11位了。那么无符号整数是不是10位就可以了呢?是的。如下图所示:

  我们也可以通过zerofill约束来验证一下。我们现在将 id 的字段属性修改一下,增加上zerofill约束。如下图:

  我们再来插入一条数据,观察是否会自动补0:

  如上图所示,正是我们所说的那样,不够位数时会自动在前面补0。因为时无符号的整数,所以一共是10位。

五、主键

  在MySQL中,主键约束用于唯一标识表中的每一行数据。怎么理解这句话呢?通俗来讲,一个事物可能会有很多的字段属性,其中某一个属性或者多个属性组合能够唯一标示该事物,我们可以将该字段设置成主键类型。

  举个例子,一个合法的中国公民,都会有自己的身份证,每个人的身份证号是不同的,且身份证号能够唯一的标示某个人,那么身份证号就可以设置成主键类型。下面我们通过一个实际例子来看:

  上图的例子中,我们设置学生的学号为主键(primary key),用来唯一标示一个学生的信息。注意:主键对应的字段的值不能重复,不能为空,一张表中最多只能有一个主键,且主键所在的列通常是整数类型。下面我们来插入一些数据来验证一下:

  上图验证的主键对应的字段的值不能重复。一但重复,就会报错不让你进行操作。再看如下图,主键对应的字段的值也不能为NULL

  当我们不想要这个主键时,直接将其删除掉即可。如下图:

  我们也不用指定删除那个字段的主键,因为一张表中只允许有一个主键。当表创建好以后但是没有主键的时候,可以再次追加主键。如下图:

  有时候一个字段并不能很好的标示数据的唯一性,但是多个字段就可以。我们也称之为复合主键。复合主键就是在创建表的时候,在所有字段之后,使用多个字段作为主键。具体实例如下:

  如上图,我们将 id 和 course 同时构成主键,他们即为复合主键。我们在查看表结构时,可以看到 id 和 course 的Key列都有PRI标志,并不是说明有两个主键,而是他们两个组成了复合主键。并且它们都是不允许为空的。我们来插入一些数据来观察一下:

  通过上图也不难发现,只有当与复合主键中所有的字段的值相同时,才算冲突,并且不会让你进行插入。复合主键也是主键,所以对主键的操作也可以用到复合主键上。

六、自增长

  在MySQL中,自增长约束是一种非常常见的约束,用于在插入数据时自动为表中的主键字段生成唯一的递增值。这种约束通常用于确保表中的每一行都具有唯一标识,并且可以方便地避免手动指定主键值的繁琐操作。

  自增长约束通常与主键字段一起使用,通过自动分配唯一的、递增的整数值来确保每行数据都有一个独特的标识符。下面我们来看一个实际的例子:

  我们下面再来插入一些值来观察一下:

  我们再插入时并没有设置id的值,但是在创建表的时候添加了自增长的约束。所以我们看到默认值是从1开始,然后加1增长。那要是我们自动为id添加了一个值,那么以后是怎么进行增长的呢?具体如下:

  如上图,当我们不再指定id的值时,是从2开始增加呢,还是1001开始增加呢?我们看如下实例:

  答案是从当前字段中已有的最大值进行加一。怎么做到的呢?如下图:

  实际上数据库一直在为我们维护者下一个的自增长的值是多少。所以我们用户可以不再去担心这个问题。重点是自增长约束通常用于创建主键列,以确保数据的唯一性和完整性。它适用于需要唯一标识每个记录的场景,例如用户ID、订单ID等。

七、唯一键

  一张表中有往往有很多字段需要唯一性,数据不能重复,但是一张表中只能有一个主键。唯一键就可以解决表中有多 个字段需要唯一性约束的问题。

  MySQL中的唯一键约束是用于确保表中某一列(或多列的组合)的数值在整个列中是唯一的。唯一键约束通过在表中创建唯一索引来实现,其主要作用是防止用户插入重复的数据,确保数据的一致性和完整性。

  怎么感觉跟主键好像啊。确实他们有很多相似之处,但是也有不同之处。下面我们通过实际例子来观察一下。如下图:

  我们知道每个人的电话号码是不能重复的,所以将telephone字段设置了unique约束。我们再来插入一些数据观察一下:

  通过上图,我们也能发现某个字段具有唯一性约束时,该字段也可以为NULL。但是主键的值是不能为NULL的。其次,一但插入重复的值,就会报错。同时,一张表中可以设置对个唯一键,但是一张表中只能有一个主键。

  唯一键的本质和主键差不多,唯一键允许为空,而且可以多个为空,空字段不做唯一性比较。关于唯一键和主键的区别: 我们可以简单理解成,主键更多的是标识唯一性的。而唯一键更多的是保证在业务上,不要和别的信息出现重复。下面结合例子理解一下:

  假设一个场景 ( 当然,具体可能并不是这样,仅仅为了帮助大家理解 ) 。比如在公司,我们需要一个员工管理系统,系统中有一个员工表,员工表中有两列信息,一个身份证号码,一个是员工工号, 我们可以选择身份号码作为主键。
  而我们设计员工工号的时候,需要一种约束:而所有的员工工号都不能重复。 具体指的是在公司的业务上不能重复,我们设计表的时候,需要这个约束,那么就可以将员工工号设计成为唯一键。 一般而言,我们建议将主键设计成为和当前业务无关的字段,这样,当业务调整的时候,我们可以尽量不会对主键做过大的调整。
   需要注意的是,不是主键具有唯一性,而是某个具有唯一性的字段被选择成为了主键,而那些不是主键但是同样需要唯一性约束的字段就应该设置成唯一键

  当然,我们也可以对唯一键进行删除和增加,这里就不再做过多解释,我们直接看实例:

八、外键

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

  一个学生一定隶属于一个班级。一个班级会有很多学生。所以当我们在定义学生表时,班级的信息一定会有大量的重复。如下图:

  从上图可知,会有很多学生都会记录上相同的class_id 与 class_name。这时候我们可以单独创建一个班级表,让班级表与学生表产生一定的联系即可。如下图:

  但是我们需要在student表中保留一个class的属性,这样才能与myclass表建立联系。具体如下图:

  在上图中,我们把student表中的class_id设置成了外键。class_id在myclass表中是主键。那么这个时候主表就是myclass表,从表是student表。主表会对从表产生一些约束的,也就是对带有外键约束的列进行约束。主表中的数据如下图:

  下面我们来对从表插入一些数据看一下:

  上图中从表中的class_id是具有外键约束的。这时向student表中插入数据时,如果插入的数据对应的class_id是myclass表中存在的,或者插入的class_id为null,那么此时是允许进行插入的。那要是插入的class_id不是myclass表中存在的呢?我们在看如下图:

  当插入的class_id不是myclass表中存在的,那么就会插入失败。通俗理解:当试图插入或更新数据时,MySQL会检查引用的主键列是否存在有效值。如果没有有效的主键值,则无法插入或更新数据。

  所以在对外表进行插入数据时,所具有外键约束的字段,插入的数据必须在主表中存在。否则就会插入失败。我们还需要注意的是:外键列的值必须是唯一的,不能有重复值。这样我们上述所举的例子并不是很好,这里能够理解就行。

九、综合练习

  有一个商店的数据,记录客户及购物情况,有以下三个表组成:

  • 商品goods(商品编号goods_id,商品名goods_name, 单价unitprice, 商品类别category, 供应商provider);
  • 客户customer(客户号customer_id,姓名name,住址address,邮箱email,性别sex,身份证card_id);
  • 购买purchase(购买订单号order_id,客户号customer_id,商品号goods_id,购买数量nums)。
  要求:
  • 每个表的主外键;
  • 客户的姓名不能为空值;
  • 邮箱不能重复。

  goods表如下图: 

  customer表如下图: 

  purchase表如下图:

  当创建完毕后,我们可自行的插入一些数据进行验证和练习。本篇文章的讲解就到这里,感谢阅读ovo~

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

​软考-高级-系统架构设计师教程(清华第2版)【第17章 通信系统架构设计理论与实践(P614~646)-思维导图】​

软考-高级-系统架构设计师教程(清华第2版)【第17章 通信系统架构设计理论与实践(P614~646)-思维导图】 课本里章节里所有蓝色字体的思维导图

Vue3 函数式弹窗

运行环境 vue3vitetselement-plus 开发与测试 1. 使用h、render函数创建Dialog 建议可在plugins目录下创建dialog文件夹,创建index.ts文件,代码如下 import { h, render } from "vue";/*** 函数式弹窗* param component 组件* param opti…

强化学习在文生图中的应用:Training Diffusion Models with Reinforcement Learning

论文链接:Training Diffusion Models with Reinforcement Learning项目地址:Training Diffusion Models with Reinforcement Learning官方代码:https://github.com/kvablack/ddpo-pytorch/tree/maintrl实现:https://huggingface.co/docs/trl/ddpo_trainer🤗关注公众号 fu…

口袋参谋:一键下载任意买家秀图片、视频,是怎么做到的!

​对于淘宝商家来说,淘宝买家秀是非常的重要的。买家秀特别好看的话,对于提升商品的销量来说,会有一定的帮助,如何下载别人的买家秀图片,然后用到自己的店铺中呢? 这里我可以教叫你们一个办法!那…

pdf如何让多张图片在一页

pdf保存为一页六张图片的方法是: 1、打开pdf查看器,打开文档。 2、点击【打印】图标进入打印程序,选择打印范围。 3、在【打印处理】选项,选择【每张张上放置多页】。 4、自定义每页放置的图片张数为六张,并对打印排版预览设置。 5、设置打印…

Halcon (2):Halcon基础知识

文章目录 文章专栏视频资源前言Halcon文档案例学习结论 文章专栏 Halcon开发 视频资源 机器视觉之C#联合Halcon 前言 本章我们主要讲解Halcon的基础语法 Halcon文档 按下F1,就可以看到Halcon的文档,不过都是纯英文的 如果不清楚参数如何使用&#x…

土地利用强度(LUI)综合指数

土地利用强度的概念可以解释为某一时间特定区域内人类活动对土地利用强度的干扰程度[1],其不仅反映不同土地利用类型本身的自然属性,也体现了人类利用土地的深度和广度,进而揭示在人类社会系统干扰下土地资源自然综合体自然平衡的保持状态[2]…

解决/usr/lib/libstdc++.so.6: version `GLIBCXX_3.x.x‘ not found问题

目录 1、查找缺少库版本2、动态库版本与gcc版本对应关系3、查找 libstdc.so.6.0.x 库文件4、如果libstdc.so.6.0.21库文件已存在,则按照下面的步骤创建软链接即可4.1 拷贝、软连接4.2验证新的 libstdc.so.6.0.21 库文件是否生效 5、如果libstdc.so.6.0.21库文件不存…

Codeforces Round 909 (Div. 3)(A~G)(启发式合并 , DSU ON TREE)

1899A - Game with Integers 题意:给定一个数 , 两个人玩游戏,每人能够执行 操作,若操作完是3的倍数则获胜,问先手的人能否获胜(若无限循环则先手的人输)。 思路:假如一个数模3余1或者2&#…

计算机msvcr120.dll丢失的解决方法,分享多种亲测可靠的方法

在使用计算机的过程中,我们有时可能会遇到一些技术问题,其中之一就是提示丢失msvcr120.dll文件。当计算机提示丢失msvcr120.dll文件时,可能是由于某些程序无法找到这个文件,从而导致程序无法正常运行。那么我们需要如何解决修复好…

微服务下整合knife4j接口文档

前言:本文旨在解决微服务下通过网关访问所用服务的knife4j文档,无需再通过其他服务单独访问 功能模块配置: 1.配置类: 在这个文件中注意下basePackage的扫描路径,修改为对应controller下的路径。 Configuration EnableSwagger…

教你轻松解决win系统ucrtbased.dll丢失的问题,亲测有效!

ucrtbased.dll是一个动态链接库文件(DLL),它是Windows操作系统中的一部分,主要负责提供操作系统和应用程序所需的函数和接口。这个文件包含了操作系统和应用程序共同使用的通用代码,以确保不同程序之间的兼容性和稳定性…

人工智能发展前景

随着人工智能的快速发展,这个行业对人才的需求也在不断增长。越来越多的有志之士开始关注人工智能,希望通过自学获得相关技能,进而在人工智能领域找到心仪的职业。本文将探讨人工智能职业发展的前景,并为大家提供自学人工智能的途…

cesium雷达扫描(雷达扫描线)

cesium雷达扫描(雷达扫描线) 下面富有源码 实现思路 使用ellipse方法加载圆型,修改ellipse中‘material’方法重写glsl来实现当前效果 示例代码 index.html <!DOCTYPE html> <html lang="en"><head>

Golang环境搭建Win10(简洁版)

Golang环境搭建Win10 Golang环境搭建(Win10)一、前言二、Golang下载三、配置环境变量3.1、配置GOROOT3.2、配置GOPATH3.3、配置GOPROXY代理 Golang环境搭建(Win10) 一、前言 Go&#xff08;又称 Golang&#xff09;是 Google 的 Robert Griesemer&#xff0c;Rob Pike 及 Ken…

亚马逊云Amazon OpenSearch Serverless“利刃在手,‘向量’八方“

全Serverless架构新价值 随着Amazon OpenSearch Serverless正式上线“商用”&#xff0c;亚马逊云科技的全栈“Serverless”应用架构也“初见雏形”&#xff0c;这也意味着&#xff0c;未来企业可以在亚马逊云科技之上简单和轻松的搭建完整的无服务器应用架构。 数据也显示&am…

十二、Docker的简介

目录 一、介绍 Docker 主要由以下三个部分组成&#xff1a; Docker 有许多优点&#xff0c;包括&#xff1a; 二、Docker和虚拟机的差异 三、镜像和容器 四、Docker Hub 五、Docker架构 六、总结 一、介绍 Docker 是一种开源的应用容器平台&#xff0c;可以在容器内部…

一键云端,AList 整合多网盘,轻松管理文件多元共享

hello&#xff0c;我是小索奇&#xff0c;本篇教大家如何使用AList实现网盘挂载 可能还是有小伙伴不懂&#xff0c;所以简单介绍一下哈 AList 是一款强大的文件管理工具&#xff0c;为用户提供了将多种云存储服务和文件共享协议集成在一个平台上的便利性。它的独特之处在于&am…

2023-2024华为ICT大赛-计算赛道-广东省省赛初赛-高职组-部分赛题分析【2023.11.18】

2023-2024华为ICT大赛 计算赛道 广东省 省赛 初赛 高职组 部分赛题 分析【2023.11.18】 文章目录 单选题tpcds模式中存在表customer&#xff0c;不能成功删除tpcds模式是&#xff08; &#xff09;以下哪个函数将圆转换成矩形&#xff08; &#xff09;下列哪个选项表示依赖该D…

jvm 内存模型概述

一、类加载子系统 1、类加载的过程&#xff1a;装载、链接、初始化&#xff0c;其中&#xff0c;链接又分为验证、准备和解析 装载&#xff1a;加载class文件 验证&#xff1a;确保字节流中包含信息符合当前虚拟机要求 准备&#xff1a;分配内存&#xff0c;设置初始值 解析&a…