Java面试之孔乙己拒止攻略(2)——MYSQL篇

一、前言

其实,我们做的大多数系统都是数据库应用系统,up主的大学专业也是这个。对于这部分知识,确实有掌握的必要。然而,实际上这部分知识并不困难,大部分知识点看一眼就会了。
本篇打算包括以下几个方面:

  1. 数据库表的设计
  2. B+树
  3. Mysql的缓存和sql执行过程
  4. Mysql索引
  5. join优化
  6. 分库分表

二、3范式与反范式设计

2.1 第一范式

所有数据列都是不可再分的原子值,也就是每个字段都不可以再拆分成更小的单位。
PS:但实际上,有些字段可以很确定的不会用作查询条件,有些时候放个json进去也未尝不可;只不过,那些信息再添加字段时,会变得十分麻烦,有新旧数据结构不同的问题

表样例:

学号姓名系名系主任课程名分数
1李晓明经济系凯因斯高等数学95
1李晓明经济系凯因斯大学英语87
1李晓明经济系凯因斯普通化学76
2张莉莉经济系凯因斯高等数学72
2张莉莉经济系凯因斯大学英语98
2张莉莉经济系凯因斯计算机基础88
3高芳芳法律系刘诗韵高等数学82
3高芳芳法律系刘诗韵法律基础82

2.2 第二范式

在满足第一范式的基础上,非主键列完全依赖于主键列,而不是部分依赖。也就是说,一个表中的所有非主键字段必须完全依赖于主键,而不是只依赖于主键的某个部分。
简单来讲,就是符合第一范式,表中必须有主键,其他字段可由主键确定。二范式只是通过拆表来解决数据冗余。不能解决删除插入异常的问题。

表样例

学号课程名分数
1高等数学95
1大学英语87
1普通化学76
2高等数学72
2大学英语98
2计算机基础88
3高等数学82
3法律基础82
学号姓名系名系主任
1李晓明经济系凯因斯
2张莉莉经济系凯因斯
3高芳芳法律系刘诗韵

2.3 第三范式

在满足第二范式的基础上,所有非主键列之间没有依赖关系。也就是说,一个表中的任何非主键字段都不能依赖于其他非主键字段,而是必须依赖于主键字段。简单来说,就是拆分实体,形成主外键的关联。

表样例

学号课程名分数
1高等数学95
1大学英语87
1普通化学76
2高等数学72
2大学英语98
2计算机基础88
3高等数学82
3法律基础82
学号姓名系名
1李晓明经济系
2张莉莉经济系
3高芳芳法律系
系名系主任
经济系凯因斯
法律系刘诗韵

2.4 实体关系与代理主键

数据库中的实体关系通常有3种,1-1,1-n,n-n。
1-1可以用主键做关联;1-n两张表,多的一方设置外键,关联少的一方;n-n得3张表,其中维护一个引用表,持有双方的外键,维护2个表的关系。
在现代数据库中,尽量给实体设置代理主键,而不要以有意义的字段作为主键。

2.5 反范式设计

然而,在实际开发中,完全按照标准的三范式设计数据库,会使得数据库有太多的表,使得关系难以理清,并且在查询时需要大量的表连接,使得程序效率骤降,sql调优变得极其困难。在我的经验中,以下情况可以违反三范式做设计。

2.5.1 不常变动的数据做适当冗余

在有些时候,数据录入到数据库中,很少做改变。比如用户的用户名,项目的code,优惠券的名称,公司的名称等。在何其关联的表中,我们可以把这些信息冗余上,可以把多数连表查询改为单表查询。不过在这些字段更新时,需要记得一起更新关联表,在SpringBoot中可以用发消息的方式进行。

2.5.2 使用级联Id

在级联Id中,有2个常见的例子。一个是鉴权中的部门系统,通常会使用一个级联code的字符串,描述从根到当前节点的全路径,比如root-eng1-dep1。这样在查询某个部门的子孙节点时可以使用like root-eng1-dep1-%。
还有一个常见的情况,就是位置信息。也就是在哪个国家,哪个省,哪个市,哪个区。我们会创建的一个Location表,并且把Id规划好,哪几位表示省,哪几位表示市,哪几位表示区。当要查找在哪个市时,只需要用相关数学运算,就可以直接用Id做查找。

2.5.3 一些明确不需要做查询的复杂字段

有些时候,有些类似备注呀,设备属性呀,收货地址信息之类的字段,很明确的知道不会用作查询,并且有较复杂的层级关系时。这时我们可以把多个属性合成一个json字段。在获取字段时主义好判空操作即可。在SpringBoot中,也支持把这种json字段直接映射成为实体。

