社区所有版块导航
Python
python开源   Django   Python   DjangoApp   pycharm  
DATA
docker   Elasticsearch  
aigc
aigc   chatgpt  
WEB开发
linux   MongoDB   Redis   DATABASE   NGINX   其他Web框架   web工具   zookeeper   tornado   NoSql   Bootstrap   js   peewee   Git   bottle   IE   MQ   Jquery  
机器学习
机器学习算法  
Python88.com
反馈   公告   社区推广  
产品
短视频  
印度
印度  
Py学习  »  DATABASE

面试官:说一下Mysql中的索引是怎么实现的?

鸭哥聊Java • 1 月前 • 49 次点击  

今天咱们来聊聊MySQL中的索引是怎么实现的,主要围绕InnoDB存储引擎的实现原理。作为一个资深Java开发工程师,我经常看到面试官问:“MySQL的索引底层是怎么实现的?”这个问题看似简单,其实考察的知识点挺深的,搞不明白就容易掉坑里。

首先,MySQL的InnoDB存储引擎使用的是B+树来实现索引结构。为什么是B+树而不是B树或者其他数据结构?这个选择不是拍脑袋决定的,而是数据库领域数十年积累下来的结果。

B+树的结构是怎样的?

B+树是一种多叉平衡树。简单理解,它是一个多层的“楼房”,每层节点存储的索引值是有序的,非叶子节点不存储实际数据,只存储索引和指针,用来指导“去哪一层找”。

在B+树中,所有的数据都存储在叶子节点上,叶子节点之间还通过双向链表相连。这样设计有几个好处:

  • 磁盘读取高效: 因为每个节点的容量较大,可以一次性读取更多数据,减少磁盘I/O次数。
  • 范围查询友好: 因为叶子节点形成了有序链表,做范围查询时,只需要顺序扫描叶子节点。
  • 平衡性: B+树自动维护平衡,插入、删除节点时树高度不会失控。

B+树索引查找是怎么做的?

假设有一个商品表product,有一列id作为主键,我们想通过下面这条SQL查询商品信息:

SELECT * FROM product WHERE id = 5;

查询过程是这样的:

  1. 从根节点开始比较,假设根节点存储的索引是 (1, 10, 20)
  2. 查询id=5,发现5在110之间,于是进入对应的子节点。
  3. 在第二层节点中,假设存储的是 (1, 4, 7),发现5又在47之间,于是进入下一个子节点。
  4. 在第三层的叶子节点中,假设存储的是 (4, 5, 6),这时找到了目标数据id=5,查找成功。

整个查找过程经历了3次磁盘I/O操作。

为什么选择B+树?

B+树的设计主要是为了解决数据库频繁读写磁盘的问题。在磁盘中,磁盘I/O是非常昂贵的操作,数据库的目标就是尽量减少I/O次数。由于B+树是多叉树,树的高度较小,即使存储几百万条数据,通常也只需要3-4次磁盘I/O就能找到目标数据。

此外,B+树的叶子节点之间有链表连接,非常适合区间查询,例如:

SELECT * FROM product WHERE id BETWEEN 5 AND 15;

数据库从id=5的叶子节点开始,顺着链表一直找到id=15,高效完成范围查询。

主键索引和普通索引的区别

  1. 主键索引: 主键索引是B+树的一个聚集索引,表中的数据物理存储方式是按照主键的顺序排列的。因此,通过主键查询非常高效。

  2. 普通索引: 普通索引是一个辅助索引,叶子节点存储的不是实际数据,而是主键值。查询时需要先查到主键值,然后再通过主键索引定位到实际数据。这叫“回表”操作。

示例代码演示

以下是一个简单的Java代码示例,模拟B+树节点的结构:

import java.util.*;

class BPlusTreeNode {
    int[] keys;
    BPlusTreeNode[] children;
    boolean isLeaf;
    
    BPlusTreeNode(int order) {
        keys = new int[order - 1];
        children = new BPlusTreeNode[order];
        isLeaf = true;
    }
}

public class BPlusTree {
    private BPlusTreeNode root;

    public BPlusTree(int order) {
        root = new BPlusTreeNode(order);
    }

    public void search(int key) {
        BPlusTreeNode current = root;
        while (!current.isLeaf) {
            int i = 0;
            while (i  current.keys[i]) {
                i++;
            }
            current = current.children[i];
        }
        
        System.out.println("Found key " + key + " in leaf node.");
    }

    public static void main(String[] args) {
        BPlusTree tree = new BPlusTree(4);
        tree.search(5);  // 模拟查询
    }
}

这段代码只是简单展示了B+树的查找过程,实际数据库引擎的实现远比这复杂得多。

最后,面试官问你:MySQL中的索引是如何实现的?为什么选择B+树?

你的回答:

MySQL InnoDB存储引擎的索引使用B+树作为数据结构。B+树是一种多叉平衡树,叶子节点存储所有数据,非叶子节点只存储索引和指针。B+树的特点是树的高度较小,即使在存储百万级别的数据时,树的高度通常也只有3-4层,因此磁盘I/O次数很少。

选择B+树的原因有以下几点:

  1. 磁盘I/O优化: B+树节点存储容量大,减少了磁盘读取次数。
  2. 范围查询高效: 叶子节点形成双向链表,做范围查询时可以顺序扫描。
  3. 自动平衡: B+树自动保持平衡,插入、删除操作不会导致树高度失控。

此外,主键索引和普通索引在存储和查找上也有差异。主键索引是聚集索引,存储了实际数据,而普通索引是辅助索引,存储的是主键值,需要回表查询。

对编程、职场感兴趣的同学,可以链接我,微信:yagebug  拉你进入“程序员交流群”。
🔥鸭哥私藏精品 热门推荐🔥

鸭哥作为一名老码农,整理了全网最全《Java高级架构师资料合集》
资料包含了《IDEA视频教程》《最全Java面试题库》、最全项目实战源码及视频》及《毕业设计系统源码》总量高达 650GB 。全部免费领取!全面满足各个阶段程序员的学习需求。

Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/176785
 
49 次点击