《MySQL:MySQL表的约束-主键/复合主键/唯一键/外键》

表的约束:表中一定要有各种约束,通过约束,让未来插入数据库表中的数据是符合预期的。约束本质是通过技术手段,倒逼程序员插入正确的数据。即,站在mysql的视角,凡是插入进来的数据,都是符合数据约束的!

约束的最终目标:保证数据的完整性和可预期性。

真正约束字段的是数据类型,但是数据类型约束很单一,需要有一些额外的约束,更好的保证数据的合法性。

空属性

两个值:null(默认的)和not null(不为空)

数据库默认字段基本都为空,但是实际开发中,尽可能保证字段不为空,因为数据为空,没办法参与运算。

例:

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

正常的逻辑是这样的:

  • 如果没有班级名,则不知道在哪个班级
  • 如果没有教室,则不知道在哪上课

所以在设计数据库表的时候,一定要在表中进行限制,满足上面条件的数据就不能插入到表中。者就是约束!

如果对班级和教室不加约束,可以为空(默认的)。

插入数据的时候,没有给班级名或教室也能插入成功,插入的数据不符合不符合预期。显然这种不加约束的做法是不符合逻辑的。

对班级和教室进行约束,不能为空。

插入数据的时候,没有给班级名或教室名,就插入失败;能插入的数据一定是给了班级名和教室,一定是符合预期的。所以建表的时候一定要加约束。

defalut

如果设置了。用户插入的时候,如果显示的有插入的有具体的数据,就使用用户插入的数据;如果没有就用默认设置的。

如果设置了默认值,可以省略该字段,就使用默认值,只有设置了default的字段才能省略。

那么not null 和 default 有什么区别呢?

  • 如果没有明确指定一列要插入,用的是default,如果建表中,对应的列默认没有设置default,无法不直接插入。
  • default 和 not null 并不冲突,而是互相补充的。
  • not null:当用户想插入的时候,无非插入的数据要么是 null,要么是合法数据,如果字段为 not null,插入 null 则报错。
  • default:当用户忽略了某一列的时候,如果该列设置了默认值则使用默认值,如果没有设置,直接报错。用于为列指定一个默认值。

总结:

  • 如果用户想显示的插入数据,就是 not null 在约束,如果为 not null ,则插入数据不能为null。
  • 如果用户不显示的插入数据,就是 default 在约束,如果没有设置 default ,则该列不能直接插入

建t14表的时候,字段没有指定 null 和 default,为什么也能直接插入呢?

MySQL会对sql指令优化。默认指定字段为 null、default 默认值也为 null。

列描述

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

zerofill

看下面这张表。

mysql会对sql语句做优化,将字段a int unsigned 类型优化为 int(10)unsigned;将字段b int 类型优化为 int(11)。10和11表示什么?其实没有zerofill括号内的数字是没有意义的。

括号内的数字表示数据的宽度。为什么int unsigned默认为10呢?

因为无符号整数表示-2147483648 到 2147483647,最大为21亿多,10位就足够将一个整数的数据位全部表示出来了;int 默认为11,因为有符号整数表示0 到 4294967295,最大为42亿多,加上符号位11位,11位就足够将一个有符号的整数的数据位全部表示出来了,

但是对列添加了zerofill属性后,显示的结果就有所不同了。修改t16a字段的属性。

可以看到,本来应该显示为1的,添加zerofill后,显示成了0001,这就是zerofill属性的作用,如果插入数据的宽度小于设定的宽度(这里设置的是4),自动填充0;如果插入宽度大于设定的值,显示的还是它本身。

要注意的是,这只是最后显示的结果,在MySQL中实际存储的还是插入的数据本身

主键

primary key:用来唯一的约束该字段里面的数据,不能重复,不能为空,一张表中最多只有一个主键。

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

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

  • 删除主键

  • 创建表时没有指定主键,可以在创建表之后追加主键。如果创建表之后插入了数据,然后再指定某一个字段为主键时,必须要保证该字段数据不能重复

复合主键

在创建表的时候,在所有字段之后,使用primary key(主键字段列表)来创建主键,如果有多个字段作为主键,可以使用复合主键。

注意:一张表中只能有一个主键,但是不意味着,一个主键只能添加给一个字段。

id和course共同组成了一个主键。即,一个学生不能重复选同一门课程。

自增长

auto_increment:当对应的字段指定了auto_increment,插入数据的时候,该字段给值,则用该值;如果该字段不给值,会自动的被系统触发,系统会从当前字段已经有的最大值+1,得到一个新的不同值,赋值给要插入数据的该字段。通常和主键搭配使用,作为逻辑主键。

如果建表的时候,不指定 auto_increment 的具体值,则从1开始。如果插入的数据被  auto_increment 指定的字段不给值,就从1自增。

如果插入的数据该字段有值,则使用该值。以后插入的数据,该字段如果不给值,则从该字段的最大值开始自增。

其实,插入一个数据的时候,表中就已经记录了下次要插入的数据的该字段的值了。

唯一键

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

