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

非正規化のトレードオフ

「先月の売上」を出すたびに 30 秒待つ

分けるほど健全になる、という話をしてきました。ここでは逆を向きます。

管理画面に「先月の売上」を出しています。注文と明細と商品と会員を結合し、300 万行を足し上げる。開いた人は毎回 30 秒待たされます。しかも遅いのは、その画面だけではありません。その 30 秒のあいだ、同じ DB で動いている注文の処理まで巻き込まれて遅くなります。ここで足りていないのは設計の正しさではなく、読む速さです。

正規化を崩して、あえて同じ値を 2 か所に置く判断を非正規化と呼びます。順番が大事で、先に分けきってから、測った結果として崩します。最初から崩した設計は、ただの雑な設計です。

崩し方は大きく 2 通りです。1 つは、結合しないと取れない値を手元の表にも書き写すこと。商品一覧を出すたびに分類名を引きに行くのをやめて、商品の表に分類名も持たせる、といった形です。もう 1 つは、毎回計算している値をあらかじめ置いておくこと。会員ごとの購入累計を、注文が入るたびに足し込んでおくのがこれにあたります。

冗長を足した瞬間、真実が 2 か所になる

書き写した以上、両方を合わせ続ける責任が生まれます。

分類名を変えたら商品側も直したか。注文が入ったら累計に足したか。注文が取り消されたら引いたか。返品されたら。この「忘れずに直す」をアプリのコードだけで守り切るのは無理があります。書き込む場所が 1 つ増えるたびに、抜け道が増えるからです。

守り方は次のいずれかです。

  • DB 側の仕掛け — 変更をきっかけに自動で相手も直す。確実だが、追いにくい処理が裏で走る
  • 定期的な作り直し — 集計結果を保持する仕組みを使い、決めたタイミングで作り直す。少し古い値を許せるなら扱いやすい
  • 出来事を起点に更新 — 「注文が確定した」という出来事を一度だけ発火させ、それを受けて集計を直す

どれを選ぶにせよ、非正規化を入れると決めた時点で、同期の仕組みまでを 1 セットで設計します。片方だけ入れると、ずれた値を誰も直せない状態になります。

それでも、ずれは起きます。起きる前提で、定期的に本来の値を計算し直して突き合わせる仕組みを別に用意しておきます。ずれていたら直し、直した件数を記録する。この見張りがないと、崩した値が正しいかどうかを誰も確かめないまま、何年も動き続けることになります。

崩す前に、測る

もう 1 つ、性能とは関係のない非正規化があります。時間を固定するための書き写しです。

請求書の宛先住所を、会社の表から毎回引いてくる設計にすると、会社が引っ越した瞬間に過去の請求書の宛先まで書き換わります。発行時点の住所は請求書の側に焼き付けておくのが正解で、これは冗長ではなく別の事実です。

性能のための非正規化に進む前には、必ず次を確かめます。分けたままで本当に遅いのか、読みと書きの比はどれくらいか、元の値が変わる頻度は十分低いか、ずれたときに業務がどう困るか。速くしたいという気持ちだけで崩すと、後から必ず食い違いの事故が起きます。

なお、注文や決済を捌く側は分けたまま、レポートを見る側は崩した表を別に用意する、という分業もよく使われます。同じデータでも、書く場所と読む場所では最適な形が違うためです。分析の側は多少古い値でも構わないことが多く、そこが分けやすさの根拠になっています。

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

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

  • 処理計算や代入を表す長方形
  • 設計何をどう作るかを決める前工程
  • 正規化データの重複を減らし整合性を保つ設計手法
  • 判断YES/NO 分岐を表す菱形
  • 分類カテゴリを当てる教師ありタスク
  • 同期処理が終わるまで次に進まない実行順
  • セット重複を持たない順序なし集合
生田 陸人
監修生田 陸人
ゆめさくエンジニア / 現役ソフトウェアエンジニア監修者プロフィールを見る →
編集 ゆめさく編集部·公開 2026/05/27·更新 2026/08/26

関連レッスン

  • インデックスの役割

    全件走査と索引参照の違いを計算量から把握する

  • トランザクションとは

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

  • クエリプランナの役割

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

  • レプリケーション

    Primary / Replica 構成での読み取り分散と整合性

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

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