当前位置: 首页 > article >正文

MySQL数据库(5)—— 表的约束

目录

一,前言

二,基础约束

2.1 空属性

2.2 默认值

3.3 列描述

4.4 zerofill

三,键约束

3.1 主键

3.2 复合主键

3.3 自增长

3.4 唯一键

四,外键

4.1 问题发现

4.2 外键约束


一,前言

  • 约束主要设针对数据类型,如果插入的数据超出了对应数据类型的取值范围,那么数据将会插入失败
  • 表中一定要有各种约束,有了约束,就能让我们未来插入到数据库的表中的数据是符合预期的,所以约束的本质就是通过技术手段,倒逼程序员插入正确的数据。
  • 反过来,站在MySQL的视角,凡是插入进来的数据都是符合数据约束的,也一定程度上增加了MySQL内部逻辑的正确性
  • 总结:约束的最终目标,就是保证数据的完整性,正确性和可预期性

二,基础约束

2.1 空属性

空属性有两个值,分别是null和not null,数据库默认字段基本都是允许为空的,但在实际开发中我们要尽可能保证字段不为空,因为空值无法参与运算,如下:

在建表时,我们要让某个字段不能为空,那么就要在后面加上not null属性:

 这样在后面插入值的时候,必须填上插入这个位置的值,不然就会报错,如下: 

问题:NULL和 '' 有什么区别?

解答

  • 我们上面插入三个值,非空的other字段我们一个没插入值,一个只写了单引号但是里面没东西
  • NULL和 '' 不一样,后者表示一个字符串,但是这个字符串是空的,没有任何字符;前者才是真正的什么都没有
  • 为了方便理解,我们可以用string做例子,我们创建了一个string但是还没有往里面插入数据,但是我们创建的string里面有很多类方法和类成员变量,所以string里面还是有东西的,而NULL就是真的什么都没有

2.2 默认值

  • 可以理解为初始值,C++中叫做“缺省值”,虽然叫法不同但是本质是一样的,就是给一个字段设置一个默认值,在向表中插入数据时如果没有给该字段赋值,那么该字段就会自动用默认值填充

  • 一旦给某字段设置了默认值,那么该字段就不会再出现NULL了
  • 并且如果一个字段设置了default,那么再设置not null也没有任何意义了 

3.3 列描述

  • 换个说法,就是“注释”,在创建表时用来对各个字段进行描述 

问题:如何理解comment也是一种约束?

解答:上面说过约束的最终目标就是保证数据的完整性,正确性和可预期性,数据不仅仅由用户提供,也由程序员维护,所以在约束用户的同时,也会给程序员约束,所以comment是给程序员看的,是一种软件层面的约束

4.4 zerofill

  • 这个东西也可以认为是一种默认值,default是针对字段的,zerofill是针对类型的
  • 以varchar(20)为例,数值类型后面的括号中的数字代表宽度,如果对应数值设置zerofill属性后,如果数据的宽度小于设定的宽度,则自动填充0

下面是没有设置zerofill的演示:

下面是添加zerofill的演示:

但是需要注意的是,zerofill只是在显示层面填充了0,并没有影响其真正存储的值:

最后需要注意的是,添加0的数量是和数值类型后面括号里的值来定的,如果是int(5),那么就会填充4个0,int类型默认是int(10),如上图,所以填充9个0

问题:为什么int默认为10?

解答:整数大小为-2^31 ~ 2^31-1,无符号整数位0 ~ 2^31-1,分别换算下来就是42亿和21亿多,这么大的数字表示起来其实也就是10位数

三,键约束

3.1 主键

①为什么要有个主键?

  • 当一个表里的数据非常非常多时,查询起来就比较困难
  • 这时候可以讲某一字段作为主键key,当需要查找记录时就可以根据这个主键来查找对应的记录,能大大减少查询的时间

②主键的规则

  • 首先,主键最多只能有一个,也就是说在建表时只能给一条字段设置primary key标记为主键,有两个时就会报错
  • 主键默认是not null的,也就是不能为空,并且主键不能重复,比如学生id,规则上一个学校是不允许有重复学号的

③演示

首先是设置主键:

主键不允许重复:

可以通过主键来查询信息:

 

也可以通过主键来更新或删除内容:

主键也可以删除和添加,但是前提是主键的数据不能重复,如果是在建表后添加主键,如果这一列数据有重复就会添加失败,所以建议是在建表时加上主键:

3.2 复合主键

  • 前面说过一个表只能由一个主键,但是并不意味着主键只能添加给一列
  • 一个主键可以被添加到多列上,这种添加到多列数据上的主键我们称为“复合主键”
  • 而且这多个添加了主键的列都要遵守主键的规则,但是只有当这些列都违反规则时才会报错,具体看下面演示

首先是建立复合主键: 

