当前位置: 首页 > news >正文

嘉峪关市建设局建管科资质网站wordpress切换语言实现

嘉峪关市建设局建管科资质网站,wordpress切换语言实现,苏州知名高端网站建设企业,wordpress媒体库 替换文章目录 一、InnoDB 简介InnoDB 行格式COMPACT 行格式CHAR(M) 列的存储格式VARCHAR(M) 最多能存储的数据记录中的数据太多产生的溢出行溢出的临界点 二、表空间文件的结构三、InnoDB 数据页结构页页的概览Infimum 和 Supremum使用Page Directory页的真实面貌 四、B 树是如何进… 文章目录 一、InnoDB 简介InnoDB 行格式COMPACT 行格式CHAR(M) 列的存储格式VARCHAR(M) 最多能存储的数据记录中的数据太多产生的溢出行溢出的临界点 二、表空间文件的结构三、InnoDB 数据页结构页页的概览Infimum 和 Supremum使用Page Directory页的真实面貌 四、B 树是如何进行查询的查询方式聚簇索引和二级索引 五、总结 InnoDB 一个支持事务安全的存储引擎同时也是 mysql 的默认存储引擎。本文主要从数据结构的角度详细介绍 InnoDB 行记录格式和数据页的实现原理从底层看清 InnoDB 存储引擎。从存储原理和读取原理分析结构。 一、InnoDB 简介 大家都知道 mysql 中数据是存储在物理磁盘上的而真正的数据处理又是在内存中执行的。由于磁盘的读写速度非常慢如果每次操作都对磁盘进行频繁读写的话那么性能一定非常差。为了上述问题InnoDB 将数据划分为若干页以页作为磁盘与内存交互的基本单位一般页的大小为 16KB。这样的话一次性至少读取 1 页数据到内存中或者将 1 页数据写入磁盘。通过减少内存与磁盘的交互次数从而提升性能。 其实这本质上就是一种典型的缓存设计思想一般缓存的设计基本都是从时间维度或者空间维度进行考量的 时间维度如果一条数据正在在被使用那么在接下来一段时间内大概率还会再被使用。可以认为热点数据缓存都属于这种思路的实现。空间维度如果一条数据正在在被使用那么存储在它附近的数据大概率也会很快被使用。InnoDB 的数据页和操作系统的页缓存则是这种思路的体现。 InnoDB 行格式 mysql 是以记录 (一行数据) 为单位向数据表中插入数据的这些记录在磁盘上的存放方式称为行格式。mysql 支持 4 种不同类型的行格式Compact、Redundant比较老本文就不具体介绍了、Dynamic、Compressed。我们可以在创建或修改表的语句中指定行格式 CREATE TABLE 表名 (列的信息) ROW_FORMAT行格式名称 ALTER TABLE 表名 ROW_FORMAT行格式名称比如我们要创建一个行格式为 Compact字符集为 ascii 的数据表 record_format_demosql 如下 mysql CREATE TABLE record_format_demo (c1 VARCHAR(10),c2 VARCHAR(10) NOT NULL,c3 CHAR(10),c4 VARCHAR(10)) CHARSETascii ROW_FORMATCOMPACT; Query OK, 0 rows affected (0.03 sec)假设我们向 record_format_demo 表中插入了 2 行数据 mysql SELECT * FROM record_format_demo; ----------------------- | c1 | c2 | c3 | c4 | ----------------------- | aaaa | bbb | cc | d | | eeee | fff | NULL | NULL | ----------------------- 2 rows in set (0.00 sec)COMPACT 行格式 记录的额外信息 记录的额外信息主要包含 3 类变长字段长度列表、NULL 值列表和记录头信息。 变长字段长度列表 mysql 中支持一些变长数据类型比如 VARCHAR(M)、TEXT 等它们存储数据占用的存储空间不是固定的而是会随着存储内容的变化而变化。为了准确描述这种数据这种变长字段占用的存储空间要同时包含 真正的数据内容占用的字节数 在 Compact 行格式中把所有变长字段的真实数据占用的字节长度都存放在记录的开头部位从而形成一个变长字段长度列表各变长字段数据占用的字节数按照列的顺序逆序存放。 我们以 record_format_demo 第一行数据为例。由于 c1、c2 和 c4 都是变成数据类型 (VARCHAR(10)), 因此要将这 3 列值得长度保存在记录的开头处。 记录头信息 记录头信息是由固定的 5 个字节 (40 位) 组成, 不同的位代表不同的含义 暂时不详细展开。 真实的数据 记录的真实数据除了包含各列具体的数据外还会自动添加一些隐藏列数据。 列名是否必须占用空间描述 row_id 否 6 字节行 ID唯一标识一条记录 transaction_id 是 6 字节事务 IDroll_pointer 是 7 字节回滚指针 实际上这几个列的真正名称其实是DB_ROW_ID、DB_TRX_ID、DB_ROLL_PTR为了美观才写成了 row_id、transaction_id 和 roll_pointer。 只有当数据库没有定义主键或者唯一键时隐藏列 row_id 才会存在并且将其作为数据表主键。因为表 record_format_demo 并没有定义主键所以 MySQL 服务器会为每条记录增加上述的 3 个列。现在看一下加上记录的真实数据的两个记录的数据结构 CHAR(M) 列的存储格式 对于 CHAR(M) 类型的列来说当列采用的是定长字符集时该列占用的字节数不会被加到变长字段长度列表而如果采用变长字符集时该列占用的字节数也会被加到变长字段长度列表。另外有一点还需要注意变长字符集的 CHAR(M) 类型的列要求至少占用 M 个字节而 VARCHAR(M) 却没有这个要求。比方说对于使用 utf8 字符集的 CHAR(10) 的列来说该列存储的数据字节长度的范围是 1030 个字节即使我们向该列中存储一个空字符串也会占用 10 个字节。 VARCHAR(M) 最多能存储的数据 MySQL 对一条记录占用的最大存储空间是有限制的除了 BLOB 或者 TEXT 类型的列之外其他所有的列不包括隐藏列和记录头信息占用的字节长度加起来不能超过 65535 个字节。可以不严谨的认为mysql 一行记录占用的存储空间不能超过 65535 个字节。这个 65535 个字节除了列本身的数据之外还包括一些其他的数据storage overhead比如说我们为了存储一个 VARCHAR(M) 类型的列其实需要占用 3 部分存储空间 真实数据真实数据占用字节的长度NULL 值标识如果该列有 NOT NULL 属性则可以没有这部分存储空间 假设 varchar_size_demo 只有一个 VARCHAR 类型的字段那么该字段最大占用的 65532 个字节。因为真实数据的长度可能占用 2 个字节NULL 值标识需要占用 1 个字节。如果该 VARCHAR 类型的列没有 NOT NULL 属性那最多只能存储 65532 个字节的数据。如果该列是 ascii 字符集对应的最大字符数最大为 65532如果是 utf8 字符集则对应的最大字符数为 21844。 记录中的数据太多产生的溢出 我们以 ascii 字符集下的 varchar_size_demo 表为例插入一条记录 mysql CREATE TABLE varchar_size_demo(c VARCHAR(65532)) CHARSETascii ROW_FORMATCompact; Query OK, 0 rows affected (0.01 sec)mysql INSERT INTO varchar_size_demo(c) VALUES(REPEAT(a, 65532)); Query OK, 1 row affected (0.00 sec)mysql 中磁盘与内存交互的基本单位是页一般为 16KB16384 个字节而一行记录最大可以占用 65535 个字节这就造成了一页存不下一行数据的情况。在 Compact 和 Redundant 行格式中对于占用存储空间非常大的列在记录的真实数据处只会存储该列的一部分数据把剩余的数据分散存储在几个其他的页中然后记录的真实数据处用 20 个字节存储指向这些页的地址从而可以找到剩余数据所在的页如图所示 这种在本记录的真实数据处只会存储该列的前 768 个字节的数据和一个指向其他页的地址然后把剩下的数据存放到其他页中的情况就叫做行溢出存储超出 768 字节的那些页面也被称为溢出页。 行溢出的临界点 MySQL 中规定一个页中至少存放两行记录。以上边的 varchar_size_demo 表为例它只有一个列 c我们往这个表中插入两条记录每条记录最少插入多少字节的数据才会行溢出的现象呢这得分析一下页中的空间都是如何利用的。 每个页除了存放我们的记录以外也需要存储一些额外的信息大概 132 个字节。每个记录需要的额外信息是 27 字节。 假设一个列中存储的数据字节数为 n如要要保证该列不发生溢出则需要满足 132 2×(27 n) 16384 结果是 n 8099。也就是说如果一个列中存储的数据小于 8099 个字节那么该列就不会成为溢出列。如果表中有多个列那么这个值更小。 二、表空间文件的结构 表空间由段segment、区extent、页page、行row组成InnoDB存储引擎的逻辑存储结构大致如下图 下面我们从下往上一个个看看。 1、行row 数据库表中的记录都是按行row进行存放的每行记录根据不同的行格式有不同的存储结构。 后面我们详细介绍 InnoDB 存储引擎的行格式也是本文重点介绍的内容。 2、页page 记录是按照行来存储的但是数据库的读取并不以「行」为单位否则一次读取也就是一次 I/O 操作只能处理一行数据效率会非常低。 因此InnoDB 的数据是按「页」为单位来读写的也就是说当需要读一条记录的时候并不是将这个行记录从磁盘读出来而是以页为单位将其整体读入内存。 默认每个页的大小为 16KB也就是最多能保证 16KB 的连续存储空间。 页是 InnoDB 存储引擎磁盘管理的最小单元意味着数据库每次读写都是以 16KB 为单位的一次最少从磁盘中读取 16K 的内容到内存中一次最少把内存中的 16K 内容刷新到磁盘中。 页的类型有很多常见的有数据页、undo 日志页、溢出页等等。数据表中的行记录是用「数据页」来管理的数据页的结构这里我就不讲细说了之前文章有说过感兴趣的可以去看这篇文章 总之知道表中的记录存储在「数据页」里面就行。 3、区extent 我们知道 InnoDB 存储引擎是用 B 树来组织数据的。 B 树中每一层都是通过双向链表连接起来的如果是以页为单位来分配存储空间那么链表中相邻的两个页之间的物理位置并不是连续的可能离得非常远那么磁盘查询时就会有大量的随机I/O随机 I/O 是非常慢的。 解决这个问题也很简单就是让链表中相邻的页的物理位置也相邻这样就可以使用顺序 I/O 了那么在范围查询扫描叶子节点的时候性能就会很高。 那具体怎么解决呢 在表中数据量大的时候为某个索引分配空间的时候就不再按照页为单位分配了而是按照区extent为单位分配。每个区的大小为 1MB对于 16KB 的页来说连续的 64 个页会被划为一个区这样就使得链表中相邻的页的物理位置也相邻就能使用顺序 I/O 了。 4、段segment 表空间是由各个段segment组成的段是由多个区extent组成的。段一般分为数据段、索引段和回滚段等。 索引段存放 B 树的非叶子节点的区的集合数据段存放 B 树的叶子节点的区的集合回滚段存放的是回滚数据的区的集合之前讲的时候就介绍到了 MVCC 利用了回滚段实现了多版本查询数据。 三、InnoDB 数据页结构 我们已经知道页是 InnoDB 管理存储空间的基本单位一个页的大小一般是 16KB。InnoDB 为了不同的目的设计了许多不同类型的页我们这里主要关注存储数据记录的页官方称为索引页。由于还没介绍索引暂且我们先称为数据页吧。 页 首先我们需要知道页Pages是 InnoDB 中管理数据的最小单元。Buffer Pool 中存的就是一页一页的数据。再比如当我们要查询的数据不在 Buffer Pool 中时InnoDB 会将记录所在的页整个加载到 Buffer Pool 中去同样的将 Buffer Pool 中的脏页刷入磁盘时也是按照页为单位刷入磁盘的。 不了解 Buffer Pool 的、或者感兴趣的可以去搜索下 页的概览 我们往 MySQL 插入的数据最终都是存在页中的。在 InnoDB 中的设计中页与页之间是通过一个双向链表连接起来。 而存储在页中的一行一行的数据则是通过单链表连接起来的。 上图中的 User Records 的区域就是用来存储行数据的。那 InnoDB 为什么要这么设计假设我们没有页这个概念那么当我们查询时成千上万的数据要如何做到快速的查询出结果众所周知MySQL 的性能是不错的而如果没有页我们剩下的只能是逐条逐条的遍历数据了。 那页是如何做到快速查询的呢在当前页中可以通过 User Records 中的连接每条记录的单链表来进行遍历如果在当前页中没有找到则可以通过下一页指针快速的跳到下一页进行查询。 Infimum 和 Supremum 有人可能会说了你在 User Records 中还不是通过遍历来解决的你就是简单的把数据分了个组而已。如果我的数据根本不在当前这个页中那我难道还是得把之前的页中的每一条数据全部遍历完这效率也太低了 当然MySQL 也考虑到了这个问题所以实际上在页中还存在一块区域叫做 The Infimum and Supremum Records 代表了当前页中最大和最小的记录。 有了 Infimum Record 和 Supremum Record 现在查询不需要将某一页的 User Records 全部遍历完只需要将这两个记录和待查询的目标记录进行比较。比如我要查询的数据 id 101 那很明显不在当前页。接下来就可以通过下一页指针跳到下页进行检索。 使用Page Directory 可能有人又会说了你这 User Records 里不也全是单链表吗即使我知道我要找的数据在当前页那最坏的情况下不还是得挨个挨个的遍历100次才能找到我要找的数据你管这也叫效率高 不得不说这的确是个问题不过是一个 MySQL 已经考虑到的问题。不错挨个遍历确实效率很低。为了解决这个问题MySQL 又在页中加入了另一个区域 Page Directory 。 顾名思义Page Directory 是个目录里面有很多个槽位Slots每一个槽位都指向了一条 User Records 中的记录。大家可以看到每隔几条数据就会创建一个槽位。其实我图中给出的数据是非常严格按照其设定来的在一个完整的页中每隔6条数据就会有一个 Slot。 Page Directory 的设计不知道有没有让你想起另一个数据结构——跳表只不过这里只抽象了一层索引 MySQL 会在新增数据的时候就将对应的 Slot 创建好有了 Page Directory 就可以对一张页的数据进行粗略的二分查找。至于为什么是粗略毕竟 Page Directory 中不是完整的数据二分查找出来的结果只能是个大概的位置找到了这个大概的位置之后还需要回到 User Records 中继续的进行挨个遍历匹配。 不过这样的效率已经比我们刚开始聊的原始版本高了很多了。 页的真实面貌 如果我开篇就把页的各种组成部分各种概念直接抛出来首先我自己接受不了这样显得很僵硬。其次对页不熟悉的人应该是不太能理解页为什么要这么设计的。所以我按照查询一条数据的一套思路把页的大致的面貌呈现给了大家。 实际上页上还存储了很多其他的字段也还有其他的区域但是这些都不会影响到我们对页的理解。所以在对页有了一个较为清晰的认知之后我们就可以来看看真实的页到底长啥样了。 上图就是页的实际全部组成除了我们之前提到过的还多了一些之前没有聊过的例如 File Header、Page Header、Free Space、File Tailer 。我们一个一个来看。 File Header 其实File Header 在上文已经聊过了只是不叫这个名字。上面提到的上一页指针和下一页指针其实就是属于File Header的除此之外还有很多其他的数据。 其实我比较抗拒把一堆参数列出来告诉你这个大小多少那个用来干嘛。对于我们需要详细了解页来说其实暂时只需要知道两个就足够了分别是 FIL_PAGE_PREVFIL_PAGE_NEXT 这两个变量就是上文提到过的上一页指针和下一页指针说是指针是为了方便大家理解实际上是页在磁盘上的偏移量。 Page Directory页目录 我们已经知道记录在页中按照主键大小正序串联成了一个单链表。如果我们要根据主键查找具体的某条记录应该怎么办简单的方式是根据链表进行遍历。但是在数据量比较大的情况下这种方式显然效率太差了。因此 mysql 使用了 Page Directory页目录来解决这个问题。Page Directory页目录大致的原理如下 将所有正常的记录包括最大和最小记录不包括标记为已删除的记录划分为几个组。怎么划分先不关注。每个组的最后一条记录也就是组内最大的那条记录的头信息中的 n_owned 属性表示该组内共有几条记录。将每个组的最后一条记录的地址偏移量单独提取出来按顺序存储到靠近页尾部的地方这个地方就是所谓的 Page Directory。 mysql 规定对于最小记录所在的分组只能有 1 条记录最大记录所在的分组拥有的记录条数只能在 1-8 条之间剩下的分组中记录的条数范围只能在是 4-8 条之间。比方说现在的 page_demo 表中正常的记录共有 18 条InnoDB 会把它们分成 5 组第一组中只有一个最小记录如下所示 页目录创建的过程如下 将所有的记录划分成几个组这些记录包括最小记录和最大记录但不包括标记为“已删除”的记录每个记录组的最后一条记录就是组内最大的那条记录并且最后一条记录的头信息中会存储该组一共有多少条记录作为 n_owned 字段上图中粉红色字段页目录用来存储每组最后一条记录的地址偏移量这些地址偏移量会按照先后顺序存储起来每组的地址偏移量也被称之为槽slot每个槽相当于指针指向了不同组的最后一个记录。 从图可以看到页目录就是由多个槽组成的槽相当于分组记录的索引。然后因为记录是按照「主键值」从小到大排序的所以我们通过槽查找记录时可以使用二分法快速定位要查询的记录在哪个槽哪个记录分组定位到槽后再遍历槽内的所有记录找到对应的记录无需从最小记录开始遍历整个页中的记录链表。 以上面那张图举个例子5 个槽的编号分别为 01234我想查找主键为 11 的用户记录 先二分得出槽中间位是 (04)/22 2号槽里最大的记录为 8。因为 11 8所以需要从 2 号槽后继续搜索记录再使用二分搜索出 2 号和 4 槽的中间位是 (24)/2 33 号槽里最大的记录为 12。因为 11 12所以主键为 11 的记录在 3 号槽里这里有个问题「**槽对应的值都是这个组的主键最大的记录如何找到组里最小的记录」**比如槽 3 对应最大主键是 12 的记录那如何找到最小记录 9。解决办法是通过槽 3 找到 槽 2 对应的记录也就是主键为 8 的记录。主键为 8 的记录的下一条记录就是槽 3 当中主键最小的 9 记录然后开始向下搜索 2 次定位到主键为 11 的记录取出该条记录的信息即为我们想要查找的内容。 看到第三步的时候可能有的同学会疑问如果某个槽内的记录很多然后因为记录都是单向链表串起来的那这样在槽内查找某个记录的时间复杂度不就是 O(n) 了吗 这点不用担心InnoDB 对每个分组中的记录条数都是有规定的槽内的记录就只有几条 第一个分组中的记录只能有 1 条记录最后一个分组中的记录条数范围只能在 1-8 条之间剩下的分组中记录条数范围只能在 4-8 条之间。 通过 Page Directory 在一个数据页中查找指定主键值的记录的过程分为两步 通过二分法确定该记录所在的槽并找到该槽所在分组中主键值最小的那条记录。通过记录的 next_record 属性遍历该槽所在的组中的各个记录。 Page Header页面头部 Page Header 专门用来存储数据页相关的各种状态信息比如本页中已经存储了多少条记录第一条记录的地址是什么页目录中存储了多少个槽等等。固定占用 56 个字节各部分字节属性含义如下 这里全列出来是因为了解这些参数的含义和为什么要设置参数能够更好的帮助我们了解页的原理和构造具体的看图说话就行。 这里也很想吐槽太多博客都写的太僵硬比如参数 PAGE_HEAP_TOP 这里的 HEAP 很多博客都直接叫堆。这就跟你给Init写注释叫初始化一样还不如不写。实际上你去研究一下就会知道这里的堆实际上就是指User Records。 里面有个两个参数可能会有点混淆分别是PAGE_N_HEAP和PAGE_N_RECS 都是当前 User Records 中记录的数量唯一的不同在于PAGE_N_HEAP 中是包含了被标记为删除的记录的 而 PAGE_N_RECS 中就是实际上我们能够查询到的所有数据。 Infimum Supremum Records 上文中提到Infimum Supremum Records会记录当前页最大最小记录。实际上不准确更准确的描述是最小记录和最大纪录的开区间。因为实际上 Infimum Records 会比当前页中的最小值还要小而 Supremum Records 会比当前页中的最大值要大。 User Records User Records 可以说是我们平时接触的最多的部分了毕竟我们的数据最终都在这。页被初始化之后User Records 中是没有数据的随着系统运行数据产生User Records 中的数据会不断的膨胀相应的 Free Space 空间会慢慢的变小。 关于 User Records 中的概念之前已经聊过了。这里只聊我认为很关键的一点那就是顺序。 我们知道在聚簇索引中Key 实际上会按照 Primary Key 的顺序来进行排列。那在 User Records 中也会这样吗我们插入一条新的数据到 User Records 中时是否也会按照 Primary Key 的顺序来对已有的数据重排序 答案是不会因为这样会拉低 MySQL 处理的效率。 User Records 中的数据是由单链表指针的指向来保证的也就是说行数据实际在磁盘上的表现是按照插入顺序来排队的先到的数据在前面后来的数据在后面。只不过通过 User Records 中的行数据之间的单链表形成了一个按照 Primary Key排列的顺序。 用图来表示大概如下 Free Space 这块其实变相的在其他的模块中讨论了最初 User Records 是完全空的当有新数据进来时会来 Free Space 中申请空间当 Free Space 没空间了则说明需要申请新的页了其他没什么特别之处。 Page Directory 这跟上文讨论的没什么出入就直接跳过了。 File Trailer 这块主要是为了防止页在刷入磁盘的过程中由于极端的意外情况网络问题、火灾、自然灾害导致失败而造成数据不一致的情况也就是说形成了脏页。 四、B 树是如何进行查询的 查询方式 上面我们都是在说一个数据页中的记录检索因为一个数据页中的记录是有限的且主键值是有序的所以通过对所有记录进行分组然后将组号槽号存储到页目录使其起到索引作用通过二分查找的方法快速检索到记录在哪个分组来降低检索的时间复杂度。 但是当我们需要存储大量的记录时就需要多个数据页这时我们就需要考虑如何建立合适的索引才能方便定位记录所在的页。 为了解决这个问题InnoDB 采用了 B 树作为索引。磁盘的 I/O 操作次数对索引的使用效率至关重要因此在构造索引的时候我们更倾向于采用“矮胖”的 B 树数据结构这样所需要进行的磁盘 I/O 次数更少而且 B 树 更适合进行关键字的范围查询。 InnoDB 里的 B 树中的每个节点都是一个数据页结构示意图如下 通过上图我们看出 B 树的特点 只有叶子节点最底层的节点才存放了数据非叶子节点其他上层节仅用来存放目录项作为索引。非叶子节点分为不同层次通过分层来降低每一层的搜索量所有节点按照索引键大小排序构成一个双向链表便于范围查询 我们再看看 B 树如何实现快速查找主键为 6 的记录以上图为例子 从根节点开始通过二分法快速定位到符合页内范围包含查询值的页因为查询的主键值为 6在[1, 7)范围之间所以到页 30 中查找更详细的目录项在非叶子节点页30中继续通过二分法快速定位到符合页内范围包含查询值的页主键值大于 5所以就到叶子节点页16查找记录接着在叶子节点页16中通过槽查找记录时使用二分法快速定位要查询的记录在哪个槽哪个记录分组定位到槽后再遍历槽内的所有记录找到主键为 6 的记录。 可以看到在定位记录所在哪一个页时也是通过二分法快速定位到包含该记录的页。定位到该页后又会在该页内进行二分法快速定位记录所在的分组槽号最后在分组内进行遍历查找。 聚簇索引和二级索引 另外索引又可以分成聚簇索引和非聚簇索引二级索引它们区别就在于叶子节点存放的是什么数据 聚簇索引的叶子节点存放的是实际数据所有完整的用户记录都存放在聚簇索引的叶子节点二级索引的叶子节点存放的是主键值而不是实际数据。 因为表的数据都是存放在聚簇索引的叶子节点里所以 InnoDB 存储引擎一定会为表创建一个聚簇索引且由于数据在物理上只会保存一份所以聚簇索引只能有一个。 InnoDB 在创建聚簇索引时会根据不同的场景选择不同的列作为索引 如果有主键默认会使用主键作为聚簇索引的索引键如果没有主键就选择第一个不包含 NULL 值的唯一列作为聚簇索引的索引键在上面两个都没有的情况下InnoDB 将自动生成一个隐式自增 id 列作为聚簇索引的索引键 一张表只能有一个聚簇索引那为了实现非主键字段的快速搜索就引出了二级索引非聚簇索引/辅助索引它也是利用了 B 树的数据结构但是二级索引的叶子节点存放的是主键值不是实际数据。 二级索引的 B 树如下图数据部分为主键值 因此如果某个查询语句使用了二级索引但是查询的数据不是主键值这时在二级索引找到主键值后需要去聚簇索引中获得数据行这个过程就叫作「回表」也就是说要查两个 B 树才能查到数据。不过当查询的数据是主键值时因为只在二级索引就能查询到不用再去聚簇索引查这个过程就叫作「索引覆盖」也就是只需要查一个 B 树就能找到数据。 五、总结 InnoDB 的数据是按「数据页」为单位来读写的默认数据页大小为 16 KB。每个数据页之间通过双向链表的形式组织起来物理上不连续但是逻辑上连续。 数据页内包含用户记录每个记录之间用单向链表的方式组织起来为了加快在数据页内高效查询记录设计了一个页目录页目录存储各个槽分组且主键值是有序的于是可以通过二分查找法的方式进行检索从而提高效率。 为了高效查询记录所在的数据页InnoDB 采用 b 树作为索引每个节点都是一个数据页。 如果叶子节点存储的是实际数据的就是聚簇索引一个表只能有一个聚簇索引如果叶子节点存储的不是实际数据而是主键值则就是二级索引一个表中可以有多个二级索引。 在使用二级索引进行查找数据时如果查询的数据能在二级索引找到那么就是「索引覆盖」操作如果查询的数据不在二级索引里就需要先在二级索引找到主键值需要去聚簇索引中获得数据行这个过程就叫作「回表」。
http://www.dnsts.com.cn/news/111828.html