唯一键的本质和主键产不多,唯一键允许字段为空,而且可以多个为空,空字段不做唯一性比较。

唯一键和主键的区别:

  • 主键更多的是标识记录的唯一性。
  • 唯一键更多的是保证业务上,不要和别的信息出现重复。
假设一个场景
比如在公司,我们需要一个员工管理系统,系统中有一个员工表,员工表中有两列信息,一个身份证号码,一个是员工工号,我们可以选择身份号码作为主键。
而我们设计员工工号的时候,需要一种约束:而所有的员工工号都不能重复。具体指的是在公司的业务上不能重复,我们设计表的时候,需要这个约束,那么就可以将员工工号设计成为唯一键。
一般而言,我们建议将主键设计成为和当前业务无关的字段,这样,当业务调整的时候,我们可以尽量不会对主键做过大的调整。

外键

外键用于定义主表和从表之间的关系:外键约束主要定义在从表上,主表必须是有主键约束或unique唯一键约束的。当定义外键之后,要求外键列数据必须在主表的主键列存在或为null。

foreign key ( 字段名 ) references 主表 ( )

案例:建立两张表。我们来简单实现学生的插入和班级的删除,看看有什么问题。

  • 建立学生表和班级表。

  • 插入班级信息。

  • 插入学生信息。

按照我们设计的学生表来看,插入“103王五3”是没有问题的,但是不符合逻辑,因为班级表中,只有两个班级,班级号分别为1,2,没有班级号为3的班级,显然这种设计是有问题的。也就是不能插入一个不存在的班级。

  • 删除班级信息。

如果删除班级号1的班级,显然也是不符合逻辑的,此时班级有学生,不能删除班级。也就是不能删除一个有学生的班级。

即,上面的设计是没有约束的,会引发相关的不符合逻辑的问题。

此时,就引入了外键来解决上面的问题。学生依赖于班级,所以学生表为从表,班级表为主表。学生表中有班级号,班级表中也有班级号,所以班级号就可以作为关联主表和从表的外键。

外键约束有两个关键点:

  • 从表和主表的关联关系
  • 产生外键约束

我们来重新设计表结构。

  • 先建立主表班级表。

  • 插入班级信息。

  • 再建立从表学生表。

  • 插入学生信息。

如果插入的学生信息,班级号在班级表中不存在,则报错。即插入的班级一定是存在的。此时,外键班级号就让从表和主表就有了关联关系,同时产生了约束。

  • 删除班级信息。

如果删除的班级还有学生,就报错,不让删除,班级中没有学生才能删除。即删除的班级一定是没有学生的。此时,外键班级号就让从表和主表有了关联关系,同时产生了约束。

这就约束了,但凡插入表中的数据、删除表中的数据的操作,一定是合法的符合逻辑的操作。

至此,本篇一共总结了八种约束。

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

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

相关文章

Qt 创建QWidget的界面库(DLL)

【1】新建一个qt库项目 【2】在项目目录图标上右击,选择Add New... 【3】选择模版:Qt->Qt设计师界面类,选择Widget,填写界面类的名称、.h .cpp .ui名称 【4】创建C调用接口(默认是创建C调用接口) #ifnd…

汽车免拆诊断案例 | 2011款雪铁龙世嘉车刮水器偶尔自动工作

故障现象 一辆2011款雪铁龙世嘉车,搭载1.6 L 发动机,累计行驶里程约为19.8万km。车主反映,该车刮水器偶尔会自动工作,且前照灯偶尔会自动点亮。 故障诊断 接车后试车发现,除了上述故障现象以外,当用遥控器…

【Linux】NAT、代理服务、内网穿透

NAT、代理服务、内网穿透 一. NAT1. NAT 技术2. NAT IP 转换过程3. NAPT 技术4. NAT 技术的缺陷 二. 代理服务器1. 正向代理2. 反向代理3. NAT 和代理服务器 内网穿透内网打洞 一. NAT NAT(Network Address Translation,网络地址转换)技术&a…

MobaXterm连接Ubuntu(SSH)

1.查看Ubuntu ip 打开终端,使用指令 ifconfig 由图可知ip地址 2.MobaXterm进行SSH连接 点击session,然后点击ssh,最后输入ubuntu IP地址以及用户名

Spring Boot系列之使用Arthas Tunnel Server 进行远程调试实践

Spring Boot系列之使用Arthas Tunnel Server 进行远程调试实践 前言 在开发和运维 Java 应用的过程中,远程诊断和调试是一个不可或缺的需求。尤其是当生产环境出现问题时,能够快速定位并解决这些问题至关重要。Arthas 是阿里巴巴开源的一款强大的 Java…

图像预处理-添加水印

