基礎正規化

第2正規形 (2NF)

著者 たいてっく(エンジニア講師 / データエンジニア)最終更新
定義

第2正規形とは、第1正規形を満たし、かつ非キー属性のすべてが候補キー全体に完全関数従属している (候補キーの一部分だけで決まる部分関数従属を持たない) リレーションの状態をいう。

第2正規形のルール: 「主キーの一部だけで決まる列」を追い出す

第2正規形 (2NF) のルールは 2 つ。

  • まず 第1正規形 を満たしていること
  • 主キーが 2 列以上の組 (複合キー) のとき、「複合キーの一部だけで決まってしまう列」があってはいけない。

この「主キーの一部だけで決まる関係」を専門用語で部分関数従属 (partial functional dependency) と呼ぶ。 言葉は難しいが、実データで見ると「同じ商品IDの行では商品名が全部同じ」みたいな、 素朴に「これ重複してるよね」と感じる状態のこと。

実践例: 1NF まで進めた受注テーブル

前ページ で 1NF 化した受注テーブルをそのまま引き継ぐ。 1 行が「1 注文の 1 商品」を表すフラットな表になっている。 このテーブルは 注文ID だけでは 1 行に絞れない (同じ注文で複数商品がある)、商品ID だけでも絞れない (同じ商品が複数注文で買われる)。 両方を組み合わせて (注文ID, 商品ID) の複合キーが主キーになる。

実データで見る冗長: 同じ色の列で同じ値が繰り返される

まず 1NF 受注テーブルを、列がどう決まっているかで色分けして眺める。 すると「同じ色の列で同じ値が何度も繰り返されている」ことが目で見える。 これが冗長性の正体で、次に「なぜこうなるか」を関数従属で分析していく。

1NF 受注テーブル (列を決定関数で色分け)
◆主キー全体 (注文ID, 商品ID) で決まる
■注文ID だけで決まる (部分関数従属)
●商品ID だけで決まる (部分関数従属)
受注 (1NF)
◆
注文IDPK
◆
商品IDPK
■
注文日
■
顧客ID
■
顧客名
■
顧客住所
●
商品名
●
単価
◆
数量
O001P012026-06-01C01田中商事東京ノート3002
O001P022026-06-01C01田中商事東京ペン1501
O002P012026-06-02C02山田工業大阪ノート3005
O003P022026-06-03C01田中商事東京ペン1503
O003P032026-06-03C01田中商事東京消しゴム1004

■ の列: 同じ注文ID (O001 が 2 行, O003 が 2 行) の行では注文日・顧客情報が全く同じ値を繰り返している。● の列: 同じ商品ID (P01 が 2 行, P02 が 2 行) の行では商品名・単価が全く同じ値を繰り返している。◆ の列だけが行ごとに独自の値を持っている。

関数従属で整理すると 3 グループに分かれる

なぜ「同じ色の列」で同じ値が繰り返されているのか。 それは「その列は主キーの一部だけで決まっている」から。 列がどう決まっているかを関数従属で分類すると、9 列がきれいに 3 グループに分かれる。 そしてこの 3 グループがそのまま「2NF 化後に分かれる 3 テーブル」の原型 になる。

1NF 受注テーブルの関数従属分析
完全関数従属◆ (注文ID, 商品ID) → 数量組み合わせで初めて決まる
注文ID商品ID
数量
部分関数従属■ 注文ID → 注文日, 顧客ID, 顧客名, 顧客住所主キーの一部 (注文ID) だけで決まる
注文ID
注文日顧客ID顧客名顧客住所
部分関数従属● 商品ID → 商品名, 単価主キーの一部 (商品ID) だけで決まる
商品ID
商品名単価

◆ の完全関数従属は主キー全体があってはじめて決まる。■ と ● は主キーの片方だけで決まる部分関数従属 — これらが「同じ商品や同じ注文の情報が複数行に重複する」原因になっている。

2NF 化: 3 グループを 3 テーブルに切り出す

あとは分析結果の通りに分ければいい。 「注文ID だけで決まる列」は 受注 テーブルに、 「商品ID だけで決まる列」は 商品 テーブルに、 「(注文ID, 商品ID) の組み合わせで決まる列」は 受注明細 テーブルに、 それぞれ切り出す。

