- 存储引擎
主要负责数据的存储和读取,采用可以替换的插件式架构,支持 InnoDB
、MyISAM
、Memory
等多个存储引擎,其中 InnoDB 引擎有自有的日志模块 redolog 模块。现在最常用的存储引擎是 InnoDB,它从 MySQL 5.5.5 版本开始就被当做默认存储引擎了。
附:更加详细的功能可以参考 Server 层基本组件介绍
-
第一范式:确保每列保持原子性,数据表中的所有字段值都是不可分解的原子值
-
第二范式:要求实体的属性完全依赖于主关键字。所谓完全依赖是指不能存在仅依赖主关键字一部分的属性。也就是说确保表中的每列都和主键相关
-
第三范式:任何非主属性不依赖于其它非主属性。也就是说确保每列都和主键列直接相关而不是间接相关
-
首先应用程序把查询SQL语句发送给服务器端执行
-
查询缓存,如果查询缓存是打开的,服务器在接收到查询请求后,并不会直接去数据库查询,而是在数据库的查询缓存中找是否有相对应的查询数据,如果存在,则直接返回给客户端。只有缓存不存在时,才会进行下面的操作
-
查询优化处理,生成执行计划。这个阶段主要包括解析SQL、预处理、优化SQL执行计划
-
MySQL根据相应的执行计划完成整个查询
-
最后将查询结果返回给客户端
👩💻面试官追问:那你在说说MySQL查询的指令执行顺序?
编写顺序:
SELECT DISTINCT
FROM
<left_table> <join_type>
JOIN
<right_table> ON <join_condition>
WHERE
<where_condition>
GROUP BY
<group_by_list>
HAVING
<having_condition>
ORDER BY
<order_by_condition>
LIMIT
<limit_params>
执行顺序:
大致可以分为四类:
- 整数
TINYINT
、SMALLINT
、MEDIUMINT
、INT
、BIGINT
分别占用8、16、24、32、64位存储空间。
- 浮点数
FLOAT
、DOUBLE
及DECIMAL
为浮点数类。
-
DECIMAL是利用字符串进行处理的,能存储精确的小数。相比于FLOAT和DOUBLE,DECIMAL的效率更低些。
-
FLOAT、DOUBLE及DECIMAL都可以指定列宽,例如FLOAT(5,2)表示一共5位,两位存储小数部分,三位存储整数部分。
- 字符串
字符串常用的主要有CHAR
和VARCHAR
- 日期
比较常用的有year
、time
、date
、datetime
、timestamp
等
👩💻面试官追问:详细说一下MySQL中char 和 varchar 的区别?
-
char∶固定长度类型,比如︰订阅char(10),当你输入"abc"三个字符的时候,它们占的空间还是10个字节,其他7个是空字节。
-
优点∶效率高
-
缺点∶占用空间
-
适用场景︰存储密码的md5值,固定长度的,使用char非常合适
-
varchar︰可变长度,
存储的值是=每个值占用的字节+一个用来记录其长度的字节的长度
从空间上考虑varchar比较合适。从效率上考虑char比较合适,二者使用需要权衡。
表格对比:
| 对比项 | char | varchar |
| — | — | — |
| 长度特点 | 长度固定,存储字符 | 长度可变,存储字符 |
| 长度不足情况 | 插入的长度小于定义长度时,则用空格填充 | 小于定义长度时,按实际插入长度存储 |
| 性能 | 存取速度比varchar快得多 | 存取速度比char慢得多 |
| 使用场景 | 适合存储很短的,固定长度的字符串,如手机号,MD5值等 | 适合用在长度不固定场景,如收货地址,邮箱地址等 |
👩💻面试官继续问:详细说一下MySQL中字段类型DATETIME 和 TIMESTA的区别?
| 类型 | 占据字节 | 范围 | 时区问题 |
| — | — | — | — |
| datetime | 8 字节 | 1000-01-01 00:00:00到 9999-12-31 23:59:59 | 存储与时区无关,不会发生改变 |
| timestamp | 4 字节 | 1970-01-01 00:00:01 到 2038-01-19 11:14:07 | 存储的是与时区有关,随数据库的时区而发生改变 |
应该尽量使用timestamp
,相比于datetime
它有着更高的空间效率
| 对比 | InnoDB | MyISAM |
| — | — | — |
| 事务 | 支持 | 不支持 |
| 锁类型 | 行锁、表锁 | 表锁 |
| MVCC | 支持 | 不支持 |
| 外键 | 支持 | 不支持 |
| 索引 | 聚簇索引、5.7以后支持全文索引 | 非聚簇索引、支持全文索引 |
| 安全性 | 支持数据库异常崩溃后的安全恢复 | 不支持 |
| 缓存 | 仅缓存索引,还缓存真实数据,对内存要求较高 | 只缓存索引,不缓存真实数据 |
| 备份 | InnoDB 支持在线热备份 | 不支持 |
👩💻面试官追问:平时选择存储引擎的时候这两个怎么取舍?
InnoDB
是Mysql的默认存储引擎,用于事务处理应用程序,支持外键。如果应用对事务的完整性有比较高的要求,在并发条件下要求数据的一致性,数据操作除了插入和查询意外,还包含很多的更新、删除操作,那么InnoDB存储引擎是比较合适的选择。对于类似于计费系统或者财务系统等对数据准确性要求比较高的系统,InnoDB是最合适的选择。
MyISAM
如果应用是以读操作和插入操作为主,只有很少的更新和删除操作,并且对事务的完整性、并发性要求不是很高,那么选择MyISAM存储引擎是非常合适的
-
Buffer Pool
是InnoDB
维护的一个缓存区域,用来缓存数据和索引在内存中,主要用来加速数据的读写,如果 Buffer Pool 越大,那么 MySQL 就越像一个内存数据库,默认大小为128M
。 -
InnoDB 会将那些热点数据和一些 InnoDB 认为即将访问到的数据存在 Buffer Pool 中,以提升数据的读取性能。
-
InnoDB 在修改数据时,如果数据的页在 Buffer Pool 中,则会直接修改 Buffer Pool,此时我们称这个页为脏页,InnoDB 会以一定的频率将脏页刷新到磁盘,这样可以尽量减少磁盘I/O,提升性能。
============================================================
索引是一种用于快速查询和检索数据的数据结构。常见的索引结构有: B 树, B+树和 Hash。
索引的作用就相当于目录的作用。打个比方:我们在查字典的时候,如果没有目录,那我们就只能一页一页的去找我们需要查的那个字,速度很慢。如果有目录了,我们只需要先去目录里查找字的位置,然后直接翻到那一页就行了。
👩💻面试官追问:说说索引的优缺点?
优点 :
-
使用索引可以大大加快数据的检索速度(大大减少检索的数据量), 这也是创建索引的最主要的原因
-
通过创建唯一性索引,可以保证数据库表中每一行数据的唯一性
缺点 :
-
从时间角度考虑。创建索引和维护索引需要耗费许多时间。当对表中的数据进行增删改的时候,如果数据有索引,那么索引也需要动态的修改,会降低 SQL 执行效率
-
从空间角度考虑。索引需要使用物理文件存储,也会耗费一定磁盘空间
👩💻面试官继续问:说说哪些情况适合建立索引哪些不适合?
适合建立索引:
-
在最频繁使用的、用以缩小查询范围的字段上建立索引
-
在频繁使用的、需要排序的字段上建立索引
不适合建立索引的情况:
-
对于查询中很少涉及的列或者重复值比较多的列,不宜建立索引
-
对于一些特殊的数据类型,不宜建立索引,比如︰**文本字段(text)**等
- 主键索引
数据表的主键列使用的就是主键索引。一张数据表有只能有一个主键,并且主键不能为 null,不能重复。
- 唯一索引(Unique Key)
唯一索引也是一种约束。唯一索引的属性列不能出现重复的数据,但是允许数据为 NULL,一张表允许创建多个唯一索引。 建立唯一索引的目的大部分时候都是为了该属性列的数据的唯一性,而不是为了查询效率。
- 普通索引(Index)
普通索引的唯一作用就是为了快速查询数据,一张表允许创建多个普通索引,并允许数据重复和 NULL。
- 前缀索引(Prefix)
前缀索引只适用于字符串类型的数据。前缀索引是对文本的前几个字符创建索引,相比普通索引建立的数据更小, 因为只取前几个字符。
- 全文索引(Full Text)
全文索引主要是为了检索大文本数据中的关键字的信息,是目前搜索引擎数据库使用的一种技术。(Mysql5.6 之前只有 MYISAM 引擎支持全文索引,5.6 之后 InnoDB 也支持了全文索引)
其中唯一索引、普通索引、前缀索引、全文索引又称为二级索引(辅助索引)
-
B+Tree 索引
-
是大多数 MySQL 存储引擎的默认索引类型。
-
哈希索引
-
哈希索引能以 O(1) 时间进行查找,但是失去了有序性。
-
InnoDB 存储引擎有一个特殊的功能叫“自适应哈希索引”,当某个索引值被使用的非常频繁时,会在 B+Tree 索引之上再创建一个哈希索引,这样就让 B+Tree 索引具有哈希索引的一些优点,比如快速的哈希查找。
-
全文索引
-
MyISAM 存储引擎支持全文索引,用于查找文本中的关键词,而不是直接比较是否相等。查找条件使用 MATCH AGAINST,而不是普通的 WHERE。
-
全文索引一般使用倒排索引实现,它记录着关键词到其所在文档的映射。
-
InnoDB 存储引擎在 MySQL 5.6.4 版本中也开始支持全文索引。
-
空间数据索引
-
MyISAM 存储引擎支持空间数据索引(R-Tree),可以用于地理数据存储。空间数据索引会从所有维度来索引数据,可以有效地使用任意维度来进行组合查询。
InnoDB、MyISAM、Memory三种存储引擎对各种索引类型的支持:
| 索引 | InnoDB引擎 | MyISAM引擎 | Memory引擎 |
| — | — | — | — |
| B+Tree 索引 | 支持 | 支持 | 支持 |
| 哈希索引 | 不支持 | 不支持 | 支持 |
| 空间数据索引 | 不支持 | 支持 | 不支持 |
| 全文索引 | 5.6版本之后支持 | 支持 | 不支持 |
-
B+树是基于B树和叶子节点顺序访问指针进行实现,它具有B树的平衡性,并且通过顺序访问指针来提高区间查询的性能
-
进行查找操作时,首先在根节点进行二分查找,找到一个key所在的指针,然后递归地在指针所指向的节点进行查找。直到查找到叶子节点,然后在叶子节点上进行二分查找,找出key所对应的data
-
插入、删除操作会破坏平衡树的平衡性,因此在插入删除操作之后,需要对树进行一个分裂、合并、旋转等操作来维护平衡性
👩💻面试官追问:那你说说B 树和B+树两者有何异同呢?
B树结构图:
可以看出:
-
B 树的所有节点既存放键(key) 也存放数据(data),而 B+树只有叶子节点存放 key 和 data,其他内节点只存放 key。
-
B 树的叶子节点都是独立的,B+树的叶子节点有一条引用链指向与它相邻的叶子节点。
-
B 树的检索的过程相当于对范围内的每个节点的关键字做二分查找,可能还没有到达叶子节点,检索就结束了。而 B+树的检索效率就很稳定了,任何查找都是从根节点到叶子节点的过程,叶子节点的顺序检索很明显。
👩💻面试官追问:为什么MySQL数据库要用B+树存储索引?而不用红黑树、Hash、B树?
- 红黑树
如果在内存中,红黑树的查找效率比B树更高,但是涉及到磁盘操作,B树就更优了。因为红黑树是二叉树,数据量大时树的层数很高,从树的根结点向下寻找的过程,每读1个节点,都相当于一次IO操作,因此红黑树的I/O操作会比B树多的多。
- hash 索引
如果只查询单个值的话,hash 索引的效率非常高。但是 hash 索引有几个问题:①不支持范围查询 ②不支持索引值的排序操作 ③不支持联合索引的最左匹配规则。
-
B树索引
-
B树索相比于B+树,在进行范围查询时,需要做局部的中序遍历,可能要跨层访问,跨层访问代表着要进行额外的磁盘I/O操作
-
B树的每个节点都存储数据,而B+树只有叶子节点才存储数据,所以查找相同数据量的情况下,B树的高度更高,IO更频繁。
-
以页为单位读取使得一次 I/O 就能完全载入一个节点,且相邻的节点也能够被预先载入;所以数据放在叶子节点,本质上是一个Page页
👩💻面试官继续追问:B+树中一个节点到底多大合适?
1页或页的倍数最为合适。因为如果一个节点的大小小于1页,那么读取这个节点的时候其实也会读出1页,造成资源的浪费。所以为了不造成浪费,所以最后把一个节点的大小控制在1页、2页、3页等倍数页大小最为合适。
这里说的“页”是 MySQL 自定义的单位(和操作系统类似),MySQL 的 Innodb
引擎中1页的默认大小是16k
,可以使用命令SHOW GLOBAL STATUS LIKE 'Innodb_page_size'
查看。
- 聚集索引:即索引结构和数据一起存放的索引。主键索引属于聚集索引
在 Mysql 中,InnoDB 引擎的表的
.ibd
文件就包含了该表的索引和数据,对于 InnoDB 引擎表来说,该表的索引(B+树)的每个非叶子节点存储索引,叶子节点存储索引和索引对应的数据
- 非聚集索引:即索引结构和数据分开存放的索引。二级索引属于非聚集索引
MYISAM 引擎的表的
.MYI
文件包含了表的索引, 该表的索引(B+树)的每个非叶子节点存储索引, 叶子节点存储索引和索引对应数据的指针,指向.MYD
文件的数据。
如图:
如上图,主键索引的叶子节点保存的是真正的数据。而辅助索引叶子节点的数据区保存的是主键索引关键字的值
假如要查询name = C 的数据,其搜索过程如下:
-
先在辅助索引中通过C查询最后找到主键id = 9
-
在主键索引中搜索id为9的数据,最终在主键索引的叶子节点中获取到真正的数据。所以通过辅助索引进行检索,需要检索两次索引
之所以这样设计,一个原因就是:如果和MyISAM一样在主键索引和辅助索引的叶子节点中都存放数据行指针,一旦数据发生迁移,则需要去重新组织维护所有的索引
👩💻面试官追问:聚集索引的优缺点有哪些?
- 聚集索引的优点
聚集索引的查询速度非常的快,因为整个B+树本身就是一颗多叉平衡树,叶子节点也都是有序的,定位到索引的节点,就相当于定位到了数据。
- 聚集索引的缺点
- 依赖于有序的数据
因为 B+树是多路平衡树,如果索引的数据不是有序的,那么就需要在插入时排序,如果数据是整型还好,否则类似于字符串或 UUID 这种又长又难比较的数据,插入或查找的速度肯定比较慢
- 更新代价大
如果对索引列的数据被修改时,那么对应的索引也将会被修改, 而且聚集索引的叶子节点还存放着数据,修改代价肯定是较大的, 所以对于主键索引来说,主键一般都是不可被修改的
👩💻面试继续问:非聚集索引的优缺点有哪些?
- 非聚集索引的优点
更新代价比聚集索引要小 。非聚集索引的更新代价就没有聚集索引那么大了,非聚集索引的叶子节点是不存放数据的
- 非聚集索引的缺点
-
跟聚集索引一样,非聚集索引也依赖于有序的数据
-
可能会二次查询(回表)。这应该是非聚集索引最大的缺点了。 当查到索引对应的指针或主键后,可能还需要根据指针或主键再到数据文件或表中查询
👩💻面试继续追问:非聚集索引一定回表查询吗?
不一定,原因详细看下面第6问
覆盖索引:指的是在一次查询中,如果一个索引包含或者说覆盖所有需要查询的字段的值,我们就称之为覆盖索引,而不再需要回表查询
覆盖索引即需要查询的字段正好是索引的字段,那么直接根据该索引,就可以查到数据了, 而无需回表查询。
举个栗子:
-
如主键索引,如果一条 SQL 需要查询主键,那么正好根据主键索引就可以查到主键。
-
再如普通索引,如果一条 SQL 需要查询 name,name 字段正好有索引, 那么直接根据这个索引就可以查到数据,也无需回表。
============================================================
事务是用户定义的一个数据库操作序列,这些操作要么全不做,要么全做,是一个不可分割的工作单位。
举个栗子:就拿最经典的转账例子来说,假如小明要给小红转账1000元,这个转账会涉及到两个关键操作就是:将小明的余额减少1000元,将小红的余额增加1000元。万一在这两个操作之间突然出现错误比如银行系统崩溃,导致小明余额减少而小红的余额没有增加,这样就不对了。事务就是保证这两个关键操作要么都成功,要么都要失败。
- 原子性(Atomicity)
事务是最小的执行单位,不允许分割。事务的原子性确保事务所有的操作要么全部提交成功,要么全部失败回滚。
- 一致性(Consistency)
执行事务前后,数据保持一致,例如转账业务中,无论事务是否成功,转账者和收款人的总额应该是不变的。
- 隔离性(Isolation)
并发访问数据库时,一个用户的事务不被其他事务所干扰,各并发事务之间数据库是独立的。
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数Java工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
如果你觉得这些内容对你有帮助,可以扫码获取!!(备注Java获取)

