ある属性の値が決まると別の属性の値が一意に定まる関係。
関数従属とは、ある属性Aの値が決まると、別の属性Bの値がただ1つに定まる関係のことです。記号で「A → B」と書きます。Aを決定項、Bを従属属性と呼びます。
身近な例で考えると、郵便番号と地域の関係に似ています。郵便番号が決まれば、対応する地域は1つに定まりますよね。逆に地域から郵便番号は1つに決まらない(複数ありうる)こともあります。このように「片方が決まればもう片方が決まる」一方通行の関係が関数従属です。
上のツールで▶ボタンを押すと、商品マスタの表から決定項(商品コード)を選び、同じコードに同じ商品名が対応することを確かめ、「商品コード → 商品名」という関数従属を確認できます。
関数従属は矢印を使って簡潔に書き表します。
A → B
それぞれの意味は次のとおりです。
・矢印の左(A)=決定項:値を決める「もとになる」属性
・矢印の右(B)=従属属性:Aの値しだいで一意に定まる属性
・矢印の向き:「Aが決まればBが決まる」という一方向を表す
注意したいのは、矢印は逆向きにできるとは限らない点です。「商品コード → 商品名」は成り立っても、「商品名 → 商品コード」は、同名の別商品があれば成り立ちません。また、複数の属性をまとめて決定項にすることもでき、その場合は「{注文番号, 商品コード} → 数量」のように書きます。上のツールの記法の読み方で、矢印の左右の役割を確認できます。
関数従属は、正規化(=表をきれいに分けてデータの重複や矛盾をなくす作業)の道しるべになります。「どの属性がどの属性に従属しているか」を調べることで、表をどう分割すべきかが見えてきます。
正規化の各段階は、関数従属の種類を1つずつ取り除いていく作業です。
・第2正規形:主キーの一部だけで決まる「部分関数従属」を別表に分けて取り除く
・第3正規形:主キー以外の属性を経由して決まる「推移的関数従属」を別表に分けて取り除く
たとえば、1つの表に「商品コード → 商品名・単価」と「社員コード → 社員名」という別々の従属が混ざっていると、データが重複し、更新ミスが起きやすくなります。関数従属を手がかりに表を分ければ、1つの事実は1か所だけに記録され、矛盾のないデータベースになります。このように、関数従属は正規化の判断の土台です。上のツールのSTEP6で、関数従属が正規化の判断に使われる様子を確認できます。
部分関数従属とは、複合主キー(2列以上の組み合わせが主キー)のとき、その一部の列だけで別の列が決まってしまう関係のことです。
上の例では、(学生ID, 科目ID)が複合主キーです。
・成績は「学生ID+科目ID」の組み合わせがそろわないと決まりません → 完全従属(問題なし)
・科目名は「科目ID」だけで決まります(学生IDは不要)→ 部分従属(問題あり)
部分従属が残ったままだと、科目名が複数の行に繰り返し記録されてしまい、科目名を更新するときに全行を直さないと矛盾が生まれます。解決策は、科目名を「科目マスタ」という別の表に切り出すことです。これが第2正規形(2NF)への変換です。
推移的関数従属とは、主キー → 中間の列 → 別の列、という2段階のリレーで決まる関係のことです。「間に別の列を経由して決まる」ので「推移的」と呼ばれます。
上の例では、社員表で次の2本の従属があります。
・社員番号 → 部署コード:社員が決まれば所属部署が決まる(主キーからの直接従属)
・部署コード → 部署名:部署コードが決まれば部署名が決まる(主キー以外からの従属)
結果として「社員番号 → 部署コード → 部署名」という2段階になり、部署名が主キーに直接従属していません。これが推移的関数従属です。
この状態だと、部署名が各社員の行にも繰り返し記録されるので、部署名を変更するときに全社員の行を直さなければなりません。解決策は「部署マスタ」として別の表に切り出すことです。部署コードと部署名の対応を1か所だけに記録すれば、変更も1行直すだけで済みます。これが第3正規形(3NF)への変換です。