【MySQL】表的约束 -- 详解

  • 表中一定要有各种约束,通过约束让我们在未来插入数据库表中的数据是符合预期的。约束本质是通过技术手段倒逼程序员插入正确的数据,反过来站在 MySQL 的角度,凡是插入进来的数据都是符合数据约束的。
  • 约束的最终目标:保证数据的完整性可预期性
  • 真正约束字段的是数据类型,但是数据类型约束很单一,需要有一些额外的约束,更好的保证数据的合法性,从业务逻辑角度保证数据的正确性。比如有一个字段是 email,要求是唯一的。
  • 表的约束很多,这里主要介绍如下几个: null/not null,default,comment,zerofillprimary key,auto_increment,unique key

一、非空约束

1、空属性

  • 两个值:null(默认的)和 not null不为空)
  • 数据库默认字段基本都是字段为空,但是在实际开发时,应尽可能保证字段不为空,因为数据为空没办法参与运算。

 

创建一个班级表,包含班级名和班级所在的教室。

插入数据时,没有给教室数据插入失败。 

站在正常的业务逻辑中:
如果班级没有名字,就不知道你在哪个班级;如果教室名字可以为空,就不知道你在哪上课。所以我们在设计数据库表时,一定要在表中进行限制,满足上面条件的数据就不能插入到表中。这就是 “ 约束

二、default 约束

1、默认值

默认值 :某一种数据会经常性的出现某个具体的值,可以在一开始就指定好,在需要真实数据时,用户可以选择性的使用默认值。
如果设置 default 后,用户插入了具体的数据,那么就用用户所提供的数据。
如果 数据在插入的时候不给该字段赋值,那么就使用默认值。

  • 如果没有明确指定某一列要插入,默认用的是 default。
  • 如果在建表时,对应列不能为空且默认没有设置 default 值,则无法直接插入数据。 

  • 当用户忽略某一列时,使用 default 默认值(如果设置了)。如果没有设置 default 值,则直接报错。
  • null 和 not null 主要是用来约束用户想插入的内容。
  • default 和 not null 二者并不冲突,而是相互补充的。

注意只有设置了 default 的列,才可以在插入值时,对列进行省略。

这里的 age 没有 not null 的约束,同时具有 default 默认值。

总结:

  • 如果用户想显示的插入,要么就插入一个具体的值,要么就插入 NULL。
  • 如果设置了 not null,那么插入 NULL 就会被拦截。
  • 如果没有设置 default,那么这一列就不能省略。
  • 如果在建表时没有设置 default 默认值(前提是没有设置 not null),那么 MySQL 会对我们的 sql 做优化,默认加了 default null。
  • not null 和 defalut 一般不需要同时出现,因为 default 本身有默认值,不会为空。

三、comment

1、列描述

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

通过 desc 查看不到注释信息: 

通过  show  可以看到:

四、zerofill

下面通过 show 看看 t17 表的建表语句:

可以看到 int(10),这个代表什么意思呢?整型不是 4 字节码吗?那这个 10 又代表什么呢?
其实没有  zerofill  这个属性,括号内的数字是毫无意义的。a  和  列就是前面插入的数据,如下:

但是对列添加了  zerofill  属性后,显示的结果就有所不同了。修改  t17  表的属性:
对 b   列添加了  zerofill  属性,再进行查找,返回如下结果:

这次可以看到 b 的值由原来的 2 变成 0000000002,这就是 zerofill 属性的作用,如果宽度小于设定的宽度(这里设置的是 10),自动填充 0

要注意的是,这只是最后显示的结果,在 MySQL 中实际存储的还是 2

为什么是这样呢?
我们可以用 hex(十六进制) 函数来证明。
可以看出数据库内部存储的还是 2,0000000002 只是设置了  zerofill  属性后的一种格式化输出而已。
修改括号内的值:
插入数据:
不够就补 0,补到括号内的数字位数为止,如果够了就直接显示。
为什么建表时默认是 int(10)?