1NF → 2NF: 部分関数従属を別テーブルに
1NF 受注 (すべてフラット)
受注 (1NF)
注文IDPK商品IDPK注文日顧客ID顧客名顧客住所商品名単価数量
O001P012026-06-01C01田中商事東京ノート3002
O001P022026-06-01C01田中商事東京ペン1501
O002P012026-06-02C02山田工業大阪ノート3005
O003P022026-06-03C01田中商事東京ペン1503
O003P032026-06-03C01田中商事東京消しゴム1004
2NF 化後 (3 テーブルに分割 — 色は分割前と同じグループを維持)
受注
注文IDPK注文日顧客ID顧客名顧客住所
O0012026-06-01C01田中商事東京
O0022026-06-02C02山田工業大阪
O0032026-06-03C01田中商事東京
商品
商品IDPK商品名単価
P01ノート300
P02ペン150
P03消しゴム100
受注明細
注文IDPK商品IDPK数量
O001P012
O001P021
O002P015
O003P023
O003P034
部分関数従属を「別テーブル + 元テーブルに FK 残し」の形で切り出す。 商品名・単価は 商品 テーブルに 1 行ずつ集約され、重複が解消。 数量 (完全関数従属) だけが 受注明細 テーブルに残る。 ただし 受注 テーブルにはまだ顧客名・顧客住所が入っており、 同じ顧客の情報が複数行に重複している (これは 3NF で解消する)。

主キーが 1 列だけのテーブルは考えなくて OK

2NF の話は「主キーの一部だけで決まる列があってはいけない」というものなので、 そもそも主キーが 1 列だけのテーブルには関係がない (「主キーの一部」というものが存在しないから)。 つまり 主キーが 1 列だけのテーブルは、1NF を満たしていれば自動的に 2NF も満たす。

2NF 違反を気にする必要があるのは、主キーが複数列の組み合わせになっているテーブル (関連テーブル / 中間テーブルなど) だけ。

練習問題

別のデータで自分でも試してみる。答えを見る前にどう分割すればいいか考えてみてほしい。

練習問題 — 図書貸出テーブルを 2NF にする
以下は図書館の貸出記録を 1NF まで整理したもの。 主キーは (会員ID, 図書ID) の複合キー。 部分関数従属を洗い出し、2NF に分割せよ。
図書貸出 (1NF)
会員IDPK図書IDPK会員名書名貸出日
M01B001山田データベース入門2026-06-01
M01B002山田ネットワーク基礎2026-06-05
M02B001田中データベース入門2026-06-03
M03B003佐藤SQL 実践2026-06-02
答えを見る

関数従属の分析:

  • 会員ID → 会員名 (部分関数従属)
  • 図書ID → 書名 (部分関数従属)
  • (会員ID, 図書ID) → 貸出日 (完全関数従属)

会員関連 (会員名) と 図書関連 (書名) をそれぞれ別テーブルに切り出し、 貸出テーブルには複合キーと貸出日のみを残す形で 3 テーブルに分割する。

貸出
会員IDPK図書IDPK貸出日
M01B0012026-06-01
M01B0022026-06-05
M02B0012026-06-03
M03B0032026-06-02
会員
会員IDPK会員名
M01山田
M02田中
M03佐藤
図書
図書IDPK書名
B001データベース入門
B002ネットワーク基礎
B003SQL 実践

2NF のチェック手順

  1. そのテーブルの主キーを確認する (複数列の組み合わせか?)
  2. 複合キーなら、主キーの「一部だけ」の組み合わせを全部書き出す (例: 主キーが (A, B) なら「A」と「B」)
  3. それ以外の各列について、その「一部だけ」で値が決まってしまわないかを確認する
  4. 決まっていたら、その一部を主キーとする別テーブルに切り出す

ここまで来れば、「主キーの一部で決まる列が重複する」問題は解消される。 ただしまだ別の重複が残っていることが多い。 今回の例で言えば、受注テーブルの中で 顧客ID → 顧客名, 顧客住所 という関係が残っており、 同じ顧客の情報が注文行ごとに繰り返し書かれている。 これを扱うのが次の 第3正規形 だ。

