データモデル設計ガイド

第 2 正規形(2NF)— 部分関数従属を排除する

複合キーの一部だけで決まる列をマスタへ分離する第 2 正規形。

2NF とは

第 2 正規形(2NF)は、主キーが複合キーのときに、その一部の列だけで決まる属性を別テーブルに分離することを求めます。「部分関数従属」を排除する段階です。

単一カラム主キーのテーブルは定義上 2NF を自動的に満たすため、2NF が問題になるのは複合主キーを持つ中間表・明細表に限られます。

典型例 — 注文明細に product_name が紛れ込む

典型例 — 注文明細に product_name が紛れ込む diagram

注文明細テーブル (order_id, product_id, product_name, quantity) で、主キーは (order_id, product_id) の複合キーです。しかし product_nameproduct_id だけで決まります。これは複合キーの「一部」への従属(部分従属)であり、2NF 違反です。

影響: 同じ商品が 100 件の注文に登場すると、product_name が 100 箇所に重複します。商品名を変更したときに 100 行を一貫して更新できなければ、データが腐ります。

sql
-- NG (2NF 違反)
CREATE TABLE order_lines (
  order_id     INT,
  product_id   INT,
  product_name VARCHAR(100),  -- product_id だけで決まる
  quantity     INT,
  PRIMARY KEY (order_id, product_id)
);

-- OK (2NF)
CREATE TABLE products (
  id   INT PRIMARY KEY,
  name VARCHAR(100) NOT NULL
);
CREATE TABLE order_lines (
  order_id   INT NOT NULL REFERENCES orders(id),
  product_id INT NOT NULL REFERENCES products(id),
  quantity   INT NOT NULL,
  PRIMARY KEY (order_id, product_id)
);

2NF を満たすためのチェック観点

複合主キーを持つテーブルを見つけたら、各列について「主キーの全体で決まるか、一部で決まるか」を 1 つずつ確認します。一部で決まる列は、その「一部」を主キーとする別テーブル(マスタ)へ切り出す候補です。

逆に、すべての列が主キー全体に従属しているなら 2NF はクリアです。その状態で次は 3NF(推移従属)を確認します。