因为一个整数占 4 个字节,4 个字节的取值范围:有符号是 -2^31~2^31-1,无符号是 0~2^32-1。

2^31-1 和 2^32-1 最后表示出来都是十位,所以用 int(10) 就足以把所有对应的整数的数据位表示出来。

有符号是 11 位,多了 1 是因为多了一个符号位。


五、主键

主键 primary key   用来 唯一 的约束该字段里面的数据,不能重复不能为空,一张表中最多只能有一个主键但不意味着一个表中的主键只能添加给一列。说明一个主键可以被添加到一列或多列,添加给多列则叫作复合主键。
主键所在的列通常是整数类型。

1、指定主键

  • 创建表的时候直接在字段上指定主键。

Key 中 PRI 表示该字段是主键。


2、主键约束

  • 主键约束:主键对应的字段中不能重复,一旦重复,操作失败。

3、追加主键

  • 当表创建好后但是没有主键的时候,可以再次追加主键。


4、删除主键


5、复合主键

在创建表的时候,在所有字段之后,使用  primary key(主键字段列表)   来创建主键,如果有多个字段作为主键,可以使用复合主键。
复合主键中的字段有个别发生冲突并不影响,但如果主键中多列的列信息都与历史的信息发生冲突了才会触发主键约束。

六、自增长

1、auto_increment

auto_increment: 当对应的字段不给值,会自动的被系统触发,系统会从当前字段中已经有的最大值进行  +1  操作,从而得到一个新的不同的值。
auto_increment 通常和主键搭配使用,作为逻辑主键。
自增长的特点
  • 任何一个字段要做自增长,前提是本身是一个索引key 一栏有值)。
  • 自增长字段必须是整数
  • 一张表最多只能有一个自增长

在插入后获取上次插入的 auto_increment 的值(批量插入获取的是第一个值)

索引:
  • 在关系数据库中,索引是一种单独的、物理的对数据库表中一列或多列的值进行排序的一种存储结构,它是某个表中一列或若干列值的集合和相应的指向表中物理标识这些值的数据页的逻辑指针清单。索引的作用相当于图书的目录,可以根据目录中的页码快速找到所需的内容。
  • 索引提供指向存储在表的指定列中的数据值的指针,然后根据您指定的排序顺序对这些指针排序。数据库使用索引以找到特定值,然后顺指针找到包含该值的行。这样可以使对应于表的 SQL 语句执行得更快,可快速访问数据库表中的特定信息。

七、唯一键

一张表中往往有很多字段需要唯一性,数据不能重复,但是一张表中只能有一个主键:唯一键就可以解决表中有多个字段需要唯一性约束的问题。
唯一键的本质和主键差不多,唯一键 允许为空 ,而且可以多个为空,空字段不做唯一性比较。

1、唯一键和主键的区别

可以简单理解成,主键更多的是标识唯一性的。而唯一键更多的是保证在业务上不要和别的信息出现重复。
乍一听好像没啥区别,下面给大家作一个假设来帮助理解:
在公司,我们需要一个员工管理系统,系统中有一个员工表,员工表中有两列信息,一个是身份证号码,一个是员工工号,我们可以选择身份号码作为主键。
那么我们在设计员工工号时,需要一种约束:所有的员工工号都不能重复。具体指的是在公司的业务上不能重复。
我们在设计表时,需要这个约束,那么就可以将员工工号设计成为唯一键。一般而言,建议将主键设计成和当前业务无关的字段。这样,当业务调整的时候,我们可以尽量不会对主键做过大的调整。
当 id 为 NULL 时,是可以直接插入且不冲突的。
  • 对应的主键一旦设置好,不能和其它键冲突,而且主键不能为空
  • 唯一键表达了与主键类似的功能,可以为空,NULL 不参与计算,与语言上的 NULL 不一样。

 

上面的设计中,数据库有逻辑上的错误,在现实生活中,不同的人电话号码不同。

毫无疑问,主键要保证唯一性,同时并不否认其它列属性不需要唯一性,如果也需要就得带上,避免出现上述情况。

唯一约束不能重复,但可以为 null

