数据库概论之MySQL表的增删改查 - 进阶版本1

news2024/12/24 0:01:01

MySQL表的增删改查 - 进阶

  • 1、数据库约束
    • 1.1 约束类型
    • 1.2 NULL约束
    • 1.3 UNIQUE约束
    • 1.4 DEFAULT约束
    • 1.5 PRIMARY约束
    • 1.6 FOREIGN KEY外键约束
      • 1.6.1 语法
      • 1.6.2 工作原理
  • 2、表的设计
    • 2.1 一对一
    • 2.2 一对多
    • 2.3 多对多

大家好,已经好久没更新了 , 学校的学业有点忙 , 没有额外的精力去进行更新了 , 假期开始了 , 我们也要开始努力了
数据库相对来说难度不是那么高,大家只要勤加练习、熟记语法,我相信学好数据库不是什么问题,博主会从0剖析,逐步讲解数据库的知识点,并且会举很多实例。最重要的是,博主不会采用软件,使用最原始的方式 -> 命令行来讲解,这样讲解的好处是逐个语句进行书写,不会造成读者思路跟不上的问题!
在这里插入图片描述

1、数据库约束

约束就是数据库在使用的时候,对于里面存储的数据提出的限制和要求,程序员可以通过约束来对数据进行更好的校验~

1.1 约束类型

约束类型说明
NOT NULL指示某列不能存储 NULL 值。
UNIQUE保证某列的每行必须有唯一的值。
DEFAULT规定没有给列赋值时的默认值。
PRIMARY KEYNOT NULLUNIQUE 的结合。确保某列(或两个列多个列的结合)有唯一标识,有助于更容易更快速地找到表中的一个特定的记录。
FOREIGN KEY保证一个表中的数据匹配另一个表中的值的参照完整性。
CHECK保证列中的值符合指定的条件。对于MySQL数据库,对CHECK子句进行分析,但是忽略CHECK子句。

以上这些约束,都是针对于某个列单独设置的。只是针对这个列来说是这样的,不同的列之间没有影响

1.2 NULL约束

NOT NULL:指示某列不能存储 NULL 值。 (数据不能为空)

正常情况下 , 一个表的每个字段是允许为空的

image-20220718221255639

当我们创建表的时候 , 指定某一列为 not null 的时候 , 我们就不能插入空值了

image-20220501112807064

当我们尝试插入空值的时候,就会报错
image-20220501112854658

NOT NULL还可以同时给多个列设置,不仅仅是一个列

image-20220501113844845

1.3 UNIQUE约束

UNIQUE :保证某列的每行必须有唯一的值。(数据唯一,插入的数据不能重复,是针对于列来说的)

默认情况下 , 表里面的数据是可以重复的

image-20220718222203680

当我们指定某一列为 unique 的话 , 插入重复的值就会报错

image-20220718222511496

那么当我们id都输入成1的时候,我们发现报错了。看一下错误信息:

ERROR 1062 (23000): Duplicate entry '1' for key 'id'

Duplicate:重复的

entry:条目(记录)

意思是:重复记录了值为1的id

我们之前就见过entryMap entrySet,此处的entry也是条目的意思。

Map里面存的是键值对,Map又没有实现Interable接口,如果想遍历一个Map就需要先把Map给转成SetSet里面的元素就叫做一个entry,就包含一个键和一个值

那么MySQL怎么发现新输入的数据是和之前的数据是重复的呢?其实这种这样的插入过程,是和之前学过的二叉树的插入过程是一样的,这里面的内容也和后面要讲的索引是相关联的。之后 , 我们再详细讲解 .

1.4 DEFAULT约束

DEFAULT :设定默认值。

默认的默认值是 NULL

image-20220501115150108

可以通过 default 约束来修改这里的默认值的取值 .

image-20220501115429753

我们仍然是只插入了id这一列,但是name使用的是我们的设置的默认值匿名人士

1.5 PRIMARY约束

PRIMARY KEYNOT NULLUNIQUE 的结合。确保某列(或两个列多个列的结合)有唯一标识,有助于更容易更快速地找到表中的一个特定的记录。

主键约束:相当于数据的唯一身份标识,类似于身份证号、学号

  1. 不能为空 : 相当于 not null
  2. 不能重复 : 相当于 unique
  3. 一个表里面只能有一个主键

这个是我们日常开发最常用的约束!

创建表的时候,很多时候都需要指定主键~

image-20220501115901154