一.ROI切割 类似裁剪图片,但是原理是基于Numpy数组的切片操作(ROI数组切片是会修改原图数据的),也就是说这个“裁剪”不是为了保存“裁剪”部分,而是为了方便修改等处理。 import cv2 as cv import numpy as npimg cv.imread(../images/dem…

数据结构——八大排序算法

排序在生活中应用很多,对数据排序有按成绩,商品价格,评论数量等标准来排序。 数据结构中有八大排序,插入、选择、快速、归并四类排序。 目录 插入排序 直接插入排序 希尔排序 选择排序 堆排序 冒泡排序 快速排序 hoare…

吃透LangChain(五):多模态输入与自定义输出

多模态数据输入 这里我们演示如何将多模态输入直接传递给模型。我们目前期望所有输入都以与OpenAl 期望的格式相同的格式传递。对于支持多模态输入的其他模型提供者,我们在类中添加了逻辑以转换为预期格式。 在这个例子中,我们将要求模型描述一幅图像。 …

【Rust 精进之路之第10篇-借用·规则】引用 (``, `mut`):安全、高效地访问数据

系列: Rust 精进之路:构建可靠、高效软件的底层逻辑 作者: 码觉客 发布日期: 2025年4月20日 引言:所有权的“限制”与“变通”之道 在上一篇【所有权核心】中,我们揭示了 Rust 如何通过所有权规则和移动 (Move) 语义来保证内存安全,避免了垃圾回收器的同时,也防止了诸…

剑指Offer(数据结构与算法面试题精讲)C++版——day16

剑指Offer(数据结构与算法面试题精讲)C版——day16 题目一:序列化和反序列化二叉树题目二:从根节点到叶节点的路径数字之和题目三:向下的路径节点值之和附录:源码gitee仓库 题目一:序列化和反序…

OpenCV 模板与多个对象匹配方法详解(继OpenCV 模板匹配方法详解)

文章目录 前言1.导入库2.图片预处理3.输出模板图片的宽和高4.模板匹配5.获取匹配结果中所有符合阈值的点的坐标5.1 threshold 0.9:5.2 loc np.where(res > threshold): 6.遍历所有匹配点6.1 loc 的结构回顾6.2 loc[::-1] 的作用6.2.1 为什么需要反转…

产品经理学习过程

一:扫盲篇(初始产品经理) 阶段1:了解产品经理 了解产品经理是做什么的、产品经理的分类、产品经理在实际工作中都会接触什么样的岗位、以及产品经理在实际工作中具体要做什么事情。 二:准备篇 阶段2:工…

【消息队列RocketMQ】一、RocketMQ入门核心概念与架构解析

在当今互联网技术飞速发展的时代,分布式系统的架构设计愈发复杂。消息队列作为分布式系统中重要的组件,在解耦应用、异步处理、削峰填谷等方面发挥着关键作用。RocketMQ 作为一款高性能、高可靠的分布式消息中间件,被广泛应用于各类互联网场景…

从“链主”到“全链”:供应链数字化转型的底层逻辑

1. 制造业与供应链数字化转型的必然性 1.1. 核心概念与战略重要性 制造业的数字化转型,是利用新一代数字技术(如工业互联网、人工智能、大数据、云计算、边缘计算等)对制造业的整体价值链进行根本性重塑的过程。这不仅涉及技术的应用&#…

x-ui重新申请ssl证书失败

由于某些需要我们重新申请ssl证书,x-ui自动化脚本不能强制更新,根据x-ui仓库源码: https://github.com/vaxilu/x-ui/blob/main/x-ui.sh 在申请ssl证书的地方稍作修改,得到,运行下面的脚本就可以重新申请ssl证书&#…

Java NIO Java 虚拟线程(微线程)与 Go 协程的运行原理不同 为何Go 能在低配机器上承接10万 Websocket 协议连接

什么是Java NIO? Java NIO(New Input/Output) 是Java 1.4(2002年)引入的一种非阻塞、面向缓冲区的输入输出框架,旨在提升Java在高性能和高并发场景下的I/O处理能力。它相比传统的 Java IO(java…

go环境安装mac

下载go安装包:https://golang.google.cn/dl/ 找到对应自己环境的版本下载。 注意有二进制的包,也有图形界面安装的包。图形界面直接傻瓜式点就行了。 二进制的按照下面操作: 1、下载二进制包。 2、将下载的二进制包解压至 /usr/local目录…

LVGL源码(9):学会控件的使用(自定义弹窗)

LVGL版本:8.3 LVGL的控件各式各样,每种控件都有自己的一些特性,当我们想要使用一个LVGL控件时,我们首先可以通过官网去了解控件的一些基本特性,官网链接如下: LVGL Basics — LVGL documentation&#xf…

《软件设计师》复习笔记(1)——考试介绍【新】

目录 一、考试介绍 证书价值 考试要求 二、【新】计算机与软件工程知识 三、软件设计 一、考试介绍 >考试科目>考题形式>考试时长>合格标准计算机与软件工程知识75道单选题(每题1分,总分75分)2023年11月改革机试后&#…

MCU中的BSS和data都占用SRAM空间吗?

在MCU中,BSS段和data段都占用SRAM空间,但它们的存储方式和用途有所不同。‌ BSS段 BSS段(Block Started by Symbol)用于存储未初始化的全局变量和静态变量。这些变量在程序启动时会被清零,因此它们不占用Flash空间&a…