コース一覧
データベース内部構造:インデックス・トランザクション・分散DB
第2正規形

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

第2正規形

商品名を直すのに、注文明細を全部書き換える

注文明細の表を考えます。1 行が「どの注文の、どの商品が、いくつ」を表すので、行を特定するには注文 ID と商品 ID の 2 つが要ります。主キーが 2 列の組になっている表です。

ここに、表示が楽だからという理由で商品名と価格まで書き写しました。

注文 ID商品 ID個数商品名価格
11002りんご500
12003バナナ300
21001りんご500

商品名を「りんご」から「青森りんご」に直す指示が来ました。直す先は商品の表ではなく、その商品が登場した過去の注文明細の全行です。3 年分あれば数万行になります。

しかも、数万行のうち 1 行でも書き換えに失敗すれば、同じ商品 ID の行に 2 つの名前が並びます。どちらが正しいのかは、もう表からは判断できません。

主キーの片方だけで決まる列を探す

なぜこうなったのかは、列を 1 つずつ見ていけば分かります。

個数は、注文 ID と商品 ID の両方が決まって初めて決まります。ところが商品名は、商品 ID だけで決まります。注文 ID は関係ありません。価格も同じです。主キーの一部だけで決まる列が、主キー全体で特定する表に混ざっている。これが直すべき箇所です。

この点検は、主キーが 2 列以上あるときだけ意味があります。主キーが 1 列なら「その一部」というものが存在しないので、条件は自動的に満たされます。意味のない番号を主キーに立てる設計が広まっているのは、こうした点検が要らなくなる効果もあるからです。裏を返せば、間に立てた表のように主キーを組にしたときだけ、列ごとに問い直す必要があります。

設計レビューでの手順も決まっています。まず主キーが何列あるかを数える。2 列以上なら、残りの列を 1 つずつ取り上げて「この列を決めるのに、主キーの両方が要るか」と問う。片方だけで足りる列が見つかったら、その片方と一緒に別の表へ出す。それだけです。

切り出し先は商品の表です。商品名と価格をそちらへ移すと、名前の変更は 1 行で終わり、まだ 1 度も注文されていない商品も登録できるようになります。

注文したときの値段は、商品マスタの値段ではない

ここで 1 つ注意があります。価格を商品の表へ移したのだから、明細から価格を消してよいかというと、そうではありません。

商品の表にある価格は「いまの価格」です。値上げをした瞬間に、過去の注文の合計金額まで変わってしまいます。売上の集計が昨日と今日で食い違い、発行済みの領収書とも合わなくなります。

そこで明細には、注文が成立した時点の単価を別に持たせます。これは書き写しに見えますが、切り出す対象ではありません。「いまの価格」と「あのとき合意した価格」は、たまたま値が同じだっただけの別の事実だからです。単価は注文 ID と商品 ID の組で決まるので、主キーの一部だけで決まる列にも当たりません。

見分け方は「その値がいつのものか」を問うことです。同じ 500 円でも、商品の表の 500 円は今日の値段、明細の 500 円は去年の 3 月に合意した値段です。名前が同じで値も同じでも、指しているものが違えば別の列として持ちます。

主キーが組になっている表で、その一部だけで決まる列が残っていない状態が第 2 正規形です。

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

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

  • 外部キーテーブル同士を結びつける鍵
  • 主キーレコードを一意に特定する列
  • 判断YES/NO 分岐を表す菱形
  • 設計何をどう作るかを決める前工程
  • レビューコードを読み合い品質を上げる工程
  • ビュークエリに名前をつけて再利用する仮想表
生田 陸人
監修生田 陸人
ゆめさくエンジニア / 現役ソフトウェアエンジニア監修者プロフィールを見る →
編集 ゆめさく編集部·公開 2026/05/27·更新 2026/08/26

関連レッスン

  • 第3正規形

    推移関数従属を排除し非キー属性の独立性を確保する

  • 非正規化のトレードオフ

    読み取り性能のために冗長を許容する判断基準を学ぶ

  • インデックスの役割

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

  • トランザクションとは

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

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

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