注意事项 :

  1. 对于一个表来说,只有一个列能被指定为主键

    image-20220501120015506

  2. 设定为主键的,既不能为空,也不能重复

    image-20220501120805343

  3. 对于主键,最典型的用法就是直接使用1、2、3、4递增的方法来进行表示

  4. 由于主键必须要填 , 而且还不能重复 . MySQL 为我们提供了一个叫自增主键的方式 , 帮助我们自动生成主键的值

    用法:在主键后面加上auto_increment

    image-20220501121045132

    当我们设定好主键之后,此时插入的记录就可以不指定自增主键的值了(直接使用null表示即可),交给MySQL自己分配即可

    image-20220501121334857

    自增主键也可以手动指定id,一旦指定之后,后续插入的数据的id就是从你指定的数字之后来排的

    image-20220501121950564

    MySQL 要想进行自增 , 就要记录下来当前的 id 已经记录到哪里了 . 而且还要保证 , 自增之后必须是不重复的.

    那么 MySQL 里面简单粗暴的方法 , 就是直接记录当前自增主键里面的最大值 , 这样就能保证自增主键速度快还不重复 .

    虽然浪费了一定的存储资源 , 但是好处还是很多的 .

    对于这个浪费 , 其实只有在数据库里面有海量的数据里面 , 才会影响到正常的使用 .

    正常情况 , 数据库里面是基本没有那么多的数据的 .

    那么自增主键是要保证生成的 id 是唯一的 , 不重复的 . 但是如果数据库是分布式部署的(分布式的意思就是数据量太大 , 一台机器存不下 , 需要用多台设备来存储数据) , 这个时候自增主键就有可能出现问题

    MySQL服务器很容易就知道自己当前主机上 id 的最大值 , 但是有多台机器的话 , 就没办法保证了

    image-20220718224306294

    举个栗子 : 结婚随份子 , 你有可能提前给新娘新郎了 , 但是没给写礼账的人 , 新郎新娘也忘记了告诉写礼账的人 , 这样他们三个的信息就没互通 , 是不知道他们三个之间的最大值的

    所以 , MySQL 生成自增主键在分布式系统上就难以满足需求了

    程序员们又想到了一个办法 :

    唯一id = 时间戳(ms) + 机房编号/机器编号 + 随机因子
    //这里面的 + 代表字符串拼接,不是算数运算
    

    未来我们见到的分布式唯一 id 算法 , 就长这个样子 .

    往数据库中不断插入数据 , 插入数据的时间不同 , 时间戳也就不同 .

    假如说 , 恰巧在同一时间插入的 , 我们还可以通过机房编号/机器编号来区分.

    最后 , 再加上随机因子 , 这样重复的概率非常非常小了

    那就真的一模一样恰巧了 , 那么我们怎么办?

    错误思路 :

    再去生成一次不就得了

    那么你怎么知道这次生成的唯一id之前没生成过 , 你不得需要把之前生成的唯一id存储起来 , 那么查找不又浪费时间了吗.

    正确思路 :

    就这么地了! 因为一模一趟的概率真的是太小太小了 , 几乎近似于0了

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hDvK0Kpx-1670639701725)(https://jialebihaitao.oss-cn-beijing.aliyuncs.com/img/%E5%B0%8F%E7%8C%AB%E5%88%86%E9%9A%94%E7%AC%A6.png)]

注意:我们想要使用自增主键,就必须确保想操作的列必须是可以输入null的,即不能把这个列的约束设置成not null

image-20220501122518187

但是个人测试 , 这样子其实是可以的

image-20220718225449608

1.6 FOREIGN KEY外键约束

1.6.1 语法

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

外键约束其实就是针对两张表进行了关联。

外键约束,描述的就是两张表的两个列之间的"依赖关系",子表依赖于父表(子表引用自父表),要求子表当中对应记录得在父表当中存在

举个栗子:

image-20220501212957543

学生表依赖了班级表,那么我们就把学生表称为"子表",班级表称为"父表"

这种情况下就可以使用外键约束来描述这种关系

通过这个例子,我们需要知道:

每个学生都得有一个具体的班级,这个班级得存在!

如果学生表这里出现一个记录,班级id是1000,此时这样的数据就是非法的

来看一个例子:

首先,我们创建一个班级表,设定班级编号为主码约束。

image-20220501214136955

接下来构造一个学生表,来指定一下外键约束

create table student (studentId int primary key auto_increment,name varchar(20),classId int,foreign key(classId) references class(classId));
-- student表里面的classId 引用了 class表里面的classId列

image-20220501215151117

image-20220501215203996

我们接下来看两个表的结构

image-20220501215628967

我们可以来插入数据了

image-20220501215733078

此时我们可以发现,这条记录中指定的classId为1,在class表中存在的话,可以插入

在插入之前,MySQL会先拿着这个classIdclass表里面查询一下,看看是否存在,存在才插入成功

在父表为空的情况下 , 直接往子表里面插入数据是会报错的 .

image-20220718230548955

那么接下来,我们尝试插入一下classId为100的情况

image-20220501220012936

我们发现,插入失败~ 错误信息如下

ERROR 1452 (23000): Cannot add or update a child row: a foreign key constraint fails (`sql0423`.`student`, CONSTRAINT `student_ibfk_1` FOREIGN KEY (`classId`) REFERENCES `class` (`classId`))

image-20220501220501614

这条记录,指定的classId为100,在class表中不存在,不能插入成功

那么我们再试两组数据

image-20220501220737287

这两次插入,classId2和3均在class表的classId列中存在,因此就能插入成功

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0m1DPVMH-1670639701729)(https://jialebihaitao.oss-cn-beijing.aliyuncs.com/%E5%B0%8F%E7%8C%AB%E5%88%86%E9%9A%94%E7%AC%A6.png)]

那么不仅仅是新增的时候要考虑到外键约束,新增成功的数据如果进行修改,也是会失败的

image-20220501221030114

注:a child row代表子表

修改成功的案例:

image-20220501221153322

student表中的classId是可以重复存在的,只要在class表里面存在即可

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZyCIY1Ec-1670639701729)(https://jialebihaitao.oss-cn-beijing.aliyuncs.com/%E5%8D%9A%E5%AE%A2%E5%88%86%E9%9A%94%E7%AC%A6-%E6%9C%88%E4%BA%AE.png)]

外键约束,同样也约束着父表,当父表中的某个记录被子表依赖着的时候,此时尝试进行修改或者删除,也会出现错误

image-20220501221644792

a parent row :父表

那么正确写法是这样的:

image-20220501221813602

目前班级1里面是没有同学的,即没有被子表依赖,就可以修改或者删除。

注意:直接删表也是不行的

image-20220501221927293

1.6.2 工作原理

在子表中插入新的记录的时候,就会先根据对应的值,在父表中先查询,查询到之后才能够执行后续的插入

那么这里的查询操作,可能是一个成本较高的操作(比较耗时) . 如果查询操作触发了遍历表 , 这是十分低效的 . 但是查询触发了索引 , 这就相对快不少 .

外键约束其实要求,父表中被依赖的这一列,必须要有索引,有了索引就能大大的提高查询速度

那么这个索引,就是class表的classId这一列,需要是primary key或者unique(有了这俩约束的列,就会自动创建出索引了)

那么我们想象一个场景:淘宝购物

image-20220502093433367

按照上面描述的外键约束的关系,就可以认为 商品表就是父表,订单表就是子表,那么订单表中的商品id需要在商品表的商品id当中存在

那么我今天买了个衣服,穿着感觉不错,一段时间之后,准备再次入手,却发现这个商品下架了(也就是被商品表中删除了)。

我们刚才不是说外键约束,一旦约定好了外键约束关系,此时父表当中有关联的数据不是不能随便删除吗?(如果某个记录被子表依赖了,此时就无法删除了。)

那这是怎么回事?

其实我们采取的办法,不是真正的删除,而是逻辑上的删除

我们可以给商品表加一个列isOk,那么如果这一列值为1,就代表这是一条有效记录,如果这一列值为0,就代表这是一个无效记录(相当于被删除了)

那么有一个问题,假如删除的话,这也不是真的删除啊。只不过是isOk这一列被存为了0 , 那不还是占据了硬盘空间的吗 ?

实际上,现在硬盘空间不值钱,存了就存了。其实目前人力成本是会更高的。

2、表的设计

所谓了"数据库设计"、"表的设计"其实就是根据实际的问题场景,把表给创建出来了

那么给你一个问题场景,如何设计数据库?如何设计表?

一个好方法就是:先找出这个数据库场景当中涉及到的"实体"(对象),再找出它们之间的关系

一个典型的场景:

学生管理系统:

  1. 表示学生的基本信息
  2. 表示班级的基本信息
  3. 表示学生学习的课程的基本信息

对于咱们找到的实体来说,就需要创建对应的表来表示相关信息(那么每个实体表,里面的基本信息以及需求都是很好确定的),但是很多时候实体和实体之间并不是孤立的,而是存在对应关系。那么这样的对应关系,也需要体现在表中(实体之间的关系,这个是隐含的,需要我们挖掘出来,这里实体之间的不同的关系,会对表的设计产生影响)

其实分析实体之间的关系就是造句子

2.1 一对一

举个栗子:

以学校的教务系统为例:

student表(学生的id,学生姓名,学生班级…)

user表(用户的账户,密码…)

那么造的句子就是:一个账户对应一个学生,一个学生也只有一个账户

那么在数据库中,怎么表示一对一的关系呢?

方法一:可以把这两个实体用一张表表示

student(id,name,class,account,password);

方法二:可以用两张表来表示,其中一张表就包含了令一个表的id

​ 根据这个关系,就可以随时找到某个账户对应的学生是谁,也能找到某个学生对应的账户

image-20220503195234662

2.2 一对多

还是以学校的教务系统为例:

student表(学号,姓名…)

class表(班级编号,班级名称…)

那么造的句子就是:一个学生应该处于一个班级中,一个班级可以包含多个学生~

在数据库中,表示一对多的关系,也有两种典型方案:

方法一:在班级表当中,新增一列,表示这个班级里面的学生id组合

image-20220503203814927

但是像Redis这样的数据库,就有数组类型,就可以考虑这种方法

方法二:班级表不变,在学生表中新增一列classId

image-20220503204207785

2.3 多对多

又是以学校的教务系统为例:

学生表(学号,姓名)

课程表(课程编号,课程名字)

学生和课程就是多对多的关系

那么造的句子就是:一个学生,可以选多个课程,一个课程同时也能包含多个学生(M个学生,可以选择N门课)

多对多的关系在数据库中只有一种办法

使用一个关联表,来表示两个实体之间的关系

image-20220503210504280

有的时候,为了更方便的表示/找到 实体之间的联系(尤其是比较复杂的场景),我们还可以画E-R图(其实不咋用),但是学校必考!

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

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

相关文章

[论文解析] Denoising Diffusion Probabilistic Models

文章目录OverviewsWhat problem is addressed in the paper?What is the key to the solution?What is the main contribution?Contents扩散概率模型背景算法实验结论Overviews What problem is addressed in the paper? We present high quality image synthesis result…

【Java面试】说说类加载机制(流程)

文章目录加载流程装载(Load)链接(Link)验证(Verify)准备(Prepare)解析(Resolve)初始化(Initialize)卸载(Unload)加载流程 类的加载流程如下: 转载(Load)->链接(Link)->初始化(Initialize)->使用(Use)->卸载(Unload) 其中链接又包含验证(Verify)&#x…

rabbitMQ延时队列——TTL和DLX

一. 场景:“订单下单成功后,15分钟未支付自动取消” 1.传统处理超时订单 采取定时任务轮训数据库订单,并且批量处理。其弊端也是显而易见的;对服务器、数据库性会有很大的要求, 并且当处理大量订单起来会很力不从…

flask前后端项目--实例-前端部分:-4-vue-Element Plus

flask前后端项目--实例-前端部分:-4-vue-Element Plus组件添加事项 一、实验测试步骤 1.Element Plus添加 1.先备份App.VUE,然后修改app.vue的内容,数据来源资Element Plus的表格table 2. 数据来源资Element Plus的表格table 3. 运行服务&…

023_SSS_Neural 3D Video Synthesis from Multi-view Video(CVPR2022)

Neural 3D Video Synthesis from Multi-view Video(CVPR2022) 本文提出了一种新的3D视频生成方法,这种方法能够以紧凑但富有表现力的表示形式表示动态真实世界场景的多视图视频记录,从而实现高质量的视图合成和运动插值。 1. Introduction 本文的主要…

百度地图 ( 一 ) 显示地图

1.百度地图 百度地图开放平台 https://lbsyun.baidu.com/ 使用百度地图时导入JavaScript包 <script type"text/javascript" src"http://api.map.baidu.com/api?v2.0&ak您的密钥"></script>1.1.如何申请 ak 密钥 在 开发平台 找 控制…

ChatGPT注册流程

1.访问官网点击 Sign up https://chat.openai.com/auth/login 2.输入你的邮箱 3.点击Continue下一步: 4.输入密码继续下一步&#xff1a; 5.然后你的邮箱会受到一封邮件&#xff08;如果没收到请检查垃圾邮箱&#xff09;&#xff1a; 6.点击验证邮箱按钮&#xff0c;会跳到…

MySQL 5.7中文乱码与远程链接问题

MySQL 5.7中文乱码与远程链接问题1. MySQL 5.7中文乱码2. 远程链接问题3. 不区分表大小写4. 超过最大连接数5. 时区问题5. GROUP BY 问题配置集合重启MySQL1. MySQL 5.7中文乱码 当我们直接在数据库里面输入中文时&#xff0c;保存后出现&#xff1a; Incorrect string value&…

LeetCode 第 244 场周赛题解

前言 这是 2021-06-06 的一场 LeetCode 周赛&#xff0c;本场周赛的题目相较而以往而言比较简单&#xff0c;基本上想到点上就可以做出来&#xff0c;主要涉及到矩阵的旋转、贪心、滑动窗口、前缀和、二分查找等知识点。 第 244 场周赛链接&#xff1a;https://leetcode-cn.c…

SpringBoot+Vue实现前后端分离的学校快递站点管理系统

文末获取源码 开发语言&#xff1a;Java 使用框架&#xff1a;spring boot 前端技术&#xff1a;JavaScript、Vue.js 、css3 开发工具&#xff1a;IDEA/MyEclipse/Eclipse、Visual Studio Code 数据库&#xff1a;MySQL 5.7/8.0 数据库管理工具&#xff1a;phpstudy/Navicat JD…

机器人开发--雷达lidar

机器人开发--雷达lidar1 介绍2 分类2.1 整体分类2.2 机械式&#xff08;三角&ToF&#xff09;三角测距激光雷达ToF测距激光雷达3 机械式单线ToF激光雷达3.1 扫描原理3.2 不同材料反射率3.3 核心参数参考1 介绍 激光雷达&#xff08;英文&#xff1a;Laser Radar &#xff…

2023最新SSM计算机毕业设计选题大全(附源码+LW)之java制造类企业erp23725

面对老师五花八门的设计要求&#xff0c;首先自己要明确好自己的题目方向&#xff0c;并且与老师多多沟通&#xff0c;用什么编程语言&#xff0c;使用到什么数据库&#xff0c;确定好了&#xff0c;在开始着手毕业设计。 1&#xff1a;选择课题的第一选择就是尽量选择指导老师…

第十四周周报

学习目标&#xff1a; 一、论文“Vector Quantized Diffusion Model for Text-to-Image Synthesis”的Code 二、猫狗识别、人脸识别模型 学习内容&#xff1a; Code 学习时间&#xff1a; 12.4-12.9 学习产出&#xff1a; 一、论文Code 正向过程&#xff1a; 先通过Tam…

Python——学生管理系统

实现学生系统的增&#xff0c;删&#xff0c;查&#xff0c;打印所有学生功能&#xff0c;分别介绍使用列表存储和使用文件存储的代码 使用列表存储 import sys students []def menu():print("1. 新增学生")print("2. 显示学生")print("3. 查找学生…

【OpenCV学习】第10课:形态学操作的应用-图像去掉干扰线丶干扰点

仅自学做笔记用,后续有错误会更改 理论 去干扰线干扰点的操作方法&#xff0c; 大体上与第9课所说的提取水平/垂直线一致&#xff0c; 只是把核改为矩形&#xff0c; 不要线型就行&#xff0c;反正都是通过开操作来实行的。 操作流程&#xff1a; 输入图像&#xff08;一般是…

python数据分析:湖南省第七次人口普查可视化

前言 嗨喽~大家好呀&#xff0c;这里是魔王呐 ❤ ~ 今天案例难度指数: ☆☆☆ 准备 环境使用&#xff1a; Anaconda (python3.9) –> 识别我们写的代码 开发工具&#xff1a; jupyter notebook –> 代码编辑功能敲代码的工具 相关模块&#xff1a; pandas pyechart…

[附源码]计算机毕业设计基于Web的绿色环保网站Springboot程序

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

c# .net iot树莓派/香橙派用到物联网包Iot.Device.bindings 支持设备说明文档

c# .net iot树莓派&#xff08;进口&#xff0c;贵&#xff09;/香橙派&#xff08;国产&#xff0c;功能相同&#xff0c;性价比高&#xff09;用到物联网包Iot.Device.bindings 支持设备说明文档 我们c# .net iot开发树莓派/香橙派都需要用到Iot.Device.bindings、System.De…

RNA-seq 详细教程:假设检验和多重检验(8)

学习目标 了解模型拟合的过程比较两种假设检验方法&#xff08;Wald test vs. LRT&#xff09;了解多重测试校正的重要性了解用于多重测试校正的不同方法1. 模型拟合和假设检验 DESeq2 工作流程的最后一步是对每个基因进行计数并将其拟合到模型中并测试差异表达。 Hypothesis t…

osgEarth各个示例分析目录

概述 由于数字地球项目需要osgEarth的代码知识&#xff0c;故决定学习osgEarth的示例&#xff0c;示例中有很多可以借鉴的内容。以下是分析目录&#xff0c;完全是随机进行的&#xff0c;并没有什么上下文逻辑。 每一篇代码边学习边分析&#xff0c;如果有错误&#xff0c;请…