データモデル設計ガイド

第 4 正規形(4NF)— 多値従属を排除する

独立した多値属性を同居させず、組み合わせ爆発をなくす第 4 正規形。

4NF とは

第 4 正規形(4NF)は、独立した多値従属(multi-valued dependency; MVD)が同じテーブルに同居することを禁じます。1 つのキーに対して、互いに無関係な多値属性が 2 つ以上ぶら下がっている状態を分離します。

MVD が独立かどうかは、「2 つの多値属性の組み合わせが完全直積になっているか」で判定できます。独立なら 4NF 違反、組み合わせに制約があるなら違反ではありません。

典型例 — スキルと言語が 1 テーブルに混在

典型例 — スキルと言語が 1 テーブルに混在 diagram

employee_skills_languages (employee_id, skill, language) というテーブルを考えます。ある社員が複数のスキルを持ち、複数の言語も話す。スキルと言語は互いに独立(SQL が話せるかどうかと、日本語が話せるかどうかは無関係)です。

このとき、1 人の社員が 3 つのスキル × 2 つの言語を持っていれば 6 行を保持することになります。スキルが 1 つ増えれば行数は言語数の倍数で増え、組み合わせ爆発します。しかも「スキルだけ追加したい」のに言語との全組み合わせを作らないと整合が壊れます。

sql
-- NG (4NF 違反): 組み合わせ全行を保持
employee_skills_languages (employee_id, skill, language)
-- (1, 'SQL', 'ja'), (1, 'SQL', 'en'),
-- (1, 'Go',  'ja'), (1, 'Go',  'en') ...

-- OK (4NF): 独立した 2 テーブルに分割
CREATE TABLE employee_skills (
  employee_id INT NOT NULL,
  skill       VARCHAR(50) NOT NULL,
  PRIMARY KEY (employee_id, skill)
);
CREATE TABLE employee_languages (
  employee_id INT NOT NULL,
  language    VARCHAR(20) NOT NULL,
  PRIMARY KEY (employee_id, language)
);

4NF 違反を見分ける質問

あるテーブルが 4NF 違反か判定する簡単な質問:

  1. そのテーブルに、同じキーに対する多値属性が 2 つ以上あるか?
  2. その 2 つは互いに意味的な関係がないか?(片方を知っても、もう片方は絞り込めない)

両方 Yes なら 4NF 違反。意味的な関係があるなら、その関係を表す別の属性(例: 「いつそのスキルを使う案件でその言語を使ったか」)が隠れている可能性があります。