在前面的文章中提到了约束,是通过数据类型对字段产生的约束。但是数据类型约束很单一,需要有一些额外的约束,更好的保证数据的合法性,从业务逻辑角度保证数据的正确性。于是就引入了表的约束。
表的约束很多,这里主要介绍如下几个:null/not null、default、comment、zerofill、primary key、auto_increment、unique key、foreign key。
文章目录
🙋♂️ 作者:@Ggggggtm 🙋♂️
👀 专栏:MySQL 👀
💥 标题:MySQL表的约束💥
❣️ 寄语:与其忙着诉苦,不如低头赶路,奋路前行,终将遇到一番好风景 ❣️
在MySQL中,空属性约束指定了某一列是否可以包含NULL值。它们用于各种目的,例如数据验证和限制数据的输入格式。以下是空属性约束的详细解释:
- NOT NULL: 当使用NOT NULL属性约束时,将禁止该列包含NULL值。这意味着在插入或更新数据时,该列必须包含有效的数值或字符,不能为NULL。
- 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来查看建表时的注释信息,如下图:
在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~