よくある疑問

Q.第2正規形は複合キーがないと関係ない?
A.正しくはありません。単一属性の主キーの場合、部分関数従属が構造的に存在しえないため、1NF を満たせば自動的に 2NF も満たします。判定作業が要らないだけです。
Q.部分関数従属をどう見つけますか?
A.複合主キー (A, B) を持つテーブルで、非キー属性が A 単独または B 単独で決まっていないかを一列ずつチェックします。決まっていれば部分従属です。
Q.2NF まで正規化する目的は?
A.複合キーの一部にしか関係しない属性を別テーブルに切り出すことで、その属性の重複と更新時異常を排除するためです。

関連トピック

もっと学びたい方へ(おすすめ書籍)

おすすめ
達人に学ぶDB設計徹底指南書 第2版
ミック

テーブル設計と正規化、パフォーマンス考慮のインデックス設計まで実務レベルで学べる定番書。第2版ではクラウド対応も強化。

Amazon で見る →
情報処理教科書 データベーススペシャリスト 2025年版
三好康之

IPAデータベーススペシャリスト試験の総合対策書。インデックス関連は本サイトと合わせて学ぶと理解が深まる。

Amazon で見る →
理論から学ぶデータベース実践入門
奥野幹也

リレーショナルモデルの理論から、インデックス設計を含む実務で使えるSQLまで解説。

Amazon で見る →
おすすめ
楽々ERDレッスン (CodeZine BOOKS)
羽生章洋

ER 図をどう「使える設計」に落とすか、実務の判断まで踏み込んだ入門書。エンティティの切り出しから多対多の扱いまで具体例が豊富。

Amazon で見る →
おすすめ
スッキリわかるSQL入門 第4版 ドリル256問付き!
中山清喬/飯田理恵子

ドリル 256 問を実際に打ちながら進める SQL の入門書。付属のブラウザ環境で演習できるので、SELECT から結合・集約までを環境構築で止まらずに通せる。

Amazon で見る →
達人に学ぶSQL徹底指南書 第2版
ミック

SQLの本質的な使い方と、インデックスが効くクエリの書き方を学べる。ウィンドウ関数など現代SQLも網羅。

Amazon で見る →
SQLアンチパターン 第2版
Bill Karwin

実務でやりがちなSQL・DB設計のアンチパターンとその回避策を体系的に学べる。

Amazon で見る →
[改訂3版]内部構造から学ぶPostgreSQL
勝俣智成 ほか

PostgreSQLの内部構造・ストレージ・インデックス機構を丁寧に解説。設計と運用計画の鉄則が学べる。

Amazon で見る →
SQL実践入門 ── 高速でわかりやすいクエリの書き方
ミック

「なぜこの書き方が速いのか」を実行計画から説明する一冊。条件分岐・集約・結合・更新のそれぞれで、良い書き方と悪い書き方を対比しながら読める。

Amazon で見る →

本セクションはAmazonアソシエイトのリンクを含みます。

オンライン個別指導

もっと深くDBを学びたい方へ。

たいてっくが、SQL・データベース設計・パフォーマンスチューニング・IPAデータベーススペシャリスト対策まで、1対1で学習をサポートします。まずは無料相談から。

無料相談を予約する →
受講者の声 (DB・SQL コース)
menta レビュー原文を見る →
  • 「教え方も上手で、お人柄も良いメンターです。DB周りの知識はもちろん、何より、しっかり教えてあげようという姿勢がとてもありがたかったです。データベース、SQLの学習を考えている方にはおススメです。」
    — H 様(DB・SQL コース受講)
  • 「体系的に知識を教えてくださり、実際の業務でも大変役立っております。特に短い時間で効率よく知識の習得や、練習をできているのは期待以上でした。」
    — M 様(DB・SQL コース受講)
  • 「大変充実したコンテンツでわかりやすいご説明をありがとうございました。基本的な質問にも丁寧にご説明いただき、また業務のご相談にも乗って頂き大変有意義な時間でした。」
    — K 様(DB・SQL コース受講)