day1
1. MySQL的索引类型有哪些?
MySQL里的索引就像是书的目录,能帮数据库快速找到你要的数据。以下是各种索引类型的通俗解释:
按数据结构分
- B+树索引:最常用的一种,数据像在一棵树上分层存放,能快速定位范围数据,比如查找某个分数区间内的学生成绩。
- 哈希索引:通过把数据变成哈希值来建立索引,查找速度特别快,但只适合精确查找,比如根据身份证号找特定的人,要是找某个范围的就不行了。
- 倒排索引(全文索引):主要用来处理文本数据,比如在一篇文章里找特定的词,它会记录每个词在哪些文档里出现过。
- R - 树索引:用于处理多维空间数据,比如地图上查找某个区域内的所有店铺。
基于InnoDB B+树索引分
- 聚簇索引:数据和索引是放在一起的,就像书的正文和目录装订在一起,一般主键会默认是聚簇索引,找数据时速度快。
- 非聚簇索引:数据和索引分开存放,就像书的正文和目录分开,查找到索引后还得再去查数据。
按索引性质分
- 普通索引:最基本的索引,用来加快查询速度,比如在学生表中给姓名字段建普通索引,查特定姓名的学生更快。
- 主键索引:特殊的唯一索引,每个表只能有一个,就像每个人的身份证号,不能重复且必须有,用来唯一标识一行数据。
- 联合索引:把多个字段组合起来建索引,比如在学生表中把班级和成绩两个字段建联合索引,查某个班级特定成绩范围的学生时会更高效。
- 唯一索引:保证索引列的值不能重复,但可以有NULL值,比如员工表中员工编号字段建唯一索引。
- 全文索引:上面按数据结构分的时候讲过,用于在文本中快速查找特定词汇。
- 空间索引:和R - 树索引类似,用于处理地理空间等数据,比如查找某个城市内的所有加油站。
2.MySQLInnoDB 引擎中的聚簇索引和非聚簇索引有什么区别?
聚簇索引
- “索引叶子结点存储的是数据行,可以直接访问完整数据”:就好比一本书,它的目录后面直接跟着对应的正文内容。在聚簇索引里,索引的最底层(叶子结点)存的不只是索引信息,而是整行的数据。所以当你通过聚簇索引去查找数据时,一下子就能拿到完整的一行数据,不用再去别的地方找。
- “每个表只能有一个聚簇索引,通常是主键索引,适合范围查询和排序”:每个表就像一本独特的书,只能有一份这种目录和正文紧密相连的结构,也就是只能有一个聚簇索引。一般情况下,主键就充当了这个聚簇索引,因为主键能唯一确定一行数据。如果要查找某个范围的数据,比如找成绩在80 - 90分之间的学生记录,或者要对数据进行排序,聚簇索引处理起来就比较高效,因为数据在物理存储上是按照一定顺序排列的。
非聚簇索引
- “索引叶子节点存储的是数据行的主键和对应的索引列,需通过主键才能访问完整的数据行”:非聚簇索引像是另外单独的一个小目录,这个小目录里记录的是数据行的主键信息以及对应的索引列信息。当你通过这个小目录找到对应的主键后,还得再去聚簇索引那里,根据主键把完整的数据行找出来,就好像你先在小目录里查到页码,还得去书的正文里找具体内容。
- “一个表可以有多个非聚簇索引(称之为非主键索引、辅助索引、二级索引),适用于快速查找特定列的数据”:一个表可以有很多个这样的小目录,也就是可以有多个非聚簇索引。当你只需要查找表中的某一个或几个特定列的数据时,用非聚簇索引就比较快。比如你只想查学生表中的学生姓名,在姓名字段上建了非聚簇索引的话,就能快速定位到这些姓名信息。
3. MySQL 的存储引擎有哪些?它们之间有什么区别?
InnoDB
- 支持事务、行级锁和外键:事务就像一个打包任务,要么全成功,要么全失败,比如转账时同时增减双方账户金额。行级锁是只锁定要处理的那一行数据,这样别人还能操作其他行,就像你在图书馆占一个座位,不妨碍别人坐其他座位。外键能把不同表的数据关联起来,比如学生表和成绩表通过学号关联。
- 提供高并发性能,适用于高负载的OLTP应用:可以同时处理很多人的操作请求,像银行系统很多人同时转账、查询等。
- 数据以聚集索引的方式存储,提高检索效率:数据存放方式让查找速度变快,就像书的目录和正文放一起,找内容方便。
MyISAM
- 不支持事务和外键,使用表级锁:没有事务打包功能,也不能关联不同表数据。表级锁是锁定整张表,就像你把整个图书馆占了,别人都不能用。
- 适合读取多、更新少的场景,如数据仓库:如果只是经常查数据,很少改数据,用它就挺好,像公司用来分析历史数据的数据仓库。
- 具有较高的读性能和较快的表级锁定:读数据速度快,锁定表也快。
MEMORY
- 数据存储在内存中,速度快,但数据在服务器重启后丢失:数据放在内存里,访问就像在眼前拿东西一样快。不过服务器一重启,内存里的数据就没了,就像电脑重启后没保存的临时文件没了。
- 适用于临时数据存储或快速缓存:比如存临时计算结果,或者做快速缓存来加快访问。
NDB (NDCluster)
- 支持高可用性和数据分布,适合大规模分布式应用:能保证服务一直可用,数据还能分散存,适合像大型电商平台那种大规模分布式系统。
- 提供行级锁和自动分区:行级锁不影响别人操作其他行,自动分区把数据分到不同地方存,提高性能。
ARCHIVE
- 用于存储大量历史数据,支持高效的插入和压缩:适合存公司多年的历史订单等大量历史数据,存数据快还能压缩节省空间。
- 不支持索引,适合日志数据存储:不能用索引快速查找,但存日志数据很合适,反正日志主要是按顺序记录。
day2
1.MySQL 索引的最左前缀匹配原则是什么?
把 MySQL 索引想象成一本字典。字典前面有个目录,我们可以快速找到想要的字,MySQL 索引就和这目录类似,能帮数据库快速找到数据。最左前缀匹配原则,就像是查字典时按照顺序查一样。
联合索引就像多层目录
在 MySQL 里,如果我们给多个字段创建了联合索引,这就好比字典有个多层的目录。比如说,我们给一个表的姓、名这两个字段建了联合索引,这个联合索引就像是字典先按姓排了个顺序,在每个姓下面又按名排了顺序。
必须从最左边开始查找
最左前缀匹配原则要求我们查询的时候得从联合索引的最左边字段开始用。还拿姓和名的联合索引来说,如果我们只根据“名”去查,这个联合索引就帮不上忙了,因为索引是先按姓排的。只有先根据“姓”查,然后可能再根据“名”进一步缩小范围,索引才能发挥作用。
连续使用索引字段
再举个例子,如果联合索引是 (字段A, 字段B, 字段C) 。当我们查询条件是 “字段A = 某个值” 时,索引能用;当查询条件是 “字段A = 某个值 AND 字段B = 某个值” 时,索引也能用;当查询条件是 “字段A = 某个值 AND 字段B = 某个值 AND 字段C = 某个值” 时,索引还是能用。但要是查询条件是 “字段B = 某个值 AND 字段C = 某个值” ,没有最左边的字段A,索引就用不上了。而且查询时字段得连续用,要是查询条件是 “字段A = 某个值 AND 字段C = 某个值” ,跳过了字段B,那么索引也只能用到字段A,字段C那部分索引就不能用。
简单来说,最左前缀匹配原则就是在使用联合索引查询时,要从最左边的字段开始,按照顺序连续使用索引里的字段,这样索引才能高效地帮我们找到数据。
2.为什么 MySQL选择使用 B+树作为索引结构?
可以把 MySQL 里的数据想象成图书馆里的大量书籍,而索引就像是图书馆的目录,能让我们快速找到想要的书。MySQL 选择 B+树作为索引结构,主要有下面几个原因:
1. 查找效率高
B+树有个特点,它的所有数据都存放在叶子节点,而且叶子节点之间有指针相连,形成了一个有序链表。这就好比图书馆的目录,把同一类书按照编号排得整整齐齐。当我们要查找某条数据时,就像在目录里找对应的书编号,通过一层一层地比较节点上的值,能快速缩小查找范围,找到我们想要的数据。而且不管数据量有多大,查找的时间都比较稳定,不会因为数据变多就慢很多。
2. 适合范围查询
在实际应用中,我们经常需要查询某个范围内的数据,比如查询年龄在 20 到 30 岁之间的用户。B+树的叶子节点是有序的链表,这就方便极了。我们只要找到范围的起始点,然后顺着链表往后找,就能把这个范围内的数据都找出来。就像在图书馆目录里找到某一类书的起始编号,然后顺着编号顺序就能找到这一类里所有的书。
3. 磁盘读写性能好
数据库的数据通常存放在磁盘上,磁盘读写是比较耗时的操作。B+树的节点可以存储多个键值对,每个节点对应磁盘上的一个页。这样一来,一次磁盘读取能获取更多的数据,减少了磁盘 I/O 的次数。就好比我们去图书馆借书,一次能多拿几本,就不用来回跑那么多次了,效率自然就提高了。
4. 插入和删除操作稳定
在数据库里,数据是经常要进行插入和删除操作的。B+树在进行这些操作时,能通过节点的分裂和合并来保持树的平衡,不会因为频繁的插入和删除导致树的结构变得很混乱,影响查找效率。这就像图书馆的管理员,在不断地添加和拿走书籍后,还能把书架整理得井井有条,让我们还是能快速找到想要的书。
总的来说,B+树的这些优点让它很适合作为 MySQL 的索引结构,能让数据库在查找、插入、删除等操作上都有比较好的性能表现。
3.MySQL 三层 B+树能存多少数据?
要估算 MySQL 三层 B+ 树能存多少数据,我们需要先了解 B+ 树的结构特点,再分析每个节点大概能存储多少数据,最后得出三层 B+ 树的总存储量。
B+ 树结构基础
B+ 树是一种多路平衡查找树,在 MySQL 里,B+ 树的非叶子节点(索引节点)只存储索引信息,而数据都存放在叶子节点中。叶子节点之间通过指针相连,形成有序链表。我们可以把 B+ 树想象成一个多层的目录结构,非叶子节点是上层目录,叶子节点是最终存放具体内容的页面。
计算各层节点可存储的数据量
1. 假设前提
- 一个数据页的大小通常为 16KB(这是 MySQL InnoDB 存储引擎默认的数据页大小)。
- 非叶子节点(索引节点)主要存储索引键值和指向子节点的指针。假设一个索引键值和指针的组合大小为 8 字节(这只是为了方便计算做的假设,实际大小会因数据类型等因素而不同)。
- 叶子节点存储实际的数据记录,假设一条数据记录大小为 1KB(同样是假设值,实际大小取决于表结构)。
2. 计算非叶子节点可存储的子节点指针数量
由于一个数据页大小是 16KB(即 16 * 1024 = 16384 字节),一个索引键值和指针组合大小为 8 字节,那么一个非叶子节点能存储的子节点指针数量为:16384 ÷ 8 = 2048 个。
3. 分析三层 B+ 树的存储情况
- 第一层(根节点):根节点是一个非叶子节点,它能存储 2048 个指向第二层节点的指针。
- 第二层(中间层非叶子节点):每个第二层的非叶子节点同样能存储 2048 个指向第三层节点的指针。因为根节点有 2048 个指针指向第二层节点,所以第二层总共有 2048 个非叶子节点,那么第二层所有节点能指向的第三层节点数量为 2048 × 2048 个。
- 第三层(叶子节点):每个叶子节点存储实际的数据记录,假设一条记录大小为 1KB,一个叶子节点(数据页)能存储 16 条记录(16KB ÷ 1KB = 16)。由于第二层节点指向第三层的叶子节点数量为 2048 × 2048 个,所以三层 B+ 树能存储的数据记录总数为 2048 × 2048 × 16 = 67108864 条。
需要注意的是,以上计算是基于假设的数据页大小、索引键值和指针大小以及数据记录大小得出的,实际情况中这些值会因表结构、数据类型等因素而有所不同,但通过这种方式能让你大致了解三层 B+ 树的存储量级。