我々はすでに、単一のデータ・ページ内のデータを探すときに検索条件が主キーである場合、あなたは特定のデータを見つけるために、データを通じてための溝、その後、二分法の位置決め溝を使用することができることを知っている。しかし、私たちはどのように数十ページの何千もの知りません我々はレコードは、我々だけで、最初のページから一緒にできるページにすばやく移動することができないので、それは主キー列または任意の他の列の値を見つけることであるかどうかに基づいて、インデックスが存在しない場合には、そのページ内のデータを検索します二重にリンクされたリストは、我々だけの道を見つけなければならなかったしつこいに基づいて特定のレコードを見つけるために、各ページを見下ろしてきました。
単純なインデックスはじめに
迅速にそのページのデータを見つけることができるようにするために、インデックスが提供する下一个数据页中用户记录的主键值必须大于上一个页中用户记录的主键值。
データを発見する効率を向上させる方法を確認するためにケースを使用して、次のランキング:
テーブルを作成します。
mysql> CREATE TABLE index_demo(
-> c1 INT,
-> c2 INT,
-> c3 CHAR(1),
-> PRIMARY KEY(c1)
-> ) ROW_FORMAT = Compact;
Query OK, 0 rows affected (0.03 sec)
3つのデータを挿入します。
mysql> INSERT INTO index_demo VALUES(1, 4, 'u'), (3, 9, 'd'), (5, 3, 'y');
Query OK, 3 rows affected (0.01 sec)
Records: 3 Duplicates: 0 Warnings: 0
わずか3つのindex_demoテーブルレコードがデータページ10の数に挿入された3つの一般的なユーザー・レコードを格納することができるページを仮定し、レコードを再度挿入します。
mysql> INSERT INTO index_demo VALUES(4, 4, 'a');
Query OK, 1 row affected (0.00 sec)
10ページまでしか3つのレコードを置くことができますので、私たちは、ページの新しい再配布していました:
ユーザーのプライマリキーは最大5で10ページ、レコード、ページ28とレコードが、これはデータの次のページの主キーの値と一致していないので、5> 4は、ユーザーがより大きくなければなりませんに記録するので、主キー値は、4でありユーザに記録されたページの主キーを必要とするので、キーは、移動履歴を伴う必要なときに、プライマリ・キーは、ページ28に移動され、メインレコード4に挿入されている5に記録され、そしてレコード4の主キーは、10ページに挿入されています。
操作にページの追加および削除を記録する過程で、我々は常にそのように設定されている状態を記録するなどの操作の数を移動することを確認しなければならないことをこのプロセスのショー:
下一个数据页中用户记录的主键值必须大于上一个页中用户记录的主键值。这个过程我们也可以称为页分裂。
いくつかのデータを挿入した後、それは次のようになります。
だから、あなたはすぐにいくつかのレコードの主キー値に従ってページを検索しますので、多くのページから必要な場合、我々はディレクトリであるためにそれらを与える必要があり、各ページに対応するディレクトリエントリは、各ディレクトリエントリは、次の2つの部分が含まれています。
ページのユーザーは、私たちが表現するためにキーを使用し、最小の主キーの値を記録します。
ページ番号、我々はpage_noを使用しています。
私達はちょうどあなたが主キーの値の記録に基づいて迅速な検索機能を実現することができ、例えば、配列に入れ、連続物理メモリに保存されているいくつかのディレクトリエントリが必要です。我々は、特定の2段階のプロセスの主キーレコード20、表情を探しているとしましょう:
開始はすぐページ9二分法であるページに対応するディレクトリエントリ20 3(以降12 <20 <209)に記録された主キー値のディレクトリエントリを決定します。
そして、フロントページにある道の記録と言うを見つけるに基づいて特定のレコードを検索するために、9ページに進みます。
ページディレクトリという名前のインデックスの名前。
InnoDBのインデックス
我々は継続的に物理メモリ上に格納されているアイテムをカタログによると、すべての主キーの値を見つけるために、カタログ内の特定の項目を素早く二分法を使用見つけるために想定しているため、トップは、シンプルなインデックススキームと呼ばれ、
InnoDBは16キロバイトに連続ストレージスペースを確保次第、あるストレージスペースの管理、などのページを使用して、基本的な単位であり、テーブル内のレコード数の増加に伴って、あなたはアイテムが鎮圧されているすべてのカタログを置くことは非常に大きな連続した収納スペースを必要としますまた、私たちはしばしば、もはやが必要とされ、もはや必要はないだろうディレクトリエントリ2を意味し、必要がない、レコードの追加および削除を持って、我々はレコードの28ページを削除したとし、28ページ2つのカタログ項目の後にディレクトリエントリはおよそ前方に移動しています
管理するための非常に柔軟な方法を提供する必要InnoDBは、この時点では目录项记录
、それがディレクトリレコードがデータレコードの一般的な管理に基づいて管理することができない。RECORD_TYPEだろう唯一の違いは、ディレクトリデータ記録や通常のデータ記録。後再考した後、ページ内のデータは、ページ管理データの形で管理することができます記録されます。
ディレクトリエントリの記録データの記録および一般的な違い:
通常、ユーザーが値0が記録されているRECORD_TYPEながら1 RECORD_TYPE値レコードディレクトリエントリは、1です。
2.カタログレコード番号と主キーの値のページの2つの列のみ、平均的なユーザー・レコードの列は、ユーザー定義されている一方で、多くの列が含まれていてもよい、自分のInnoDBのに加えて、非表示の列が追加されました。
min_rec_mask値1を記録したディレクトリエントリに格納されたページディレクトリエントリに記録された3最小限の主キー値を、他の別の記録min_rec_maskの値が0であります
これら三つの異なる、他の部分はインデックスページがページを埋めストアが高いページディレクトリを格納し、生成し続けるために、後で拡張することができるときである同じですに加えて、最後のレンダリングは、このになりました:
そして、ゆっくりと抽象化:
その名は、B +ツリーです。
店舗ユーザデータページレコード、またはストアデータページディレクトリエントリを記録するかどうか、我々はまた、ノードのデータのこれらのページを呼び出すように、それらは、B +ツリーデータ構造に保存されていると考えています。それは実際には、我々の実際のユーザ・レコードもリーフノードまたはリーフ・ノードとして知られているノードB +ツリーの底部に格納され、図から分かるように、ストアディレクトリエントリに使用される残りのノードは非リーフノードと呼ばれ又はB +ツリーはまた、最上層のルートとして知られている。説明を容易にするために、最下層の規定は、その層が、私たちのユーザレコードの0層として格納され、その後、加算オンことノードノード、内。
概算木の力ページは、100個のデータを保存することができた場合:
B +ツリーは一つだけアップ100件のレコードを格納するために、ユーザによって記録されたノード記憶するためである一層のみである場合、
B +ツリーが1000×100 = 100000のレコードを格納するまで、二つの層を有する場合、
B +ツリーが3層を有する場合に、 ×1000×1000 100 = 100000000件のまでのレコードを保存します。
B +ツリーは、4つの層を持っている場合は、1000年1000×1000×まで保存することができます×100 =千億レコードを
一般的に、我々は唯一の最も4ページの観光を見つけるために、レコードを見つけるために、主キーの値によって、これ以上の4層よりもB +ツリーを使用するので、通常の状況下では、テーブルに記録千億がないではないだろう(3を探しますページディレクトリエントリとユーザーのページを記録)、およびそこにいわゆるページディレクトリは、各ページ内(ページディレクトリ)ですので、ページは迅速に実装することができるので、することは二分法でレコードを探します
クラスタ化インデックス
上記のツリー構造は、以下の2つの特性があります。
1.主キーを使用して記録のサイズとソート記録ページ
2.B +ツリーのリーフノードは、完全なユーザレコードに保存されています
これら二つの特性を持つ+ Bがツリーと呼ばれ聚簇索引
、すべてのユーザーのレコードがこのクラスタインデックスのリーフノードに格納されています。MySQLのステートメントを作成するために、当社の明示的な使用INDEX文を必要としないこのクラスタ化インデックスは、InnoDBストレージエンジンが自動的に私たちのためにクラスタ化インデックスを作成します。
クラスタ化インデックスは、データをチェックするための主キーであるため、とき私たちのクエリはプライマリキーを含めることはできません、あなたはまだデータすべてを最初から最後までやる必要がありますか?
セカンダリインデックス
私たちのクエリは、C2列の値であると仮定し、その後、我々はC2列B +木の値に種類の新しいポストを作成する必要があります。
いくつかの異なるして上に導入クラスタ化されたB +ツリーインデックス:
-
意味の三つの側面を含む、ソートレコードとページにレコードC2列のサイズを使用します。
- それは、単独リンクリストに配置されたサイズのC2列のページ順に記録されています。
- 各ページには列c2に記録されているページの順序に従って、二重リンクリスト内に配置されているユーザレコードを保管してください。
- レコードストレージディレクトリページは、列C2に記録された発注ページディレクトリエントリに応じて配置されている二重連結リスト内の同じレベルで異なるレベル及びページに分割されます。
-
これは、B +ツリーのリーフノードに格納されている完全なユーザ・レコードではなく、これらの二つの列の列のみC2 +主キーの値。
-
ディレクトリレコードは、もはやC2 +ページ番号が一致し、列になったページ番号が一致し、主キー+、ではありません。
だから我々はあなたが私たちだけで構築されたこのB +ツリーを使用することができ、C2列の値によって記録されたいくつかの単語を検索する場合。次のようにレコードのルックアップ列にC2は、一例として見て4です。
-
pが42である場合、ルート・ページ、すなわちページ44によれば、履歴ページディレクトリエントリを決定し、ページディレクトリを迅速にレコードを検索することができる(2 <4 <9以降)。
-
実際のユーザーがページディレクトリエントリを記録することで、ページを記録場所を決定。ページのページ42に迅速に実際に格納されているユーザのレコードを検索することができるが、単一の列c2制約がないので、4の記録C2列の値は、データの複数のページに分散させることができる、及び、4≤4 <2ため34ページには、ページと実際のストレージ35件の記録、ユーザのページに決定されます。
-
実際のユーザレコードのページに格納された特定のレコードに移動します。ページ34とページ35には、特定のレコードを対象とします。
-
しかし、我々はので(で、主キー)のみC2とC1で、このB +ツリーのリーフノード店のレコードを2つの列
必须再根据主键值去聚簇索引中再查找一遍完整的用户记录。这个过程也被称为回表。也就是根据c2列的值查询一条完整的用户记录需要使用到2棵B+树
の操作を必要としたが、スペースを節約するために戻ってテーブルにしています。
これはまた、B +ツリーインデックス2つ(英語二次インデックス)、又は二次指数として知られているようので、B +ツリーの非プライマリ・キー列にこの完全なユーザ・レコードの前に配置することができる手術台への復帰を必要とします。我々は、このB +ツリーが確立インデックス付きの列c2で呼び出すので、私たちが使用しているので、B + C2列照合木の大きさです。
共同インデックス
また、同時にある照合など、複数の列のサイズは、例えば、我々はB +ツリーは、サイズC2、C3の列に基づいてソートしたいインデックス複数の列に同時に、これは2つの意味が含まれていることができます。
まず、各レコードのページと列c2でソート。
同一の記録列C2、C3ソートカラム用いた場合に
レンダリング:
-
C2、C3によって記録された各ディレクトリエントリは、三つの部分のページ数、各レコードは、カラムC2の値によってソートする、C2列が同じレコード場合、塔C3の値に従ってソート。
-
記録ノードC2、C3、および主キー列C1からB +ユーザ葉
-
C2およびC3サイズ列がB +ツリーインデックスジョイントと呼ばれる照合として確立されているに、本質的に二次的指標です。これは、列C2およびC3はそれぞれインデックス式が異なる意味します
ノートInnoDBのB +ツリーインデックス
ページ番号のルートページは変更されません
我々は(存在しない場合、デフォルトが作成されます)テーブルにクラスタ化インデックスを作成するときは、ルート・ページとなっているが、今回はデータが保存されていないルートページ。
データストレージがいっぱいになったときにデータを追加するとき、データテーブル、ルート・ページ以前に格納されたデータの添加は、ページにコピーしたデータは、ページ分割を生成することは、ページBを発生した場合、この時間は、ルート・ページ内に格納されていますページのディレクトリが記録されています。
彼らはインデックスにアクセスするために、固定の場所からページ番号を根絶すること、InnoDBストレージエンジンのインデックスを使用するために必要な方。
ページ内のノードの一意性
セカンダリインデックスが列でソートされたとき、これは、セカンダリインデックスのための唯一の問題であり、同じような状況は、主キーの一意性を区別する必要があるとともに、この時間が発生する可能性がある。ほかにデータを追加するだけでターゲットページ。
少なくとも1つのページストア二つのレコード
あなたはレコードのみを入れた場合、絵は想像できない、あまりにも美しくなるためです。
ステートメントを作成、削除、インデックスのMySQL
InnoDBは自動的に自動的にB +ツリー索引を作成するために主キーまたはUNIQUE列として宣言されますが、私たちは、他の列のビルドインデックスにしたい場合、我々は、明示的に指定する必要があります。
我々は、単一の列がテーブルの作成や複数の列の共同インデックスの設立にインデックスを作成する必要が指定できます。
CREATE TALBE 表名 (
各种列的信息 ··· ,
[KEY|INDEX] 索引名 (需要被索引的单个列或多个列)
)
またはテーブルへの変更:
ALTER TABLE 表名 ADD [INDEX|KEY] 索引名 (需要被索引的单个列或多个列);
あなたはまた、削除インデックスが時にテーブル構造を変更することができます。
ALTER TABLE 表名 DROP [INDEX|KEY] 索引名;
具体的な例:
CREATE TABLE index_demo(
c1 INT,
c2 INT,
c3 CHAR(1),
PRIMARY KEY(c1),
INDEX idx_c2_c3 (c2, c3)
);
ALTER TABLE index_demo DROP INDEX idx_c2_c3;