三、B树、B+树

3.1 内存中用于查找的数据结构

在内存中,我们的用于数据查找的数据结构,常常用这两种。哈希表和红黑树。
哈希表是把键算出一个哈希值,再映射到数组的某个槽中。当查找时,先计算哈希值,然后直接找到对应的槽,遍历到key值相同的元素时即可找到。这种数据结构的查找算法效率是n(1)。mysql的哈希索引,也只能在内存引擎中使用。
然而,哈希表这种数据结构,无法做排序运算,这时就需要用二叉查找树。二叉查找树保证每个节点只有2个子节点,左节点的值比自身小,右节点的值比自身大。红黑树是一个优化的二叉查找树,通过旋转等方法,使树尽可能平衡,也就让树的层数尽可能小,尽可能两边都有节点。红黑树的查找效率是lg(n)

B树与B+树

然而在数据库中,磁盘的数据读取并不是一个内存的随机访问。硬件通常一次读取一大批连续的数据。而在内存的红黑树中,一个节点才放3个数据,而磁盘一次读取可以读一个逻辑块,通常是4KB,这显然不匹配。
于是B树和B+树算法就产生了。mysql的一个节点会存放16KB的数据,并根据估算来计算每个节点存放的数据行数量。
那么,B树的定义就成了每个节点的子节点引用放在一个数组中,数组元素根据主键值有序排列。每个节点维护其处理的数据范围。
而B+数则是,只有在叶子节点存放数据,以减少回表,减少数据库IO次数。
Mysql的innodb使用的是B+树,之前的MyISAM使用的是B树,主键索引和数据分属于不同的文件。
在这里插入图片描述

四、Mysql的buffer pool

4.1 什么是buffer pool

Buffer Pool是MySQL中InnoDB存储引擎的一种内存缓存机制,用于加速对磁盘上数据的访问。具体来说,Buffer Pool是一块内存区域,其中存储了最近使用的数据页的副本,这些数据页通常是磁盘上的数据文件的一部分。在MySQL需要读取或写入磁盘上的数据时,会首先查找Buffer Pool中是否存在该数据页的副本,如果存在,则直接从内存中读取或写入数据,避免了频繁的磁盘访问。

Buffer Pool中存放的是InnoDB存储引擎的数据页,包括索引页、数据页、undo页等。其中,索引页用于存放B+树索引的节点数据,数据页用于存放表中的行数据,undo页用于存放事务回滚信息等。

Buffer Pool中存储的数据是以数据页为单位进行管理的,每个数据页的大小通常是16KB。在MySQL启动时,Buffer Pool会从操作系统中申请一块连续的内存区域作为缓存区域,并将其划分为多个数据页。当InnoDB需要访问磁盘上的数据时,它会首先查找Buffer Pool中是否存在该数据页,如果存在,则直接读取缓存中的数据;如果不存在,则从磁盘上读取该数据页,并将其存储到Buffer Pool中。

4.2 一个sql语句如何被定为到数据页上

当MySQL接收到一个SQL语句时,它会首先通过解析器将该语句分解为语法树,然后通过优化器对语法树进行分析和优化,生成一个查询计划。在生成查询计划的过程中,MySQL会根据表的统计信息、索引信息以及其他一些因素,选择最优的查询策略和执行计划。

在执行查询计划时,MySQL需要访问表中的数据页,并将其加载到Buffer Pool中。当MySQL需要访问某个数据页时,它会首先检查该数据页是否已经在Buffer Pool中缓存,如果已经缓存,则直接从Buffer Pool中读取数据;如果没有缓存,则需要从磁盘上读取该数据页,并将其存储到Buffer Pool中,然后再从Buffer Pool中读取数据。数据页中有个类似哈希表的数据结构,它使用表空间号+数据页号作为一个key,然后缓冲页对应控制块作为value。

KEYVALUE
表空间+页号对应控制块
表空间+页号对应控制块
。。。。。。

因此,MySQL并不需要事先知道哪些数据页可能会被使用,而是在查询执行的过程中动态地加载和使用数据页。如果某个数据页在查询过程中没有被使用,那么在Buffer Pool空间不足时,该数据页可能会被淘汰出缓存区,释放空间供其他数据页使用。