总结:

  • 在技术上,唯一键可以为空,主键不能为空。
  • 主键通常用来标定某一行记录在整表中的唯一性,而唯一键的侧重点在于让用户插入的列值和表中其它的列值不要发生冲突,从而保证在业务上、在上层对应的字段的唯一性。
  • 二者不是对立的,是互相补充的。主键保证表中记录的唯一性,唯一性保证列中的信息不会出现重复。

八、外键

外键 用于定义主表从表之间的关系:外键约束主要定义在从表上,主表则必须是有主键约束或  unique  约束。
当定义外键后,要求外键列数据必须在主表的主键列存在或为 null。
外键的本质:产生关联,增加约束,来整体增加表和表之间的完整性。
foreign key(字段名) references 主表(列)

对上面的示意图进行设计:

  • 先创建主键表


  • 再创建从表


  • 正常插入数据


  • 插入一个班级号为 1的学生,因为没有这个班级,所以插入不成功


  • 插入班级idnull,比如来了一个学生,目前还没有分配班级


  • 删除班级


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

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

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

相关文章

javaApI(Application Programming Interface)应用程序编程接口

ApI概念 Apl:指的是官方给开发人员提供的说明文档,对语言中有哪些类,类中有哪些方法进行说明 Objict 类 java.lang.Object 是java类体系结构中最顶层的类 Object可以表示java中任意的类 Object类中的方法 toString() 输出一个对象,但是…

在Ubuntu系统下搭建TDengine集群

目录 一、Ubuntu虚拟机创建 二、系统相关配置 1、设置系统hostname 2、网络配置及IP规划 3、配置FQDN(etc/hosts) 4、服务端口设置 三、TDengine server安装 1、服务安装 2、修改配置 3、启动taosd 4、服务卸载 四、客户端安装 1、client安…

掘根宝典之C语言概述(main函数的多种写法,注释,标识符,ASCII码,转义字符)

目录 main函数的多种写法 1.void main() 2.main() 3.int main() 4.int main(void) 注释 标识符 ASCII码 转义字符 \n,\",\\,\a,\ \b \r \t \ddd \xdd main函数的多种写法 1.void main() 一些编译器允许这么写…

大厂经验谈之OKR目标管理

前言 这是大厂经验谈系列第一篇文章,来看看互联网公司是如何制定和管理目标的。OKR是目前互联网公司经常采用的目标管理工具,最开始也是由国外著名公司推崇,比如Google、微软、亚马逊等,后面才逐步引入国内。既然是工具就有用得好和不好的地方,很多团队仍然把OKR当做KPI来…

vue2.0及起步(前端面试知识积累)

1、需要了解的vue概要知识 1、vue是什么? 一套用于构建用户界面的渐进式JavaScript框架。 为什么vue被称为是渐进式JS框架? 答:Vue允许开发者在不同的项目中以渐进式的方式使用它,这种渐进式表现在以下的方面: 逐步采…

这几个Python内置函数你都知道吗

divmod() divmod() 是一个 Python 内置函数,用于同时返回商和余数。它接受两个参数,第一个参数是被除数,第二个参数是除数,返回一个包含两个值的元组,第一个值是商,第二个值是余数。 示例用法如下&#…

【Simulink系列】——动态系统仿真 之 混合系统

声明:本系列博客参考有关专业书籍,截图均为自己实操,仅供交流学习! 一、混合系统概述 由不同类型系统共同构成的系统称为混合系统!仿真时必须考虑连续信号和离散信号的采样匹配问题,一般使用变步长连续求…

C++学习笔记:多态

C学习笔记:多态 什么是多态?多态的构成条件?C11中的final和override抽象类是什么?什么是虚表?多继承中的虚表 什么是多态? 多态是在不同继承关系的类对象,去调用同一函数,产生了不同的行为。 例如:学校在餐厅的某个档口为老师们提供了教师优惠,同样…

SpreadJS+vue3练手使用