写在最后
作为一名即将求职的程序员,面对一个可能跟近些年非常不同的 2019 年,你的就业机会和风口会出现在哪里?在这种新环境下,工作应该选择大厂还是小公司?已有几年工作经验的老兵,又应该如何保持和提升自身竞争力,转被动为主动?
就目前大环境来看,跳槽成功的难度比往年高很多。一个明显的感受:今年的面试,无论一面还是二面,都很考验Java程序员的技术功底。
最近我整理了一份复习用的面试题及面试高频的考点题及技术点梳理成一份“Java经典面试问题(含答案解析).pdf和一份网上搜集的“Java程序员面试笔试真题库.pdf”(实际上比预期多花了不少精力),包含分布式架构、高可扩展、高性能、高并发、Jvm性能调优、Spring,MyBatis,Nginx源码分析,Redis,ActiveMQ、Mycat、Netty、Kafka、Mysql、Zookeeper、Tomcat、Docker、Dubbo、Nginx等多个知识点高级进阶干货!
由于篇幅有限,为了方便大家观看,这里以图片的形式给大家展示部分的目录和答案截图!
Java经典面试问题(含答案解析)
阿里巴巴技术笔试心得
《一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码》,点击传送门即可获取!
程序员,面对一个可能跟近些年非常不同的 2019 年,你的就业机会和风口会出现在哪里?在这种新环境下,工作应该选择大厂还是小公司?已有几年工作经验的老兵,又应该如何保持和提升自身竞争力,转被动为主动?
就目前大环境来看,跳槽成功的难度比往年高很多。一个明显的感受:今年的面试,无论一面还是二面,都很考验Java程序员的技术功底。
最近我整理了一份复习用的面试题及面试高频的考点题及技术点梳理成一份“Java经典面试问题(含答案解析).pdf和一份网上搜集的“Java程序员面试笔试真题库.pdf”(实际上比预期多花了不少精力),包含分布式架构、高可扩展、高性能、高并发、Jvm性能调优、Spring,MyBatis,Nginx源码分析,Redis,ActiveMQ、Mycat、Netty、Kafka、Mysql、Zookeeper、Tomcat、Docker、Dubbo、Nginx等多个知识点高级进阶干货!
由于篇幅有限,为了方便大家观看,这里以图片的形式给大家展示部分的目录和答案截图!
[外链图片转存中…(img-woecVZpK-1712263283674)]
Java经典面试问题(含答案解析)
[外链图片转存中…(img-7egOEMGS-1712263283675)]
阿里巴巴技术笔试心得
[外链图片转存中…(img-leo537gv-1712263283675)]
《一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码》,点击传送门即可获取!