相关文章:

  • 如何替换网站上的动画mip wordpress主题
  • 如何做网站创业网站无法发送邮件wordpress
  • 有哪些网站可以做全景效果图东道设计地址
  • 华亭县门户网站东莞中赢网站建设公司怎么样
  • 阳泉网站设计Wordpress大前端DUX5.0主题
  • 南宁微网站制作私企建筑公司排名
  • 农业信息中心网站建设衡阳专业的关键词优化终报价
  • 北京建网站服务wordpress+php版本太低
  • 网站建站外包公司国外好用的网站
  • 网站内怎么做搜索网页微信截图快捷键
  • 雄县有做网站的吗查看网站是什么语言做的
  • 建设网站开通网线多少钱广州seo服务外包
  • 福田附近公司做网站建设哪家效益快个人主页图片
  • 做网站选什么配置电脑企业网站导航优化
  • 北京怎么建立网站知名网建公司
  • 成都城乡建设网站js弹出网站
  • 正定网站建设网上怎么做销售
  • 建设化妆品网站的成本网站建设先做前台还是后台
  • wordpress熊掌号seo的英文全称是什么
  • 网站后台地址忘了苏州app软件开发公司
  • 如何用服务器搭建自己的网站如何修改网站备案
  • 电商网站开发文档莱芜房产网二手房出售信息
  • 预付网站制作费怎么做凭证铜川北京网站建设
  • 深圳 福田 网站建设软件开发文档管理工具
  • 小说网站搭建教程济南seo优化外包服务
  • 如何搭建自己的网站服务器地址免费素材免费下载
  • 怎么把现有网站开发php广州网站优化建设
  • 库尔勒谁在做电商网站建设网站的竞品分析怎么做
  • 办网站如何备案seo免费自学的网站
  • 如何做论坛网站 知乎济南百度公司做网站吗