コース一覧
データベース内部構造:インデックス・トランザクション・分散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

レプリケーション

重いのは読みか、書きか

DB が悲鳴を上げているとき、最初に分けるのはここです。どちらかで打ち手がまったく変わります。

一覧、検索、詳細表示のような読み取りが大半を占めているなら、同じ内容のコピーを何台か用意して、読み取りだけをそちらへ回せば台数ぶん楽になります。これがレプリケーションです。書き込みを受け付ける 1 台を Primary、コピー側を Replica と呼びます。

注意すべきは、これで軽くなるのが読み取りだけだということです。書き込みは相変わらず Primary 1 台に集まります。Replica を 10 台に増やしても、書き込みの限界は 1 ミリも動きません。

測り方は難しくありません。単位時間あたりの SELECT の本数と、INSERT や UPDATE の本数を比べるだけです。一般的な Web サービスは読みが 9 割を超えることが多く、その場合はコピーを増やす効果が素直に出ます。逆に、計測値やログの蓄積が負荷の中心なら、読みをいくら分散させても何も変わりません。

コピーは必ず、少し遅れて届く

Primary の変更は、変更内容のログとして Replica へ送られ、向こう側で適用されます。送って適用するまでに時間がかかるので、コピーは常に少し過去です。

プレーンテキスト

Primary  INSERT INTO users ... ('Alice')     -- 成功
Replica  SELECT * FROM users WHERE ...       -- 0 件

会員登録の直後にマイページへ飛ばしたら「ユーザーが見つかりません」と出る、という形で表に出ます。バグに見えますが、読み書きを分けた時点で必ず生まれる性質です。

対策は、遅れをなくすことではなく、遅れても困らない経路を作ることです。書き込んだ直後の読み取りだけ Primary に向ける、というのがいちばん素直な形です。

JavaScript

const rows = justWrote
  ? await primary.query("SELECT ...")
  : await replica.query("SELECT ...");

COMMIT を返す前に、どこまで待つか

遅れをどこまで許すかは、Primary が COMMIT を返すタイミングで決まります。

送っただけで返すなら、Primary の速度はほぼそのままですが、Primary が壊れた瞬間に、まだ届いていなかったぶんが失われます。Replica が受け取ったのを確認してから返すなら、失われるぶんは減りますが、その往復のぶん毎回遅くなります。全台の反映を待つなら、1 台の不調がそのまま全体の停止になります。

既定はたいてい、送っただけで返す形です。速い代わりに、Primary の故障時に直近の数件が消えることを受け入れています。決済のように 1 件も消せない処理があるなら、その系統だけでも確認を待つ設定にできないかを考えます。Primary が落ちた後は Replica の 1 台を昇格させて再開しますが、切り替えには数秒から数分かかり、その間の書き込みは止まります。

解説

レプリカの遅れは「ある」前提で設計する。「ない」前提のコードが事故になる。

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

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

  • branchGit で開発するときに毎日打つ 5 つの基本コマンド
  • 処理計算や代入を表す長方形
  • 設計何をどう作るかを決める前工程
生田 陸人
監修生田 陸人
ゆめさくエンジニア / 現役ソフトウェアエンジニア監修者プロフィールを見る →
編集 ゆめさく編集部·公開 2026/05/27·更新 2026/08/26

関連レッスン

  • シャーディング

    水平分割でデータを分散し書き込みを拡張する手法

  • CAP 定理

    Consistency / Availability / Partition tolerance の同時達成不可性

  • 結果整合性

    BASE と AP 系システムが選ぶ妥協と利点

  • NewSQL と分散 SQL

    TiDB / Spanner が実現する分散環境での ACID

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

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