1. インデックスを知る
MySQL ブックのインデックスの内容を見つけたいとします。MySQL ブックを 1 つずつ手に取って見つけるのではなく、MySQL ブックのカタログを読んで、それに対応するページ番号を見つけます。カタログ内の索引を参照し、対応するページ番号の索引の内容を表示します。
インデックスの利点:
索引は書籍の目録に相当し、索引を使用すると検索速度が向上します。
インデックスの欠点:
インデックスを使用すると検索が高速化されますが、追加、削除、変更の際に作成されたインデックスを調整する必要があるため、追加、削除、変更のコストも増加します。
インデックスによって領域のオーバーヘッドも増加し、インデックスの構築には保存するために追加のハード ディスク領域が必要になります。
インデックスはインデックスを意味し、インデックスを表示するかインデックスを作成するかに関係なく、インデックスに関する操作のみが通常インデックスという単語を持ちます。
2. インデックス操作
2.1 インデックスを表示する
通常、主キー制約、一意制約、および外部キー制約を作成すると、対応する列のインデックスが自動的に作成されます。
次に、インデックスを表示するための Student テーブルを作成します。
student 表:
create table student(id int primary key,name varchar(20));
上記で作成した Student テーブルの ID は主キーなので、ID によってインデックスが自動的に生成されます。Student テーブルのインデックスをクエリすると、ID インデックスを見つけることができます。
インデックスの表示: テーブル名からインデックスを表示します。
2.2 インデックスの作成
データテーブル内の列にインデックスを作成する場合は、次の点を考慮する必要があります。
データ量が多く、これらの列に対して条件付きクエリが実行されることがよくあります。
これらの列では、データ テーブルの挿入、変更、削除操作の頻度が低くなります。
インデックスは追加のディスク領域を占有します。ディスク領域が十分であるかどうかを検討してください。
非主キー、非一意制約、および非外部キーに対応するフィールドに対して通常のインデックスを作成できます。
学生テーブルを作成します。
//如果有student表,请先删除在创建
create table student(id int primary key,name varchar(20));
インデックスを作成します: create Index インデックス名 no テーブル名 (フィールド名);
create index index_name on student(name);
注意: インデックスを作成するには、テーブル作成の最初にインデックスを作成するのが最善です。そうでない場合、テーブル内にすでに多くのレコードがあるテーブルの場合、インデックスの作成は危険な操作です。この時点で大量の IO を実行すると、時間がかかります (主にデータ量に応じて、数十分から数時間かかる場合があります)。この間、データベースは正常に使用できません。
2.3 インデックスの削除
次に、1.3で追加したインデックスを削除します。
インデックスの削除: テーブル名のインデックスインデックス名を削除します。
drop index index_name on student;
注: インデックスを削除すると、大量のディスク IO が消費される可能性があります。
3. MySQL のインデックス データ構造
1. MySQL のインデックスのデータ構造はハッシュ テーブルですか?
回答: ハッシュ テーブル内の要素を見つける時間計算量は O(1) ですが、ハッシュ テーブルは等しいかどうかの比較のみが可能であり、範囲クエリは実行できないため、ハッシュ テーブルはデータベースのインデックス作成には適していません。
2. MySQL のインデックスのデータ構造は二分探索木ですか?
回答: 二分探索木で要素を見つける時間計算量は O(n) です。二分探索とは、要素の数が多い場合、木の高さが比較的高くなるということを意味します。ツリーの高さによって、クエリ時の要素の比較数も決まります。
3. MySQL のインデックスのデータ構造は N 分探索木ですか?
回答: N 分探索木の各ノードには複数の値があり、同時に複数のフォークがあるため、木の高さは低くなります。代表的な実装の 1 つは B ツリーと呼ばれます。比較の数は減っていませんが、1 つのノードで複数回比較する必要がある場合がありますが、ハードディスクへの読み取りと書き込みの数は減り、各ノードはハードディスク上にあります。
B ツリー:
B ツリーは N 分木の典型的な実装であり、その特徴は、各ノードに複数の値があり、子ノードの値がすべて親ノードの値よりも小さいことです。
B ツリーはすでに二分探索ツリーよりもデータベースのインデックスに適していますが、それだけでは十分ではありません。このために、B ツリーをさらに改良した B+ ツリーが導入されています。B+ ツリーは、このシーンのインデックスを作成するために特別に作成されたデータ構造です。
B+ ツリーに固有:
B+ ツリーは N フォーク探索ツリーでもあります。各ノードには N 個のキーが含まれ、N 個のキーで N 個の間隔が分割されます。最後のキーは最大値に相当します。
親要素のキーは子要素に繰り返し表示され、最大値として表示されます。この繰り返しの表示により、リーフ ノードにすべてのデータの完全なセットと、非要素のすべての値を含めることができます。葉ノードは葉ノードに反映されます。
リーフ ノードは、リンク リストと同様の方法で端から端まで接続されます。
B+ ツリー:
B+ ツリーの利点:
N-fork 検索ツリーとして高さが低くなり、ハードディスク IO 数が相対的に少なくなります (B-tree と同様)
範囲クエリに適しています
すべてのクエリはリーフ ノードに分類され、どの要素がクエリされるかに関係なく、中間の比較の数はほぼ同じです。B ツリーの場合、各クエリの速度は異なる場合がありますが、B+ ツリーの場合、各クエリの速度は同じです
すべてのキーがリーフ ノードに反映されるため、すべてのデータ行をリーフ ノードに配置するだけで済みます。非リーフ ノードは、行全体ではなく単純な ID を保存するだけで済みます。これは、非リーフ ノードが占有するスペースが大幅に削減されることを意味します。
有的表不仅有主键索引,还有别的非主键列也可能有索引,此时如何构造B+树?
答:构造一个主键列的B+树,然后再构造一个非主键列的 B+ 树。非主键列有索引的 B+树非叶子节点里面存的都是一些key(比如:一些学生姓名),到了叶子节点这一层,存的并不是完整的数据行,而是存的主键值。如果使用主键列进行查询,只需要查询一次主键列 B+树即可。如果采用非主键列来查询,则需要先查一遍非主键列的B+树,然后再查一遍主键列的B+树
当前B+树这个数据结构,只是针对 MySQL 的 innoDB 这个数据库引擎里面所典型使用的数据结构。不同的数据库,不同的引擎,里面存储数据的结构可能也不同