在向进程表插入数据时,只有插入进程的IP和端口都出现冲突时才会产生复合主键冲突,否则正常插入:

复合主键和主键一样可以删除和添加,就是添加的时候,要在后面的括号里填入多个列即可

alter table 表名 drop primary key;
alter table 表名 add primary key(多个列名);

3.3 自增长

  • 设置了自增长的字段,插入数据时如果没有给该字段赋值,那么系统会自动找出当前列已有数据中的最大值,将该最大值加1后插入该字段
  • 任何一个字段要做自增长,前提是本身必须是一个索引(就是key那一栏有值,目前可以认为主键就是一个索引),并且自增长字段必须是数值类型,一张表最多只能有一个自增长字段
  • 自增长通常和主键搭配使用,但是一般而言,建议将主键设计成与当前业务无关的字段,避免因为业务逻辑的调整而需要修改主键,下面是演示:

①添加自增长属性 

②如果插入的第一条记录时没有指明,会自动从1开始,并且后续插入仍然没有指明时,会依次递增: 

③如果指明了,那么下一次插入会从本次指明的数字开始,前提时指明的数字不能和已有的数字重复:

3.4 唯一键

  • 主键虽然能解决一条字段的唯一性,但是一张表可能有很多字段需要唯一性,但是主键只能有一个
  • 所以有了唯一键,它可以有多个,负责一张表中多个字段的唯一性
  • 唯一键和主键都能保证字段中数据的唯一性,但是唯一键允许为空,并且也允许多个字段同时为空,因为空字段不做唯一性比较
  • 可以理解为主键是特殊的唯一键

①首先是添加唯一键 

②当插入的数据的唯一键字段和已有字段重复时,插入会报错

③如果插入时不指定唯一键字段的值,那么会默认插入NULL 

 

问题:主键和唯一键不会冲突吗?

解答: 

  • 人身上是有很多的属性值的,建表的本质其实就是通过表来描述对应的一个对象,mysql上的每一个表相当于C中的结构体,C++里的类,用来描述一个具体的事物。
  • 我们选择或设置主键通常有两种做法:一种是从我身上众多具有唯一属性的列,选择出某一列称为主键;另一种是选择一个和业务无关的列作为主键
  • 所以一个人身上某个唯一属性没有被选为主键,但不代表这些没有被选为主键的属性没有唯一性,也需要维护唯一性,所以主键和唯一键不冲突。

四,外键

外键这个东西比较复杂,我们单独分一个标题来讲解

4.1 问题发现

我们先搞两个表:

学生表:

班级表:

先往表中插入一些值:SQL如下:

insert into class values (1,'计算机101');
insert into class values (2,'计算机102');
insert into student (name,telphone,classid) values ('张三','123456789',1);
insert into student (name,telphone,classid) values ('李四','123456798',3);
insert into student (name,telphone,classid) values ('王五','123456987',2);
insert into student (name,telphone,classid) values ('赵六','123459213',3);

假设上面是我粗心,把部分同学的班级都输入成了3班,可以插入,但是我们的班级表中只有1班和2班,所以上面的SQL可以插入,但是在逻辑上是错误的 

 所以我们发现了问题所在,所以我们要想办法避免上述情况,当然是要在技术上避免

4.2 外键约束

①我们先建立外键

②上面就是将学生表的classid和班级表的id挂钩,当插入值得classid在班级表里有的时候才能允许插入,没有则会报错,这就是外键约束


http://www.kler.cn/a/553655.html

相关文章:

  • 老游戏回顾:BM
  • 交友项目-交友软件简介
  • go-micro
  • shell——分支语句
  • 【Python游戏】双人简单对战游戏
  • 数组和指针常见笔试题(深度剖析)
  • Centos7 使用 yum 报错 Could not retrieve mirrorlist
  • 【Rust中级教程】1.10. 引用及内部可变性(简单回顾):引用、内部可变性、`Cell`类型及相关操作
  • less 和 sass 的异同(css 预处理语言)
  • 非docker安装open-webui连接ollama实现deepseek本地使用,集成其他openai模型,常见启动报错问题解决。
  • 人工智能丨卷积神经网络的概念, 它与普通的神经网络有何不同
  • HarmonyOS的核心特性:分布式技术引领创新
  • DeepSeek与ChatGPT:会取代搜索引擎和人工客服的人工智能革命
  • Zookeeper(54)如何使用Zookeeper的命令行工具?
  • Redis-03高级篇下-最佳实践:
  • Nginx下proxy_redirect的三种配置方式
  • scroll、offset、client三大家族和getBoundingClientRect方法
  • android 定制mtp连接外设的设备名称
  • 基于JavaSpringboot+Vue实现前后端分离房屋租赁系统
  • lua的local 变量和self 变量的理解理解后解决自己写的bug.