構造]ページ
基本的なページは、ストレージスペースをInnoDBの単位で管理され、それが16キロバイトの大きさについて、一般的です。実際には、ページの多くの異なる種類がありますが、私たちがご紹介メインページは、インデックスページと呼ばれるデータを格納するために使用されます。
その後、構造のインデックスページを見てみましょう:
もっと重要なのは、三つの領域は以下のとおりです。
- +最低ファイナル
- ユーザレコード
- ページディレクトリ
明らかに他の二つの領域は、後に説明するが、実際には未使用のスペースが行が記録されたユーザレコード店、および空き領域のページスペースと呼ばれています。
ページに保存されたレコード
構造の単純化されたバージョンの下の行を確認した後:
C1、C2の中で、C3は実際のデータは、ヘッダ情報がページに重要な役割を果たしています。
- delete_mask:レコードが削除されているかどうか、この行を特定のロゴを削除
- min_rec_mask:これはその考えを保持することができ、コンテンツのインデックスであります
- n_owned:私は後に言及します
- heap_no:このページ内の記録位置を示し、このフィールドの開始値が2であることに注意してください。だから、0と1のですか?InnoDBは自動的に記録は最小を表し、各ページには二つのレコード、最大レコードのための1つを追加提供します。以前Infimum + supremumスペースを覚えていますか?二つの記録を保持するために使用されます。
したがって、ページ内のすべてのレコードは、(主キーの大きさの順に配列されていることが重要です) - RECORD_TYPE:一時的に問題のことができ、現在のレコードのタイプを示します
- next_record:このフィールドは、実際のデータ次のレコードに現在のレコードの実データからのオフセットアドレスを識別します。
実際には、要約すると、heap_noとnext_recordにより、単一順序付けられたリストつなぎ合わせ、メインキーの大きさに応じてすべてのレコードのページを置きます。
ページディレクトリ(ページディレクトリ)
我々はレコードを検索したい場合は今、私たちはすべてのレコードは一重リンクリストを注文することになるつなぎ合わせわかったので、それだけで過去にリストをトラバースする必要があります。しかし、この効率は非常に低いことは間違いありません、そして、InnoDBは、それを最適化するために行う方法ですか?
次のように最適化のプロセスは、次のとおりです。
所有的记录会被分成几组,这包括前面所说的最大最小记录
其中最小记录所在的组只能有一条记录也就是它自己,最大记录所在的分组拥有的记录条数只能在 1~8 条之间,剩下的分组中记录的条数范围只能在是 4~8 条之间
- 每组的最后一条记录(也就是主键值最大的一条记录)头信息中的n_owned属性表示该记录拥有多少条记录,也就是该组内共有几条记录。
每组的最后一条记录的地址会被单独提取出来,按照顺序存在页的尾部,其实就是我们前面所说的页目录的地方。每个地址的偏移量在Innodb中被称为插槽
按照上面的规则,我们可以得到这么一副图:
可以看到有两个插槽,意味着被分为了两组,其中:
- 最小记录的n_owned值为1,这就代表着以最小记录结尾的这个分组中只有1条记录,也就是最小记录本身。
- 最大记录的n_owned值为5,这就代表着以最大记录结尾的这个分组中只有5条记录,包括最大记录本身还有我们自己插入的4条记录。
说了这么多条条框框,这对于加快查找又有什么用呢?别着急现在就来揭晓如何使用。
为了更明显的看出区别,我们多加几条记录,并且逻辑上调整了下结构,便于理解:
现在我们就可以利用二分法来查找,比如说我们想找主键值为10的记录,过程是这样的:
计算中间槽的位置:(0+4)/2=2,所以查看槽2对应记录的主键值为8,又因为8 < 10,所以设置low=2,high保持不变。
重新计算中间槽的位置:(2+4)/2=3,所以查看槽3对应的主键值为12,又因为12 > 10,所以设置high=3,low保持不变。
因为high - low的值为1,所以确定主键值为10的记录在槽3对应的组中。此刻我们需要找到槽3中主键值最小的那条记录,然后沿着单向链表遍历槽3中的记录。
怎么定位一个组中最小的记录呢?我们可以很轻易的拿到槽2对应的记录(主键值为8),该条记录的下一条记录就是槽3中主键值最小的记录,该记录的主键值为9。所以我们可以从这条主键值为5的记录出发,遍历槽3中的各条记录,直到找到主键值为6的那条记录即可。
由于前面规定了一个组中包含的记录条数只能是1~8条,所以遍历一个组中的记录的代价是很小的。
所以总结一下在一个页中查找指定主键值的记录的过程分为两步:
通过二分法确定该记录所在的插槽,并找到该插槽中主键值最小的那条记录。
通过记录的next_record属性遍历该槽所在的组中的各个记录。
可以看到在这种情况下,通过分组设置和二分法的配合查询,会比之前直接单链表遍历的方法快太多了。