From b48d14643bcfff8b43927632e4a0d5c4c3bf2d5a Mon Sep 17 00:00:00 2001 From: dunwu Date: Sun, 27 Mar 2022 23:39:10 +0800 Subject: [PATCH] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E6=96=87=E6=A1=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- assets/mysql/Mysql.xmind | Bin 833290 -> 1060886 bytes docs/composite/数据结构与数据库.md | 136 ------------ .../数据结构与数据库索引.md | 203 ++++++++++++++++++ docs/sql/mysql/mysql-index.md | 80 ++++--- docs/sql/mysql/mysql-transaction.md | 14 +- docs/sql/mysql/mysql-workflow.md | 3 +- 6 files changed, 267 insertions(+), 169 deletions(-) delete mode 100644 docs/composite/数据结构与数据库.md create mode 100644 docs/composite/数据结构与数据库索引.md diff --git a/assets/mysql/Mysql.xmind b/assets/mysql/Mysql.xmind index 751d872e189d488f48723137eea4638e998e1b5c..83ea138a3d671987f956c991a3d9de05e85def5e 100644 GIT binary patch delta 135793 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

7JyCLdIRB5;ww09ptL$og;%`65DT%%J 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 关键词:链表、数组、散列表、红黑树、B+ 树、LSM 树、跳表 - -## 引言 - -从本质来看,数据库只负责两件事:读数据、写数据。 - -数据结构的核心就是合理组织数据,尽可能提升读、写数据的效率。 - -所以,数据结构是实现数据库的基石。 - -## 索引 - -索引是基于原始数据衍生的扩展数据结构。它的主要作用是缩小检索的数据范围,提升查询性能。 - -很多数据库允许单独添加和删除索引,而不影响数据库的内容,它只会影响查询性能。维护额外的结构势必会引入开销,特别是在新数据写入时。对于写人,它很难超过简单地追加文件方式的性能,因为那已经是最简单的写操作了。由于每次写数据时,需要更新索引,因此任何类型的索引通常都会降低写的速度。 - -### 数组和链表 - -数组和链表分别代表了连续空间和不连续空间的存储方式,它们是线性表(Linear List)的典型代表。其他所有的数据结构,比如栈、队列、二叉树、B+ 树等,实际上都是这两者的结合和变化。 - -数组**支持随机访问**。根据下标随机访问的时间复杂度为 `O(1)`。但这并不代表数组的查找时间复杂度也是 `O(1)`。 - -- 对于无序数组,只能顺序查找,其时间复杂度为 `O(n)`。 -- 对于有序数组,可以应用二分查找法,其时间复杂度为 `O(log n)`。 - -在有序数组上应用二分查找法如此高效,为什么几乎没有数据库直接使用数组作为索引?这是因为它的限制条件:数据有序。为了保证数据有序,每次添加、删除数组数据时,都必须要进行数据调整,来保证其有序。此外,由于数组空间大小固定,每次扩容只能采用复制数组的方式。数组的这些特性,决定了它不适合用于数据频繁变化的应用场景。 - -### 散列表 - -散列表的思路是:使用 Hash 函数将 Key 转换为数组下标。 - -哈希表的本质是一个数组,它通过 Hash 函数将查询的 Key 转为数组下标,利用数组的随机访问特性,使得我们能在 `O(1)` 的时间代价内完成检索。 - -#### 位图和布隆过滤器 - -在海量数据中,快速判断一个对象是否存在。相比于有序数组、二叉检索树和哈希表这三种方案,位图和布隆过滤器其实更适合解决这类状态检索的问题。这是因为,在不要求 100% 判断正确的情况下,使用位图和布隆过滤器可以达到 `O(1)` 时间代价的检索效率,同时空间使用率也非常高效。 - -为了判断一个很大的数据范围中,某数值是否存在,可以将这个范围的数据存为数组,其数组值为布尔型(true 或 false)。由于很多语言中,布尔类型需要 1 个字节,而二进制位(bit)的值 0 或 1 也可以表示 true 或 false,并且占用空间更小,所以更加合适。而这种基于位运算的哈希结构,即为位图。 - -布隆过滤器最大的特点,就是对一个对象使用多个哈希函数。如果我们使用了 k 个哈希函数,就会得到 k 个哈希值,也就是 k 个下标,我们会把数组中对应下标位置的值都置为 1。布隆过滤器和位图最大的区别就在于,我们不再使用一位来表示一个对象,而是使用 k 位来表示一个对象。这样两个对象的 k 位都相同的概率就会大大降低,从而能够解决哈希冲突的问题了。 - -布隆过滤器的误判有一个特点,那就是,它只会对存在的情况有误判。如果某个数字经过布隆过滤器判断不存在,那说明这个数字真的不存在,不会发生误判;如果某个数字经过布隆过滤器判断存在,这个时候才会有可能误判,有可能并不存在。不过,只要我们调整哈希函数的个数、位图大小跟要存储数字的个数之间的比例,那就可以将这种误判的概率降到非常低。 - -布隆过滤器过滤器适用于对误判有一定容忍度的场景。 - -### B+ 树 - -内存是半导体元件。对于内存而言,只要给出了内存地址,我们就可以直接访问该地址取出数据。这个过程具有高效的随机访问特性,因此内存也叫随机访问存储器(Random Access Memory,即 RAM)。内存的访问速度很快,但是价格相对较昂贵,因此一般的计算机内存空间都相对较小。 - -而磁盘是机械器件。磁盘访问数据时,需要等磁盘盘片旋转到磁头下,才能读取相应的数据。尽管磁盘的旋转速度很快,但是和内存的随机访问相比,性能差距非常大。一般来说,如果是随机读写,会有 10 万到 100 万倍左右的差距。但如果是顺序访问大批量数据的话,磁盘的性能和内存就是一个数量级的。 - -磁盘的最小读写单位是扇区,较早期的磁盘一个扇区是 **`512`** 字节。随着磁盘技术的发展,目前常见的磁盘扇区是 **`4K`** 个字节。操作系统一次会读写多个扇区,所以操作系统的最小读写单位是块(Block),也叫作簇(Cluster)。当我们要从磁盘中读取一个数据时,操作系统会一次性将整个块都读出来。因此,对于大批量的顺序读写来说,磁盘的效率会比随机读写高许多。 - -假设有一个有序数组存储在硬盘中,如果它足够大,那么它会存储在多个块中。当我们要对这个数组使用二分查找时,需要先找到中间元素所在的块,将这个块从磁盘中读到内存里,然后在内存中进行二分查找。如果下一步要读的元素在其他块中,则需要再将相应块从磁盘中读入内存。直到查询结束,这个过程可能会多次访问磁盘。我们可以看到,这样的检索性能非常低。 - -由于磁盘相对于内存而言访问速度实在太慢,因此,对于磁盘上数据的高效检索,我们有一个极其重要的原则:对磁盘的访问次数要尽可能的少! - -将索引和数据分离就是一种常见的设计思路。在数据频繁变化的场景中,有序数组并不是一个最好的选择,二叉检索树或者哈希表往往更有普适性。但是,哈希表由于缺乏范围检索的能力,在一些场合也不适用。因此,二叉检索树这种树形结构是许多常见检索系统的实施方案。 - -随着索引数据越来越大,直到无法完全加载到内存中,这是需要将索引数据也存入磁盘中。B+ 树给出了将树形索引的所有节点都存在磁盘上的高效检索方案。操作系统对磁盘数据的访问是以块为单位的。因此,如果我们想将树型索引的一个节点从磁盘中读出,即使该节点的数据量很小(比如说只有几个字节),但磁盘依然会将整个块的数据全部读出来,而不是只读这一小部分数据,这会让有效读取效率很低。B+ 树的一个关键设计,就是让一个节点的大小等于一个块的大小。节点内存储的数据,不是一个元素,而是一个可以装 m 个元素的有序数组。这样一来,我们就可以将磁盘一次读取的数据全部利用起来,使得读取效率最大化。 - -B+ 树还有另一个设计,就是将所有的节点分为内部节点和叶子节点。内部节点仅存储 key 和维持树形结构的指针,并不存储 key 对应的数据(无论是具体数据还是文件位置信息)。这样内部节点就能存储更多的索引数据,我们也就可以使用最少的内部节点,将所有数据组织起来了。而叶子节点仅存储 key 和对应数据,不存储维持树形结构的指针。通过这样的设计,B+ 树就能做到节点的空间利用率最大化。此外,B+ 树还将同一层的所有节点串成了有序的双向链表,这样一来,B+ 树就同时具备了良好的范围查询能力和灵活调整的能力了。 - -因此,B+ 树是一棵完全平衡的 m 阶多叉树。所谓的 m 阶,指的是每个节点最多有 m 个子节点,并且每个节点里都存了一个紧凑的可包含 m 个元素的数组。 - -即使是复杂的 B+ 树,我们将它拆解开来,其实也是由简单的数组、链表和树组成的,而且 B+ 树的检索过程其实也是二分查找。因此,如果 B+ 树完全加载在内存中的话,它的检索效率其实并不会比有序数组或者二叉检索树更 -高,也还是二分查找的 log(n) 的效率。并且,它还比数组和二叉检索树更加复杂,还会带来额外的开销。 - -另外,这一节还有一个很重要的设计思想需要你掌握,那就是将索引和数据分离。通过这样的方式,我们能将索引的数组大小保持在一个较小的范围内,让它能加载在内存中。在许多大规模系统中,都是使用这个设计思想来精简索引的。而且,B+ 树的内部节点和叶子节点的区分,其实也是索引和数据分离的一次实践。 - -MySQL 中的 B+ 树实现其实有两种,一种是 MyISAM 引擎,另一种是 InnoDB 引擎。它们的核心区别就在于,数据和索引是否是分离的。 - -在 MyISAM 引擎中,B+ 树的叶子节点仅存储了数据的位置指针,这是一种索引和数据分离的设计方案,叫作非聚集索引。如果要保证 MyISAM 的数据一致性,那我们需要在表级别上进行加锁处理。 - -在 InnoDB 中,B+ 树的叶子节点直接存储了具体数据,这是一种索引和数据一体的方案。叫作聚集索引。由于数据直接就存在索引的叶子节点中,因此 InnoDB 不需要给全表加锁来保证一致性,它只需要支持行级的锁就可以了。 - -### LSM 树 - -B+ 树的数据都存储在叶子节点中,而叶子节点一般都存储在磁盘中。因此,每次插入的新数据都需要随机写入磁盘,而随机写入的性能非常慢。如果是一个日志系统,每秒钟要写入上千条甚至上万条数据,这样的磁盘操作代价会使得系统性能急剧下降,甚至无法使用。 - -操作系统对磁盘的读写是以块为单位的,我们能否以块为单位写入,而不是每次插入一个数据都要随机写入磁盘呢?这样是不是就可以大幅度减少写入操作了呢?解决方案就是:**LSM 树**(Log Structured Merge Trees)。 - -LSM 树就是根据这个思路设计了这样一个机制:当数据写入时,延迟写磁盘,将数据先存放在内存中的树里,进行常规的存储和查询。当内存中的树持续变大达到阈值时,再批量地以块为单位写入磁盘的树中。因此,LSM 树至少需要由两棵树组成,一棵是存储在内存中较小的 C0 树,另一棵是存储在磁盘中较大的 C1 树。 - -LSM 树具有以下 3 个特点: - -1. 将索引分为内存和磁盘两部分,并在内存达到阈值时启动树合并(Merge Trees); -2. 用批量写入代替随机写入,并且用预写日志 WAL 技术(Write AheadLog,预写日志技术)保证内存数据,在系统崩溃后可以被恢复; -3. 数据采取类似日志追加写的方式写入(Log Structured)磁盘,以顺序写的方式提高写 - 入效率。 - -LSM 树的这些特点,使得它相对于 B+ 树,在写入性能上有大幅提升。所以,许多 NoSQL 系统都使用 LSM 树作为检索引擎,而且还对 LSM 树进行了优化以提升检索性能。 - -### 倒排索引 - -倒排索引的核心其实并不复杂,它的具体实现其实是哈希表,只是它不是将文档 ID 或者题目作为 key,而是反过来,通过将内容或者属性作为 key 来存储对应的文档列表,使得我们能在 O(1) 的时间代价内完成查询。 - -尽管原理并不复杂,但是倒排索引是许多检索引擎的核心。比如说,数据库的全文索引功能、搜索引擎的索引、广告引擎和推荐引擎,都使用了倒排索引技术来实现检索功能。 - -### 索引的维护 - -#### 创建索引 - -- **数据压缩**:一个是尽可能地将数据加载到内存中,因为内存的检索效率大大高于磁盘。那为了将数据更多地加载到内存中,索引压缩是一个重要的研究方向。 -- **分支处理**:另一个是将大数据集合拆成多个小数据集合来处理。这其实就是分布式系统的核心思想。 - -#### 更新索引 - -(1)Double Buffer(双缓冲)机制 - -就是在内存中同时保存两份一样的索引,一个是索引 A,一个是索引 B。两个索引保持一个读、一个写,并且来回切换,最终完成高性能的索引更新。 - -优点:简单高效 - -缺点:达到一定数据量级后,会带来翻倍的内存开销,甚至有些索引存储在磁盘上的情况下,更是无法使用此机制。 - -(2)全量索引和增量索引 - -将新接收到的数据单独建立一个可以存在内存中的倒排索引,也就是增量索引。当查询发生的时候,我们会同时查询全量索引和增量索引,将合并的结果作为总的结果输出。 - -因为增量索引相对全量索引而言会小很多,内存资源消耗在可承受范围,所以我们可以使用 Double Buffer 机制 -对增量索引进行索引更新。这样一来,增量索引就可以做到无锁访问。而全量索引本身就是只读的,也不需要加锁。因此,整个检索过程都可以做到无锁访问,也就提高了系统的检索效率。 - -## 参考资料 - -- **书籍** - - [《数据密集型应用系统设计》](https://book.douban.com/subject/30329536/) -- **教程** - - [数据结构与算法之美](https://time.geekbang.org/column/intro/100017301) - - [检索技术核心 20 讲](https://time.geekbang.org/column/intro/100048401) -- **论文** - - [Data Structures for Databases](https://www.cise.ufl.edu/~mschneid/Research/papers/HS05BoCh.pdf) -- **文章** - - [Data Structures and Algorithms for Big Databases](https://people.csail.mit.edu/bradley/BenderKuszmaul-tutorial-xldb12.pdf) diff --git a/docs/composite/数据结构与数据库索引.md b/docs/composite/数据结构与数据库索引.md new file mode 100644 index 0000000..9de6091 --- /dev/null +++ b/docs/composite/数据结构与数据库索引.md @@ -0,0 +1,203 @@ +# 数据结构与数据库索引 + +> 关键词:链表、数组、散列表、红黑树、B+ 树、LSM 树、跳表 + +## 引言 + +**数据库**是“按照 **数据结构** 来组织、存储和管理数据的仓库”。是一个长期存储在计算机内的、有组织的、可共享的、统一管理的大量数据的集合。 + +——上面这句定义对数据库的定义来自百度百科。通过这个定义,我们也能明显看出数据结构是实现数据库的基石。 + +从本质来看,数据库只负责两件事:读数据、写数据;而数据结构研究的是如何合理组织数据,尽可能提升读、写数据的效率,这恰好是数据库的核心问题。因此,数据结构与数据库这两个领域有非常多的交集。其中,数据库索引最能体现二者的紧密关联。 + +**索引是数据库为了提高查找效率的一种数据结构**。索引基于原始数据衍生而来,它的主要作用是缩小检索的数据范围,提升查询性能。通俗来说,索引在数据库中的作用就像是一本书的目录索引。索引对于良好的性能非常关键,在数据量小且负载较低时,不恰当的索引对于性能的影响可能还不明显;但随着数据量逐渐增大,性能则会急剧下降。因此,**索引优化应该是查询性能优化的最有效手段**。 + +很多数据库允许单独添加和删除索引,而不影响数据库的内容,它只会影响查询性能。维护额外的结构势必会引入开销,特别是在新数据写入时。对于写入,它很难超过简单地追加文件方式的性能,因为那已经是最简单的写操作了。由于每次写数据时,需要更新索引,因此任何类型的索引通常都会降低写的速度。 + +本文以一些常见的数据库为例,分析它们的索引采用了什么样的数据结构,有什么利弊,为何如此设计。 + +## 数组和链表 + +数组和链表分别代表了连续空间和不连续空间的存储方式,它们是线性表(Linear List)的典型代表。其他所有的数据结构,比如栈、队列、二叉树、B+ 树等,实际上都是这两者的结合和变化。 + +**数组用连续的内存空间来存储数据**。数组**支持随机访问,根据下标随机访问的时间复杂度为 `O(1)`**。但这并不代表数组的查找时间复杂度也是 `O(1)`。 + +- **对于无序数组,只能顺序查找,其时间复杂度为 `O(n)`**。 +- **对于有序数组,可以应用二分查找法,其时间复杂度为 `O(log n)`**。 + +在有序数组上应用二分查找法如此高效,为什么几乎没有数据库直接使用数组作为索引?这是因为它的限制条件:**数据有序**——为了保证数据有序,每次添加、删除数组数据时,都必须要进行数据调整,来保证其有序,而 **数组的插入/删除操作,时间复杂度为 `O(n)`**。此外,由于数组空间大小固定,每次扩容只能采用复制数组的方式。数组的这些特性,决定了它不适合用于数据频繁变化的应用场景。 + +![img](https://raw.githubusercontent.com/dunwu/images/dev/snap/20220320115836.png) + +**链表用不连续的内存空间来存储数据;并通过一个指针按顺序将这些空间串起来,形成一条链**。 + +区别于数组,链表中的元素不是存储在内存中连续的一片区域,链表中的数据存储在每一个称之为「结点」复合区域里,在每一个结点除了存储数据以外,还保存了到下一个节点的指针(Pointer)。由于不必按顺序存储,**链表的插入/删除操作,时间复杂度为 `O(1)`**,但是,链表只支持顺序访问,其 **查找时间复杂度为 `O(n)`**。其低效的查找方式,决定了链表不适合作为索引。 + +![img](https://raw.githubusercontent.com/dunwu/images/dev/snap/20220320174829.png) + +## 哈希索引 + +哈希表是一种以键 - 值(key-value)对形式存储数据的结构,我们只要输入待查找的值即 key,就可以找到其对应的值即 Value。 + +**哈希表** 使用 **哈希函数** 组织数据,以支持快速插入和搜索的数据结构。哈希表的本质是一个数组,其思路是:使用 Hash 函数将 Key 转换为数组下标,利用数组的随机访问特性,使得我们能在 `O(1)` 的时间代价内完成检索。 + +![img](https://raw.githubusercontent.com/dunwu/images/dev/snap/20220320201844.png) + +有两种不同类型的哈希表:**哈希集合** 和 **哈希映射**。 + +- **哈希集合** 是集合数据结构的实现之一,用于存储非重复值。 +- **哈希映射** 是映射 数据结构的实现之一,用于存储键值对。 + +哈希索引基于哈希表实现,**只适用于等值查询**。对于每一行数据,哈希索引都会将所有的索引列计算一个哈希码(`hashcode`),哈希码是一个较小的值。哈希索引将所有的哈希码存储在索引中,同时在哈希表中保存指向每个数据行的指针。 + +✔ 哈希索引的**优点**: + +- 因为索引数据结构紧凑,所以**查询速度非常快**。 + +❌ 哈希索引的**缺点**: + +- 哈希索引值包含哈希值和行指针,而不存储字段值,所以不能使用索引中的值来避免读取行。不过,访问内存中的行的速度很快,所以大部分情况下这一点对性能影响不大。 +- **哈希索引数据不是按照索引值顺序存储的**,所以**无法用于排序**。 +- 哈希索引**不支持部分索引匹配查找**,因为哈希索引时使用索引列的全部内容来进行哈希计算的。如,在数据列 (A,B) 上建立哈希索引,如果查询只有数据列 A,无法使用该索引。 +- 哈希索引**只支持等值比较查询**,包括 `=`、`IN()`、`<=>`;不支持任何范围查询,如 `WHERE price > 100`。 +- 哈希索引有**可能出现哈希冲突** + - 出现哈希冲突时,必须遍历链表中所有的行指针,逐行比较,直到找到符合条件的行。 + - 如果哈希冲突多的话,维护索引的代价会很高。 + +> 因为种种限制,所以哈希索引只适用于特定的场合。而一旦使用哈希索引,则它带来的性能提升会非常显著。例如,Mysql 中的 Memory 存储引擎就显示的支持哈希索引。 + +## B-Tree 索引 + +通常我们所说的 B 树索引是指 `B-Tree` 索引,它是目前关系型数据库中查找数据最为常用和有效的索引,大多数存储引擎都支持这种索引。使用 `B-Tree` 这个术语,是因为 MySQL 在 `CREATE TABLE` 或其它语句中使用了这个关键字,但实际上不同的存储引擎可能使用不同的数据结构,比如 InnoDB 使用的是 `B+Tree `索引;而 MyISAM 使用的是 `B-Tree `索引。 + +`B-Tree` 索引中的 B 是指 `balance`,意为平衡。需要注意的是,`B-Tree` 索引并不能找到一个给定键值的具体行,它找到的只是被查找数据行所在的页,接着数据库会把页读入到内存,再在内存中进行查找,最后得到要查找的数据。 + +### 二叉搜索树 + +二叉搜索树的特点是:每个节点的左儿子小于父节点,父节点又小于右儿子。其查询时间复杂度是 `O(log n)`。 + +当然为了维持 `O(log n)` 的查询复杂度,你就需要保持这棵树是平衡二叉树。为了做这个保证,更新的时间复杂度也是 `O(log n)`。 + +随着数据库中数据的增加,索引本身大小随之增加,不可能全部存储在内存中,因此索引往往以索引文件的形式存储的磁盘上。这样的话,索引查找过程中就要产生磁盘 I/O 消耗,相对于内存存取,I/O 存取的消耗要高几个数量级。可以想象一下一棵几百万节点的二叉树的深度是多少?如果将这么大深度的一颗二叉树放磁盘上,每读取一个节点,需要一次磁盘的 I/O 读取,整个查找的耗时显然是不能够接受的。那么如何减少查找过程中的 I/O 存取次数? + +一种行之有效的解决方法是减少树的深度,将**二叉树变为 N 叉树**(多路搜索树),而 **B+ 树就是一种多路搜索树**。 + +### `B+Tree` 索引 + +B+ 树索引适用于**全键值查找**、**键值范围查找**和**键前缀查找**,其中键前缀查找只适用于最左前缀查找。 + +理解 `B+Tree`,只需要理解其最重要的两个特征即可: + +- 第一,所有的关键字(可以理解为数据)都存储在叶子节点,非叶子节点并不存储真正的数据,所有记录节点都是按键值大小顺序存放在同一层叶子节点上。 +- 其次,所有的叶子节点由指针连接。如下图为简化了的`B+Tree`。 + +![img](https://raw.githubusercontent.com/dunwu/images/dev/snap/20200304235424.jpg) + +根据叶子节点的内容,索引类型分为主键索引和非主键索引。 + +- **聚簇索引(clustered)**:又称为主键索引,其叶子节点存的是整行数据。因为无法同时把数据行存放在两个不同的地方,所以**一个表只能有一个聚簇索引**。**InnoDB 的聚簇索引实际是在同一个结构中保存了 B 树的索引和数据行**。 +- 非主键索引的叶子节点内容是主键的值。在 InnoDB 里,非主键索引也被称为**二级索引(secondary)**。数据存储在一个位置,索引存储在另一个位置,索引中包含指向数据存储位置的指针。可以有多个,小于 249 个。 + +**聚簇表示数据行和相邻的键值紧凑地存储在一起,因为数据紧凑,所以访问快**。因为无法同时把数据行存放在两个不同的地方,所以**一个表只能有一个聚簇索引**。 + +**聚簇索引和非聚簇索引的查询有什么区别** + +- 如果语句是 `select * from T where ID=500`,即聚簇索引查询方式,则只需要搜索 ID 这棵 B+ 树; +- 如果语句是 `select * from T where k=5`,即非聚簇索引查询方式,则需要先搜索 k 索引树,得到 ID 的值为 500,再到 ID 索引树搜索一次。这个过程称为**回表**。 + +也就是说,**基于非聚簇索引的查询需要多扫描一棵索引树**。因此,我们在应用中应该尽量使用主键查询。 + +**显然,主键长度越小,非聚簇索引的叶子节点就越小,非聚簇索引占用的空间也就越小。** + +自增主键是指自增列上定义的主键,在建表语句中一般是这么定义的: NOT NULL PRIMARY KEY AUTO_INCREMENT。从性能和存储空间方面考量,自增主键往往是更合理的选择。有没有什么场景适合用业务字段直接做主键的呢?还是有的。比如,有些业务的场景需求是这样的: + +- 只有一个索引; +- 该索引必须是唯一索引。 + +由于没有其他索引,所以也就不用考虑其他索引的叶子节点大小的问题。这时候我们就要优先考虑上一段提到的“尽量使用主键查询”原则,直接将这个索引设置为主键,可以避免每次查询需要搜索两棵树。 + +------ + +内存是半导体元件。对于内存而言,只要给出了内存地址,我们就可以直接访问该地址取出数据。这个过程具有高效的随机访问特性,因此内存也叫随机访问存储器(Random Access Memory,即 RAM)。内存的访问速度很快,但是价格相对较昂贵,因此一般的计算机内存空间都相对较小。 + +而磁盘是机械器件。磁盘访问数据时,需要等磁盘盘片旋转到磁头下,才能读取相应的数据。尽管磁盘的旋转速度很快,但是和内存的随机访问相比,性能差距非常大。一般来说,如果是随机读写,会有 10 万到 100 万倍左右的差距。但如果是顺序访问大批量数据的话,磁盘的性能和内存就是一个数量级的。 + +磁盘的最小读写单位是扇区,较早期的磁盘一个扇区是 **`512`** 字节。随着磁盘技术的发展,目前常见的磁盘扇区是 **`4K`** 个字节。操作系统一次会读写多个扇区,所以操作系统的最小读写单位是块(Block),也叫作簇(Cluster)。当我们要从磁盘中读取一个数据时,操作系统会一次性将整个块都读出来。因此,对于大批量的顺序读写来说,磁盘的效率会比随机读写高许多。 + +假设有一个有序数组存储在硬盘中,如果它足够大,那么它会存储在多个块中。当我们要对这个数组使用二分查找时,需要先找到中间元素所在的块,将这个块从磁盘中读到内存里,然后在内存中进行二分查找。如果下一步要读的元素在其他块中,则需要再将相应块从磁盘中读入内存。直到查询结束,这个过程可能会多次访问磁盘。我们可以看到,这样的检索性能非常低。 + +由于磁盘相对于内存而言访问速度实在太慢,因此,对于磁盘上数据的高效检索,我们有一个极其重要的原则:对磁盘的访问次数要尽可能的少! + +将索引和数据分离就是一种常见的设计思路。在数据频繁变化的场景中,有序数组并不是一个最好的选择,二叉检索树或者哈希表往往更有普适性。但是,哈希表由于缺乏范围检索的能力,在一些场合也不适用。因此,二叉检索树这种树形结构是许多常见检索系统的实施方案。 + +随着索引数据越来越大,直到无法完全加载到内存中,这是需要将索引数据也存入磁盘中。B+ 树给出了将树形索引的所有节点都存在磁盘上的高效检索方案。操作系统对磁盘数据的访问是以块为单位的。因此,如果我们想将树型索引的一个节点从磁盘中读出,即使该节点的数据量很小(比如说只有几个字节),但磁盘依然会将整个块的数据全部读出来,而不是只读这一小部分数据,这会让有效读取效率很低。B+ 树的一个关键设计,就是让一个节点的大小等于一个块的大小。节点内存储的数据,不是一个元素,而是一个可以装 m 个元素的有序数组。这样一来,我们就可以将磁盘一次读取的数据全部利用起来,使得读取效率最大化。 + +B+ 树还有另一个设计,就是将所有的节点分为内部节点和叶子节点。内部节点仅存储 key 和维持树形结构的指针,并不存储 key 对应的数据(无论是具体数据还是文件位置信息)。这样内部节点就能存储更多的索引数据,我们也就可以使用最少的内部节点,将所有数据组织起来了。而叶子节点仅存储 key 和对应数据,不存储维持树形结构的指针。通过这样的设计,B+ 树就能做到节点的空间利用率最大化。此外,B+ 树还将同一层的所有节点串成了有序的双向链表,这样一来,B+ 树就同时具备了良好的范围查询能力和灵活调整的能力了。 + +因此,B+ 树是一棵完全平衡的 m 阶多叉树。所谓的 m 阶,指的是每个节点最多有 m 个子节点,并且每个节点里都存了一个紧凑的可包含 m 个元素的数组。 + +即使是复杂的 B+ 树,我们将它拆解开来,其实也是由简单的数组、链表和树组成的,而且 B+ 树的检索过程其实也是二分查找。因此,如果 B+ 树完全加载在内存中的话,它的检索效率其实并不会比有序数组或者二叉检索树更 +高,也还是二分查找的 log(n) 的效率。并且,它还比数组和二叉检索树更加复杂,还会带来额外的开销。 + +另外,这一节还有一个很重要的设计思想需要你掌握,那就是将索引和数据分离。通过这样的方式,我们能将索引的数组大小保持在一个较小的范围内,让它能加载在内存中。在许多大规模系统中,都是使用这个设计思想来精简索引的。而且,B+ 树的内部节点和叶子节点的区分,其实也是索引和数据分离的一次实践。 + +MySQL 中的 B+ 树实现其实有两种,一种是 MyISAM 引擎,另一种是 InnoDB 引擎。它们的核心区别就在于,数据和索引是否是分离的。 + +在 MyISAM 引擎中,B+ 树的叶子节点仅存储了数据的位置指针,这是一种索引和数据分离的设计方案,叫作非聚集索引。如果要保证 MyISAM 的数据一致性,那我们需要在表级别上进行加锁处理。 + +在 InnoDB 中,B+ 树的叶子节点直接存储了具体数据,这是一种索引和数据一体的方案。叫作聚集索引。由于数据直接就存在索引的叶子节点中,因此 InnoDB 不需要给全表加锁来保证一致性,它只需要支持行级的锁就可以了。 + +## LSM 树 + +B+ 树的数据都存储在叶子节点中,而叶子节点一般都存储在磁盘中。因此,每次插入的新数据都需要随机写入磁盘,而随机写入的性能非常慢。如果是一个日志系统,每秒钟要写入上千条甚至上万条数据,这样的磁盘操作代价会使得系统性能急剧下降,甚至无法使用。 + +操作系统对磁盘的读写是以块为单位的,我们能否以块为单位写入,而不是每次插入一个数据都要随机写入磁盘呢?这样是不是就可以大幅度减少写入操作了呢?解决方案就是:**LSM 树**(Log Structured Merge Trees)。 + +LSM 树就是根据这个思路设计了这样一个机制:当数据写入时,延迟写磁盘,将数据先存放在内存中的树里,进行常规的存储和查询。当内存中的树持续变大达到阈值时,再批量地以块为单位写入磁盘的树中。因此,LSM 树至少需要由两棵树组成,一棵是存储在内存中较小的 C0 树,另一棵是存储在磁盘中较大的 C1 树。 + +LSM 树具有以下 3 个特点: + +1. 将索引分为内存和磁盘两部分,并在内存达到阈值时启动树合并(Merge Trees); +2. 用批量写入代替随机写入,并且用预写日志 WAL 技术(Write AheadLog,预写日志技术)保证内存数据,在系统崩溃后可以被恢复; +3. 数据采取类似日志追加写的方式写入(Log Structured)磁盘,以顺序写的方式提高写 + 入效率。 + +LSM 树的这些特点,使得它相对于 B+ 树,在写入性能上有大幅提升。所以,许多 NoSQL 系统都使用 LSM 树作为检索引擎,而且还对 LSM 树进行了优化以提升检索性能。 + +## 倒排索引 + +倒排索引的核心其实并不复杂,它的具体实现其实是哈希表,只是它不是将文档 ID 或者题目作为 key,而是反过来,通过将内容或者属性作为 key 来存储对应的文档列表,使得我们能在 O(1) 的时间代价内完成查询。 + +尽管原理并不复杂,但是倒排索引是许多检索引擎的核心。比如说,数据库的全文索引功能、搜索引擎的索引、广告引擎和推荐引擎,都使用了倒排索引技术来实现检索功能。 + +## 索引的维护 + +### 创建索引 + +- **数据压缩**:一个是尽可能地将数据加载到内存中,因为内存的检索效率大大高于磁盘。那为了将数据更多地加载到内存中,索引压缩是一个重要的研究方向。 +- **分支处理**:另一个是将大数据集合拆成多个小数据集合来处理。这其实就是分布式系统的核心思想。 + +### 更新索引 + +(1)Double Buffer(双缓冲)机制 + +就是在内存中同时保存两份一样的索引,一个是索引 A,一个是索引 B。两个索引保持一个读、一个写,并且来回切换,最终完成高性能的索引更新。 + +优点:简单高效 + +缺点:达到一定数据量级后,会带来翻倍的内存开销,甚至有些索引存储在磁盘上的情况下,更是无法使用此机制。 + +(2)全量索引和增量索引 + +将新接收到的数据单独建立一个可以存在内存中的倒排索引,也就是增量索引。当查询发生的时候,我们会同时查询全量索引和增量索引,将合并的结果作为总的结果输出。 + +因为增量索引相对全量索引而言会小很多,内存资源消耗在可承受范围,所以我们可以使用 Double Buffer 机制 +对增量索引进行索引更新。这样一来,增量索引就可以做到无锁访问。而全量索引本身就是只读的,也不需要加锁。因此,整个检索过程都可以做到无锁访问,也就提高了系统的检索效率。 + +## 参考资料 + +- [《数据密集型应用系统设计》](https://book.douban.com/subject/30329536/) +- [数据结构与算法之美](https://time.geekbang.org/column/intro/100017301) +- [检索技术核心 20 讲](https://time.geekbang.org/column/intro/100048401) +- [Data Structures for Databases](https://www.cise.ufl.edu/~mschneid/Research/papers/HS05BoCh.pdf) +- [Data Structures and Algorithms for Big Databases](https://people.csail.mit.edu/bradley/BenderKuszmaul-tutorial-xldb12.pdf) diff --git a/docs/sql/mysql/mysql-index.md b/docs/sql/mysql/mysql-index.md index 0400c7a..ae79527 100644 --- a/docs/sql/mysql/mysql-index.md +++ b/docs/sql/mysql/mysql-index.md @@ -37,25 +37,27 @@ ## 1. 索引简介 -**_索引优化应该是查询性能优化的最有效手段_**。 +**索引是数据库为了提高查找效率的一种数据结构**。 + +索引对于良好的性能非常关键,在数据量小且负载较低时,不恰当的索引对于性能的影响可能还不明显;但随着数据量逐渐增大,性能则会急剧下降。因此,索引优化应该是查询性能优化的最有效手段。 ### 1.1. 索引的优缺点 -B+ 树索引,按照顺序存储数据,所以 Mysql 可以用来做 ORDER BY 和 GROUP BY 操作。因为数据是有序的,所以 B+ 树也就会将相关的列值都存储在一起。最后,因为索引中存储了实际的列值,所以某些查询只使用索引就能够完成全部查询。 +B 树是最常见的索引,按照顺序存储数据,所以 Mysql 可以用来做 `ORDER BY` 和 `GROUP BY` 操作。因为数据是有序的,所以 B 树也就会将相关的列值都存储在一起。最后,因为索引中存储了实际的列值,所以某些查询只使用索引就能够完成全部查询。 ✔ 索引的优点: -- 索引大大减少了服务器需要扫描的数据量,从而加快检索速度。 -- 支持行级锁的数据库,如 InnoDB 会在访问行的时候加锁。使用索引可以减少访问的行数,从而减少锁的竞争,提高并发。 -- 索引可以帮助服务器避免排序和临时表。 -- 索引可以将随机 I/O 变为顺序 I/O。 +- **索引大大减少了服务器需要扫描的数据量**,从而加快检索速度。 +- **索引可以帮助服务器避免排序和临时表**。 +- **索引可以将随机 I/O 变为顺序 I/O**。 +- 支持行级锁的数据库,如 InnoDB 会在访问行的时候加锁。**使用索引可以减少访问的行数,从而减少锁的竞争,提高并发**。 - 唯一索引可以确保每一行数据的唯一性,通过使用索引,可以在查询的过程中使用优化隐藏器,提高系统的性能。 ❌ 索引的缺点: -- 创建和维护索引要耗费时间,这会随着数据量的增加而增加。 +- **创建和维护索引要耗费时间**,这会随着数据量的增加而增加。 - **索引需要占用额外的物理空间**,除了数据表占数据空间之外,每一个索引还要占一定的物理空间,如果要建立组合索引那么需要的空间就会更大。 -- 写操作(`INSERT`/`UPDATE`/`DELETE`)时很可能需要更新索引,导致数据库的写操作性能降低。 +- **写操作(`INSERT`/`UPDATE`/`DELETE`)时很可能需要更新索引,导致数据库的写操作性能降低**。 ### 1.2. 何时使用索引 @@ -63,37 +65,67 @@ B+ 树索引,按照顺序存储数据,所以 Mysql 可以用来做 ORDER BY ✔ 什么情况**适用**索引: -- 表经常进行 `SELECT` 操作; -- 表的数据量比较大; -- 列名经常出现在 `WHERE` 或连接(`JOIN`)条件中 +- **频繁读操作( `SELECT` )** +- **表的数据量比较大**。 +- **列名经常出现在 `WHERE` 或连接(`JOIN`)条件中**。 ❌ 什么情况**不适用**索引: -- **频繁写操作**( `INSERT`/`UPDATE`/`DELETE` )- 需要更新索引空间; -- **非常小的表** - 对于非常小的表,大部分情况下简单的全表扫描更高效。 -- 列名不经常出现在 `WHERE` 或连接(`JOIN`)条件中 - 索引就会经常不命中,没有意义,还增加空间开销。 -- 对于特大型表,建立和使用索引的代价将随之增长。可以考虑使用分区技术或 Nosql。 +- **频繁写操作**( `INSERT`/`UPDATE`/`DELETE` ),也就意味着需要更新索引。 +- **列名不经常出现在 `WHERE` 或连接(`JOIN`)条件中**,也就意味着索引会经常无法命中,没有意义,还增加空间开销。 +- **非常小的表**,对于非常小的表,大部分情况下简单的全表扫描更高效。 +- **特大型的表**,建立和使用索引的代价将随之增长。可以考虑使用分区技术或 Nosql。 ## 2. 索引的数据结构 +在 Mysql 中,索引是在存储引擎层而不是服务器层实现的。所以,并没有统一的索引标准;不同存储引擎的索引的数据结构也不相同。 + +### 数组 + +数组是用连续的内存空间来存储数据,并且支持随机访问。 + +有序数组可以使用二分查找法,其时间复杂度为 `O(log n)`,无论是等值查询还是范围查询,都非常高效。 + +但数组有两个重要限制: + +- 数组的空间大小固定,如果要扩容只能采用复制数组的方式。 +- 插入、删除时间复杂度为 `O(n)`。 + +这意味着,如果使用数组作为索引,如果要保证数组有序,其更新操作代价高昂。 + ### 2.1. 哈希索引 -> Hash 索引只有精确匹配索引所有列的查询才有效。 +哈希表是一种以键 - 值(key-value)对形式存储数据的结构,我们只要输入待查找的值即 key,就可以找到其对应的值即 Value。 -哈希表是一种以键 - 值(key-value)存储数据的结构,我们只要输入待查找的值即 key,就可以找到其对应的值即 Value。哈希的思路很简单,把值放在数组里,用一个哈希函数把 key 换算成一个确定的位置,然后把 value 放在数组的这个位置。 +**哈希表** 使用 **哈希函数** 组织数据,以支持快速插入和搜索的数据结构。哈希表的本质是一个数组,其思路是:使用 Hash 函数将 Key 转换为数组下标,利用数组的随机访问特性,使得我们能在 `O(1)` 的时间代价内完成检索。 -对于每一行数据,对所有的索引列计算一个 `hashcode`。哈希索引将所有的 `hashcode` 存储在索引中,同时在 Hash 表中保存指向每个数据行的指针。 +![img](https://raw.githubusercontent.com/dunwu/images/dev/snap/20220320201844.png) -哈希索引的**优点**: +有两种不同类型的哈希表:**哈希集合** 和 **哈希映射**。 + +- **哈希集合** 是集合数据结构的实现之一,用于存储非重复值。 +- **哈希映射** 是映射 数据结构的实现之一,用于存储键值对。 + +哈希索引基于哈希表实现,**只适用于等值查询**。对于每一行数据,哈希索引都会将所有的索引列计算一个哈希码(`hashcode`),哈希码是一个较小的值。哈希索引将所有的哈希码存储在索引中,同时在哈希表中保存指向每个数据行的指针。 + +在 Mysql 中,只有 Memory 存储引擎显示支持哈希索引。 + +✔ 哈希索引的**优点**: - 因为索引数据结构紧凑,所以**查询速度非常快**。 -哈希索引的**缺点**: +❌ 哈希索引的**缺点**: -- 哈希索引数据不是按照索引值顺序存储的,所以**无法用于排序**。 -- 哈希索引**不支持部分索引匹配查找**。如,在数据列 (A,B) 上建立哈希索引,如果查询只有数据列 A,无法使用该索引。 -- 哈希索引**只支持等值比较查询**,不支持任何范围查询,如 `WHERE price > 100`。 -- 哈希索引有**可能出现哈希冲突**,出现哈希冲突时,必须遍历链表中所有的行指针,逐行比较,直到找到符合条件的行。 +- 哈希索引值包含哈希值和行指针,而不存储字段值,所以不能使用索引中的值来避免读取行。不过,访问内存中的行的速度很快,所以大部分情况下这一点对性能影响不大。 +- **哈希索引数据不是按照索引值顺序存储的**,所以**无法用于排序**。 +- 哈希索引**不支持部分索引匹配查找**,因为哈希索引时使用索引列的全部内容来进行哈希计算的。如,在数据列 (A,B) 上建立哈希索引,如果查询只有数据列 A,无法使用该索引。 +- 哈希索引**只支持等值比较查询**,包括 `=`、`IN()`、`<=>`;不支持任何范围查询,如 `WHERE price > 100`。 +- 哈希索引有**可能出现哈希冲突** + - 出现哈希冲突时,必须遍历链表中所有的行指针,逐行比较,直到找到符合条件的行。 + - 如果哈希冲突多的话,维护索引的代价会很高。 + + +> 因为种种限制,所以哈希索引只适用于特定的场合。而一旦使用哈希索引,则它带来的性能提升会非常显著。 ### 2.2. B 树索引 diff --git a/docs/sql/mysql/mysql-transaction.md b/docs/sql/mysql/mysql-transaction.md index 24e074e..6360853 100644 --- a/docs/sql/mysql/mysql-transaction.md +++ b/docs/sql/mysql/mysql-transaction.md @@ -208,7 +208,7 @@ T1 修改一个数据,T2 随后读取这个数据。如 ### 4.3. 提交读 -**`提交读(READ COMMITTED)` 是指:一个事务只能读取已经提交的事务所做的修改**。换句话说,一个事务所做的修改在提交之前对其它事务是不可见的。提交读解决了脏读的问题。 +**`提交读(READ COMMITTED)` 是指:事务提交后,其他事务才能看到它的修改**。换句话说,一个事务所做的修改在提交之前对其它事务是不可见的。提交读解决了脏读的问题。 提交读是大多数数据库的默认事务隔离级别。 @@ -245,12 +245,12 @@ T1 读取某个范围的数据,T2 在这个范围内插 数据库隔离级别解决的问题: -| 隔离级别 | 脏读 | 不可重复读 | 幻读 | -| :------: | :--: | :--------: | :--: | -| 未提交读 | ❌ | ❌ | ❌ | -| 提交读 | ✔️ | ❌ | ❌ | -| 可重复读 | ✔️ | ✔️ | ❌ | -| 可串行化 | ✔️ | ✔️ | ✔️ | +| 隔离级别 | 丢失修改 | 脏读 | 不可重复读 | 幻读 | +| :------: | :--: | :--------: | :--: | :--: | +| 未提交读 | ✔️ | ❌ | ❌ | ❌ | +| 提交读 | ✔️ | ✔️ | ❌ | ❌ | +| 可重复读 | ✔️ | ✔️ | ✔️ | ❌ | +| 可串行化 | ✔️ | ✔️ | ✔️ | ✔️ | ## 5. 死锁 diff --git a/docs/sql/mysql/mysql-workflow.md b/docs/sql/mysql/mysql-workflow.md index 338c447..a81f9e8 100644 --- a/docs/sql/mysql/mysql-workflow.md +++ b/docs/sql/mysql/mysql-workflow.md @@ -69,8 +69,7 @@ MySQL 客户端连接命令:`mysql -h<主机> -P<端口> -u<用户名> -p<密 MySQL 将缓存存放在一个引用表(不要理解成`table`,可以认为是类似于`HashMap`的数据结构),通过一个哈希值索引,这个哈希值通过查询本身、当前要查询的数据库、客户端协议版本号等一些可能影响结果的信息计算得来。所以两个查询在任何字符上的不同(例如:空格、注释),都会导致缓存不会命中。 -**如果查询中包含任何用户自定义函数、存储函数、用户变量、临时表、mysql 库中的系统表,其查询结果** -**都不会被缓存**。比如函数`NOW()`或者`CURRENT_DATE()`会因为不同的查询时间,返回不同的查询结果,再比如包含`CURRENT_USER`或者`CONNECION_ID()`的查询语句会因为不同的用户而返回不同的结果,将这样的查询结果缓存起来没有任何的意义。 +**如果查询中包含任何用户自定义函数、存储函数、用户变量、临时表、mysql 库中的系统表,其查询结果都不会被缓存**。比如函数`NOW()`或者`CURRENT_DATE()`会因为不同的查询时间,返回不同的查询结果,再比如包含`CURRENT_USER`或者`CONNECION_ID()`的查询语句会因为不同的用户而返回不同的结果,将这样的查询结果缓存起来没有任何的意义。 **不建议使用数据库缓存,因为往往弊大于利**。查询缓存的失效非常频繁,只要有对一个表的更新,这个表上所有的查询缓存都会被清空。因此很可能你费劲地把结果存起来,还没使用呢,就被一个更新全清空了。对于更新压力大的数据库来说,查询缓存的命中率会非常低。除非你的业务就是有一张静态表,很长时间才会更新一次。比如,一个系统配置表,那这张表上的查询才适合使用查询缓存。