4.3 buffer pool的几个特性

  • LRU算法:
    Buffer Pool中的数据页会按照最近使用时间进行排序,最近使用的数据页会被优先保留在内存中,而较长时间未使用的数据页则可能会被淘汰出内存,释放空间。这种淘汰算法被称为LRU(Least Recently Used)算法。
  • 预读机制:
    MySQL在读取磁盘上的数据页时,不仅会读取当前需要的数据页,还会预先读取相邻的一些数据页,以便在下次查询时可以直接从Buffer Pool中读取这些数据页,提高查询性能。
  • 脏页管理:
    当MySQL修改一个数据页时,该页会被标记为“脏页”,表示该页的内容已经被修改但尚未同步到磁盘上。MySQL会定期将脏页同步到磁盘上,以保证数据的持久性和一致性。如果Buffer Pool中的空间不足,MySQL可能会选择先淘汰一些脏页,以腾出空间存储新的数据页。
    Buffer Pool的大小是可以通过配置参数进行调整的,key值为innodb_buffer_pool_size。如果把该值大小设置的比较大,其实就可以把mysql当成一个内存数据库用。在实际开发中,我们可以把一些常访问的数据放到一个数据库服务器中,并把该服务器配置较大内存。

4.4 网上搬运的mysql innodb架构

在这里插入图片描述
在这里插入图片描述

五、结语

这篇虽然是孔乙己拒止攻略,但mysql作为应用开发最多接触的中间件,确实有必要深入了解其底层原理。这样子在编码和优化时才会有更广阔的思路,对性能瓶颈也有更深刻的认识。
本篇的内容用chatgpt辅助编写,参考了一些其他人的博客,以及B站上的一篇讲mysql面试的视频

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

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

相关文章

Rocky和ChatGPT谈笑风生的日子 |【AI行研商业价值分析】

Rocky Ding 公众号:WeThinkIn 写在前面 【AI行研&商业价值分析】栏目专注于分享AI行业中最新热点/风口的思考与判断。也欢迎大家提出宝贵的意见或优化ideas,一起交流学习💪 大家好,我是Rocky。 近日,ChatGPT风光无…

Github每日精选(第97期): 类似ChatGPT 的开源AI 聊天ChatRWKV

ChatRWKV 类似于 ChatGPT,但由 RWKV(100% RNN)语言模型提供支持,并且是开源的。 github地址 ChatRWKV 类似于 ChatGPT,但由我的 RWKV(100% RNN)语言模型提供支持,这是目前唯一可以在…

揭秘 ChatGPT 背后的技术栈:将Kubernetes扩展到2500个节点

揭秘 ChatGPT 背后的技术栈:将Kubernetes扩展到2500个节点 etcdKube mastersDocker image 推送NetworkingARP cache 在本文中,OpenAI 的工程师团队分享了他们在 Kubernetes 集群扩展过程中遇到的各种挑战和解决方案,以及他们取得的性能和效果…

半天就行!教你用ChatGPT开发小程序;谁能做出中国的Discord?LangChain中文入门教程;一个周末搞定电影预告片的AI工作流 | ShowMeAI日报

👀日报&周刊合集 | 🎡生产力工具与行业应用大全 | 🧡 点赞关注评论拜托啦! 🤖 『Discord和它的中国「学徒」们』为什么还没有人跑出来? ShowMeAI知识星球资料分类「下资料」,编号「R080」 D…

2023最新ChatGPT3.0小程序/云开发无需服务器开源Vue自带API接口

正文: ChatGPT3.0小程序,云开发无需服务器开源vue自带接口,界面的UI也是比较还原官方的了,就连颜色都是一摸一样的,有兴趣的自行去安装体验吧,其它就没什么好介绍的了。 程序: wwxgus.lanzoum.com/iLfKe0otvx5i 图片:

2023 首发 ChatGPTv3.0多端小程序开源源码 云开发无需服务器 带接口

云开发无需服务器开源vue自带接口! 全开源vue 自带接口 上传即可使用! 无需服务器 后续会更新流量主版本! 。。。。

2023最新VUE开发的ChatGPT3.5全开源小程序源码+功能强大/UI也不错

正文: 所需环境 uniapp nodejs 搭建教学 首先前端源码下载下来,用idea源码编辑器打开,只需要修改配置文件中的请求api(request/request.js),需要搭建好后端请求 1.服务器配置 centos7.9 2.宝塔面板安装宝塔 3.如果在线下载…

获取了文心一言的内测及与其ChatGPT、GPT-4 对比结果

百度在3月16日召开了关于文心一言(知识增强大语言模型)的发布会,但是会上并没现场展示demo。如果要测试的文心一言 也要获取邀请码,才能进行测试的。 我这边通过预约得到了邀请码,大概是在3月17日晚就收到了&#xff…

