コース一覧
データベース内部構造:インデックス・トランザクション・分散DB
B+tree(実際の DB 実装)

データベース内部構造:インデックス・トランザクション・分散DB

SQLの書き方ではなく、DBMSの内側を学ぶコースです。RDBとNoSQL、正規化、B-tree、トランザクションとMVCC、クエリプランナ、レプリケーションと分散SQLを通して、性能と整合性の判断根拠を身につけます。

1
データベースの基礎
0. データベースとは8分
1. RDB と NoSQL の違い8分
2. データベースの歴史8分
3. エンティティ関係モデル (ER)8分
4. 主キー・外部キー・候補キー8分
2
正規化
0. 正規化とは何か8分
1. 第1正規形8分
2. 第2正規形8分
3. 第3正規形8分
4. 非正規化のトレードオフ8分
3
インデックスと B-tree
0. インデックスの役割8分
1. B-tree の仕組み8分
2. B+tree(実際の DB 実装)8分
3. ハッシュインデックス8分
4. カバリングインデックス8分
4
トランザクションと ACID
0. トランザクションとは8分
1. ACID 特性8分
2. 分離レベル8分
3. MVCC(マルチバージョン同時実行制御)8分
4. デッドロックと回避8分
5
クエリ最適化
0. クエリプランナの役割8分
1. EXPLAIN の読み方8分
2. Nested Loop / Hash / Merge Join8分
3. インデックスチューニング8分
4. 統計情報とカーディナリティ8分
6
スケーリング
0. レプリケーション8分
1. シャーディング8分
2. CAP 定理8分
3. 結果整合性8分
4. NewSQL と分散 SQL8分

データベース内部構造:インデックス・トランザクション・分散DB

01データベースとは
02RDB と NoSQL の違い
03データベースの歴史
04エンティティ関係モデル (ER)
05主キー・外部キー・候補キー
06正規化とは何か
07第1正規形
08第2正規形
09第3正規形
10非正規化のトレードオフ
11インデックスの役割
12B-tree の仕組み
13B+tree(実際の DB 実装)
14ハッシュインデックス
15カバリングインデックス
16トランザクションとは
17ACID 特性
18分離レベル
19MVCC(マルチバージョン同時実行制御)
20デッドロックと回避
21クエリプランナの役割
22EXPLAIN の読み方
23Nested Loop / Hash / Merge Join
24インデックスチューニング
25統計情報とカーディナリティ
26レプリケーション
27シャーディング
28CAP 定理
29結果整合性
30NewSQL と分散 SQL

データベース内部構造:インデックス・トランザクション・分散DB

B+tree(実際の DB 実装)

30 歳から 50 歳までを取るのに、木を辿り直す

索引で 1 件を引くのは速い。では「30 歳から 50 歳までの会員を全部」はどうでしょうか。

節にも値の実体が置いてある木では、30 歳の行を見つけたあと、次の 31 歳がどこにあるかは分かりません。木のどこかにあるとしか言えないので、また根から辿り直します。該当が 5 万件あれば、5 万回辿り直すことになります。1 件ずつなら速いのに、範囲になった途端に割に合わなくなります。

実際の DB が使っている B+tree は、ここを 2 つの工夫で解いています。

内側の節は、道しるべだけにする

1 つ目は、値の実体を葉だけに置いたことです。内側の節に残るのは「ここから先は 30 以上」といった境界の値だけになります。

これは節約として効きます。1 つの節の大きさは決まっているので、実体を追い出したぶん、境界の値をもっと詰め込めます。詰め込めるほど 1 段で分かれる数が増え、木は浅くなります。代わりに、どの値を探しても必ず葉まで下りることになりますが、下りる段数自体が減っているので割に合います。

2 つ目は、葉と葉を横につないだことです。

diagram (will load when visible)

こうなると、範囲の取り出しは「木を 1 回だけ下りて、あとは横に歩く」で済みます。しかも横に並んだ葉はディスク上でも近くにあることが多いので、飛び飛びに読むより速く読めます。木を辿り直す回数は、最初の 1 回だけです。

つながりは双方向なので、新しい順に取り出したいときは右端から左へ歩けます。並べ替えの指示を書いても、すでに並んでいるものを順に読むだけで済み、全部取り出してから並べ直す作業が発生しません。索引の並び順と、画面に出したい順が一致していると得をするのはこのためです。

全部の列を取りに行くと、索引を 2 回引く

もう 1 つ、実装の側の話があります。MySQL の InnoDB では、主キーの索引の葉に行そのものが入っています。主キーで引くときは、木を 1 回下りればもう行が手に入ります。

主キー以外の列に貼った索引は違います。葉に入っているのは行そのものではなく、主キーの値です。メールアドレスで検索すると、まずその索引を辿って主キーを得て、次にその主キーで主キー側の木をもう一度下ります。2 段構えです。該当が 1 万件あれば、この往復も 1 万回起きます。必要のない列まで含めて全列を取りに行けば、この往復は必ず発生します。逆に、欲しいものが主キーだけなら往復は起きません。

だから一覧を作るときは、返す件数と取る列を先に決めます。1 画面に 20 件しか出さないのに 1 万件を取ってからアプリ側で切ると、往復も 1 万回起きます。

主キーの選び方にも影響します。値がばらばらな主キーを使うと、新しい行が木のあちこちに挿し込まれ、そのたびに節の分割が起きます。時間順に増える主キーなら、追加は木の右端に集まるので分割がほとんど起きません。なお PostgreSQL は本体を別に持つ構造で、主キーの索引も他の索引と同じ扱いです。どちらにせよ長く運用すると節に隙間が溜まっていくので、索引を作り直す定期作業が必要になります。

このレッスンに出てくる用語

意味があいまいなまま進んだ語は、ここから読み直せます。

  • treeディレクトリ構造をツリー表示するコマンド
  • MySQL広く使われるオープンソースのRDBMS
  • 外部キーテーブル同士を結びつける鍵
  • 主キーレコードを一意に特定する列
  • PostgreSQL機能が豊富なオープンソースのRDBMS
生田 陸人
監修生田 陸人
ゆめさくエンジニア / 現役ソフトウェアエンジニア監修者プロフィールを見る →
編集 ゆめさく編集部·公開 2026/05/27·更新 2026/08/26

関連レッスン

  • ハッシュインデックス

    等価検索専用の高速インデックスとその制約

  • カバリングインデックス

    テーブル本体を読まずに済む複合インデックス設計

  • トランザクションとは

    BEGIN / COMMIT / ROLLBACK の意味と必要性を学ぶ

  • クエリプランナの役割

    SQL から実行計画が生成される過程を追う

分からないところは Tap (AI先生) に質問できます

24 時間いつでも、あなたのレベルに合わせて日本語で答えます。