正規化の説明に主キーを持ち出すのは大きな誤り

 正規化はデータベース作成の際の重要なプロセスですが、その正規化の説明において主キーが持ち出されることがあります。
 具体的な例としては「第2正規形とは、主キーの一部により他の項目が特定されるような関係(部分関数従属)が存在しない状態」というような説明がよく見られます。
 書籍等でもこのような解説がしばしばみられますが、これは誤りです。主キーではなく候補キーを用いて説明しなければなりません。なお、候補キーについては下記または本編(こちら)を参照ください。

f:id:accs2014:20170504210401p:plain:right:w400

 例を挙げましょう。
 右のような「販売テーブル」というテーブルがあります。「販売ID」の1つの値は、1件の販売を表しています。例えば「販売ID」が1である行が3つありますが、この1件の販売において、3種類の商品(「商品コード」がA001,A002,A005)が販売されたことが読み取れます。
 このテーブルは「販売ID」と「商品コード」の2つの列の組み合わせにより1つの行を特定できるつくりになっていますので、これらの2つの列を主キー(複合キー)として用いることができます。


f:id:accs2014:20170504210400p:plain:right:w400

 さて、ここで右図のように「番号」という列を新たに追加し、これを主キーとして設定することもできます。そこでさらに「主キーは1つの列なのだから『主キーの一部により他の項目が特定されるような関係(部分関数従属)』など存在しえません。よってこのテーブルは第2正規形の条件を満たしています」と主張したらどうでしょうか。最初に挙げたような定義に沿って判断すると、これは正しいということになってしまいますが…
 しかし、このような設定をしたところで、このテーブルが抱えている問題点、つまり「商品が販売されたときに、商品コードだけでなく商品名も繰り返し入力しなければならず無駄であり、その組み合わせに矛盾を生じる恐れがある」という点は、まったく解消されていません。やはりこのような主張は誤りなのです。


 一方で、「候補キー(その値さえわかれば1つの行を特定できるような列、または列の組み合わせ。主キーとするかどうかによらず、列自体がそういう性質を持っているという点が重要です)」を理解できていれば正しい定義に沿った主張が可能となります。具体的に言えば「番号」列があるかないか、どの列を主キーをにするかという問題以前に「このテーブルは『販売ID』と『商品コード』の組み合わせによって1つの行を特定するようなつくりになっている。つまり『販売ID』と『商品コード』の組み合わせが候補キーになっている。そのうちの一部である「商品コード」により商品名が特定されることから、このテーブルは第2正規形の条件を満たしてない」という結論に至るはずです。

 正規化の説明の際に主キーを持ち出すのは「候補キーが定義されていない段階での便宜的な説明」ですので、わかっている人はあまり気にしないのですが、それを真に受けると「どれかの列を主キーとして設定しておかないと正規化を進められない」という誤解につながりますし、そのような手順は不自然です。データベースに対するモヤモヤを抱える大きな要因の一つですので注意してください。