搭建人工智能wx机器人完整版教程

参考搭建流程 首先需要下载Ubuntu 20.04 镜像包 阿里云开源镜像包 下载方式: 打开以上网站-->点击20.04/-->点击ubuntu-20.04.5-live-server-amd64.iso下载 项目开源地址 https://github.com/zhayujie/chatgpt-on-wechat NxShell下载地址 https://xiaodao.lan…

【微信小程序】微信小程序的接口调入 获取太阳码 根据返回值的类型进行接收,微信接口可能直接返回图片,也可能返回一个错误信息的json,同时兼容处理这两种情况

目录 事件起因环境和工具操作过程解决办法遇到的一点问题结束语 事件起因 在开发一个关于微信小程序的过程中,有一个这样的需求,要求生成微信小程序的太阳码,然而这个东西的请求方式我们是这样的:我作为后端服务去请求这个太阳码…

如何设计开放平台接口与集成chatgpt

如何设计开放平台接口与集成chatgpt 文章目录 如何设计开放平台接口与集成chatgpt前言一、Token机制生成方式有哪些session存在的问题JWT如何解决session存在的问题 二、AppId、AppSecretAppId机制签名机制 三 码上实现客户端注意 源码地址配置 前言 前一段时间,突…

ChatGPT研究(二)——ChatGPT助力跨模态AI生成应用

✏️写作:个人博客,InfoQ,掘金,知乎,CSDN 📧公众号:进击的Matrix 🚫特别声明:创作不易,未经授权不得转载或抄袭,如需转载可联系小编授权。 前言 …

《花雕学AI》12:从ChatGPT的出现看人类与人工智能的互补关系与未来发展

马云说道,ChatGPT这一类技术已经对教育带来挑战,但是ChatGPT这一类技术只是AI时代的开始。 谷歌CEO桑德尔皮猜曾说:“人工智能是我们人类正在从事的最为深刻的研究方向之一,甚至要比火与电还更加深刻。” 360周鸿祎认为&#xf…

论文谷歌翻译:SinGAN(代码开源)

论文地址:https://arxiv.org/abs/1905.01164 代码地址:http://webee.technion.ac.il/people/tomermic/SinGAN/SinGAN.htm 摘要 提出了 SinGAN,这是一个可以从单张自然图像学习的非条件性生成式模型。模型可以捕捉给定图像中各个小块内的内在…

最好最常用的国外邮箱推荐!注册非常简单!

大家都知道,接送和发送电子邮件是我们日常不可避免的,不管是个人也好,企业也好,都需要邮箱来处理一些东西。 当然现在的通讯比较发达,打电话、短信、QQ或者微信都可以进行交流沟通,也可以发送些简单的文件…

编译器技术的演进与变革

在过去的数十年里,摩尔定律一直支配着半导体行业的发展路线,随着晶体管尺寸的不断变小单个芯片上集成的晶体管数量越来越多。 最新的 NVIDIA A100 GPU 单个芯片集成了 540 亿个晶体管,而嵌入式系统级芯片(System on Chip&#xff…

2023年美赛A题赛后总结

文章目录 心路历程1. 选题2. 初次建模3. 数据收集4. 二次建模5. 算法实现以及优化6.全英论文撰写 总结 心路历程 2023年美赛是在2月17号早上6点到2月21号早上8点这期间举行的,美赛开赛前一天我们三个人还在考期末考,甚至美赛刚开始前两天有位队友每天还…

概率统计极简入门:通俗理解微积分/期望方差/正态分布前世今生(23修订版)

原标题:数据挖掘中所需的概率论与数理统计知识(12年首次发布,23年重编公式且反复改进) 修订背景 本文初稿发布于12年年底,十年后的22年底/23年初ChatGPT大火,在写ChatGPT通俗笔记的过程中,发现ChatGPT背后技术涉及到了…

ChatGPT 插件(八个插件,个个优秀)

webpilot——联网搜索图片、视频、文档、人脉等 1. 有哪些免费的高清无版权的图片网站,请从这些网站里找一些图片给我,图片搜索关键词为:Shanghai aerial,把图片的url链接发我; 2. 有哪些免费的GIF图片网站,请从这些网…

从ChatGPT看AI未来趋势和挑战 | 万字长文

ChatGPT 持续成为大家关注的焦点,开启通用人工智能(AGI)之门。北京交通大学桑基韬教授和于剑教授撰写的《从ChatGPT看AI未来趋势和挑战》,详述了ChatGPT 的“能”与“不能”,AI中什么是“真”以及AI的未来趋势,非常值得关注&#…