SpreadJS的练手使用 // 首先在 package.json 这个文件里{"name": "app-admin","private": true,"version": "0.0.0","type": "module","scripts": {"dev": "vite",&quo…

【深度学习笔记】 3_13 丢弃法

注:本文为《动手学深度学习》开源内容,部分标注了个人理解,仅为个人学习记录,无抄袭搬运意图 3.13 丢弃法 除了前一节介绍的权重衰减以外,深度学习模型常常使用丢弃法(dropout)[1] 来应对过拟合…

阿里面试:最佳线程数,如何确定?

尼恩说在前面 在40岁老架构师 尼恩的读者交流群(50)中,最近有小伙伴拿到了一线互联网企业如得物、阿里、滴滴、极兔、有赞、shein 希音、百度、网易的面试资格,遇到很多很重要的面试题: 如何确定系统的最佳线程数? 小伙伴 没有回…

机器学习深度解析:原理、应用与前景

随着人工智能的迅速发展,机器学习已经成为当今时代最为引人注目的技术之一。它不仅仅是一种技术或工具,更是一种推动社会进步、影响人类生活的重要力量。那么,什么是机器学习?它是如何工作的?又在哪些领域中发挥着不可…

阿里云服务器ECS u1实例性能怎么样?

阿里云服务器ECS u1实例,2核4G,5M固定带宽,80G ESSD Entry盘优惠价格199元一年,性能很不错,CPU采用Intel Xeon Platinum可扩展处理器,购买限制条件为企业客户专享,实名认证信息是企业用户即可&a…

介绍一下我们:久菜盒子工作室

大数据科学团队/全网可搜索的久菜盒子工作室 我们是:985硕博/美国全奖doctor/计算机7年产品负责人/医学大数据公司医学研究员/SCI一区2篇/Nature子刊一篇/中文二区核心一篇/都是我们 主要领域:医学大数据分析/经管数据分析/金融模型/统计数理基础/统计学…

编程笔记 Golang基础 028 结构体与JSON

编程笔记 Golang基础 028 结构体与JSON 一、JSON二、结构体转JSON(序列化)三、JSON转结构体(反序列化)小结 结构体与JSON之间的相互转换是现代软件开发中数据处理的基础工具,极大地简化了数据在不同层次、不同组件间的…

spring boot 集成科大讯飞星火认知大模型

一、安装依赖 <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0" xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation"http://maven.apache.org/POM/…

Educational Codeforces Round 160 (Rated for Div. 2) D. Array Collapse(笛卡尔树+DP)

原题链接&#xff1a;D. Array Collapse 题目大意&#xff1a; 给你一个长度为 n n n 的排列 p p p &#xff0c;排列的定义为 [ 1 , 2 , 3 , . . , n ] [1,2,3,..,n] [1,2,3,..,n] 中每个数都出现 恰好 一次。 你可以做 任意多次 这样的操作&#xff1a; 选出一个任意长度…

前端导出EXCEL

步骤解析 定义了一个名为 excelDown 的函数&#xff0c;它接受两个参数&#xff1a;res 和 type。res 是包含响应数据的对象&#xff0c;type 是要导出的文件类型。如果 type 未提供&#xff0c;则默认使用 Excel 文件的 MIME 类型。 export const excelDown (res, type) >…

unity导航网格无法烘培到台阶和斜坡

如图是我在b站学Unity导航网格时建的一个示例场景&#xff0c;本场景使用的为棱长1m的立方体&#xff0c;读者可以以此为参照度量其他物体大小。 可见导航网格根本无法烘焙到斜坡和台阶上&#xff0c;为解决问题我做了不少尝试&#xff0c;调整最大坡度和步高都没办法解决问题…

AI新纪元:可能的盈利之道

本文来源于Twitter大神宝玉&#xff08;dotey&#xff09;在聊 Sora 的时候&#xff0c;总结了 Sora 的价值和可能的盈利方向&#xff0c;我把这部分内容单独摘出来再整理一下。现在的生成式 AI 大家应该不陌生&#xff0c;用它总结文章、翻译、写作、画图&#xff0c;当然真正…