< All Topics

リレーショナルデータモデルの正規化

データモデル設計の改善

ある業務に関するデータモデルを設計するとき、データとして管理したい項目を頭に入れた上で最初は大まかな設計をすることになる。また、細かいところまで気を配って設計したつもりでも、あとから見落しが見つかることもある。そしてデータモデルの設計では(概念データモデルであろうが論理データモデルであろうが)いくつか問題を抱えたものが出来上がることがある。というか普通はそうである。

ここでは以下、まずリレーショナルデータモデルのリレーションが抱えてしまう問題について説明し、その後、それらの問題を解決するための指針となるリレーショナルデータモデルの正規化について説明する。

第1正規形

リレーションは表形式であらわされ、1行目に見出しがあり、見出しを構成している各項目は属性と呼ばれた。そしてそれぞれのデータはこの表で1行であらわされ、タプルと呼ばれた。つまり、タプルはそれぞれのデータで各属性の値を組にしたものである。

リレーショナルデータモデルでは、属性の値が複数の値の組となっていることは許されていない。つまり、ある属性の値がスカラーではなくさらに分解できるようになっているデータは扱うことができない。このようなことが起きているリレーションは非正規リレーションと呼ばれる。

非正規リレーションは、次のどちらかの方法で、すべての属性の値がもうそれ以上分解不可能な(つまりスカラー)値となるように改善する。

  • 組になっている属性の値がバラバラになるようにデータの数(行の数)を増やす。
  • 別に新たなリレーションを付け加え、分解可能な(つまりスカラーではない)属性を分離する。
受注番号受注年月日項番商品名数量単価
00012023-10-071ボールペンA2120
2ノートA3150
3ノートB1130
00022023-10-091ボールペンB2100
2ノートA1150
00032023-10-091ボールペンA4120
非正規リレーション「受注」

ここで、受注番号は受注ごとに新たに発行される番号であり、項番は1回の受注で複数の商品の注文があった場合に、商品別に連番で発行される番号とする。

この、非正規リレーションでは、受注をあらわす一つひとつのデータに対して、属性「商品名」、「数量」、「単価」の値が複数の値の組となっている。

このような場合、次のように、組になっている属性の値がバラバラになるようにデータの数(行の数)を増やす。

受注番号受注年月日項番商品名数量単価
00012023-10-071ボールペンA2120
00012023-10-072ノートA3150
00012023-10-073ノートB1130
00022023-10-091ボールペンB2100
00022023-10-092ノートA1150
00032023-10-091ボールペンA4120
リレーション「受注」

もしくは、以下のように、リレーション「受注明細」を作り、商品名、数量、単価の情報をリレーション「受注」から分離する。このとき、新しくできるリレーション「受注明細」にも「受注番号」という属性を作り、リレーション「受注」の属性「受注番号」を参照できるようにしておく。(2つに分割された後、リレーション「受注」では属性「受注番号」の値によってタプルが一意に決まるようになっているので、この参照によって、2つのリレーションに不具合なく関連がつくことになる。)

受注番号受注年月日
00012023-10-07
00022023-10-09
00032023-10-09
リレーション「受注」
受注番号項番商品名数量単価
00011ボールペンA2120
00012ノートA3150
00013ノートB1130
00021ボールペンB2100
00022ノートA1150
00031ボールペンA4120
リレーション「受注明細」

どの属性の値もこれ以上分解できない値(つまりスカラー)となっているリレーションは第1正規形と呼ばれる。

更新時異状

リレーションに対してデータの更新をする際、いくつかの問題が起きることがある。これは更新時異状と呼ばれる。

更新時異状は、

  • 修正時異状
  • 挿入時異状
  • 削除時異状

のような種類に分けて考えることができる。

修正時異状とは

あるリレーションで、ある属性の値が等しいタプルが複数あるとする。これらのタプルのうち、ある1つのタプルで、ある属性の値を修正するとき、残りのタプルのその属性も修正しないと辻褄が合わなくなってしまう。

受注番号受注年月日項番商品名数量単価
00012023-10-071ボールペンA2120
00012023-10-072ノートA3150
00012023-10-073ノートB1130
00022023-10-091ボールペンB2100
00022023-10-092ノートA1150
00032023-10-091ボールペンA4120
受注

このリレーションでは、属性「商品名」の値として「ノートA」が現れているタプルが2つある。そのため、ノートAの単価が変更されたとき、単価の値を2ヶ所更新する必要があるが、何かしらのミスをおかすことによりどちらかの更新がなされないと辻褄が合わなくなる。

このように、あるタプルのある属性の値を修正するとき、その属性の値を持つ全てのタプルに対してこの属性の値を修正しなけらばならないため、データ更新時のミスが発生するリスクを抱えていると言える。

挿入時異状とは

あるリレーションで、ある属性の値としてこれまでなかった値を新たに今後想定する必要が出てきたとする。しかし、この、これまでになかった値を属性の値として持つなにかしらのタプルが現れるまでは、リレーションにこの新たな値が反映されることはない。つまり、今後想定する必要のある新たな値をリレーションに挿入することはできない。

受注番号受注年月日項番商品名数量単価
00012023-10-071ボールペンA2120
00012023-10-072ノートA3150
00012023-10-073ノートB1130
00022023-10-091ボールペンB2100
00022023-10-092ノートA1150
00032023-10-091ボールペンA4120
受注

新商品として商品名「ボールペンC」、単価「150」を販売することになったとしても、受注がない限りこのリレーション「受注」にボールペンC の情報は挿入できない。

削除時異状とは

あるリレーションであるタプルを削除したとき、ある属性ですでに想定されていたある値がリレーションから完全になくなってしまい、その値に関係する情報が失われてしまうということが起きることがある。

受注番号受注年月日項番商品名数量単価
00012023-10-071ボールペンA2120
00012023-10-072ノートA3150
00012023-10-073ノートB1130
00022023-10-091ボールペンB2100
00022023-10-092ノートA1150
00032023-10-091ボールペンA4120
受注

注文のキャンセルがあったなどの理由で、このリレーションからタプル(0001, 2023-10-07, ノートB, 1, 130 )を削除すると、「ノートBの単価が130である」という情報は失われる。

関数従属性と正規化

とりあえず作ってみたリレーショナルデータモデルはこれまで説明したような問題を抱えていることが多々あるため、さらに手を加えよりよいリレーショナルデータモデルへ改善するということがよく行われる。そのときに鍵となる概念が関数従属性と呼ばれるもので、関数従属性の立場からよりよいリレーショナルデータモデルへ改善する際に取られる方法が正規化と呼ばれるものである。

関数従属性とは

あるリレーション $R$ とその属性 $A$、$B$ に注目したとする。属性 $B$ の値は属性 $A$ の値によって一意に決まってしまうようなものである場合、 $B$ は $A$ に関数従属するといい、
$$A \to B $$
とあらわす。

関数従属という概念は、属性を複数組み合わせた場合へと拡張することができる。つまり、あるリレーション $R$ とその属性の組 $A_1,A_2,\ldots,A_m$ 及び $B_1,B_2,\ldots,B_n$ に注目したとき、$B_1,B_2,\ldots,B_n$ の値は $A_1,A_2,\ldots,A_m$ の値によって一意に決まってしまうようなものである場合、$B_1,B_2,\ldots,B_n$ は $A_1,A_2,\ldots,A_m$ に関数従属するといい、
$$A_1,A_2,\ldots,A_m \to B_1,B_2,\ldots,B_n$$
とあらわす。

受注番号受注年月日顧客番号項番商品名数量単価
00012023-10-0733251ボールペンA2120
00012023-10-0733252ノートA3150
00012023-10-0733253ノートB1130
00022023-10-0941101ボールペンB2100
00022023-10-0941102ノートA1150
00032023-10-0905561ボールペンA4120
受注

このリレーション「受注」では、例えば、次のような関数従属性がある。

  • 商品名 → 単価
    商品によって単価は決まっている。
  • 受注番号 → 受注年月日
    受注ごとに受注番号がつけられ、受注年月日はその受注を受けた日であるから自動的に決まる。
  • 受注番号 → 顧客番号
    受注ごとに受注番号がつけられ、顧客はその受注を行った人であるから自動的に決まる。
  • 受注番号, 項番 → 受注年月日, 顧客番号, 商品名, 数量, 単価
    受注番号と商品名の組み合わせでその受注の内容はすべて決まっている。
  • 受注番号, 項番 → 顧客番号
    直前で説明されている関数依存性が成り立つので、→ の右側から一部だけを取り出しても成り立つ。

完全関数従属性

あるリレーション $R$ とその属性の組 $A_1,A_2,\ldots,A_m$ 及び $B_1,B_2,\ldots,B_n$ に注目したとき、$B_1,B_2,\ldots,B_n$ は $A_1,A_2,\ldots,A_m$ に関数従属していたとする。つまり、

$$A_1,A_2,\ldots,A_m \to B_1,B_2,\ldots,B_n$$

となっていたとする。そして、$A_1,A_2,\ldots,A_m$ のうちのどれか1つでも取り除いてしまうと、関数従属性が成り立たなくなってしまうとする。このようなとき、$B_1,B_2,\ldots,B_n$ は $A_1,A_2,\ldots,A_m$ に完全関数従属するという。

また、関数従属性

$$A_1,A_2,\ldots,A_m \to B_1,B_2,\ldots,B_n$$

は成り立っているが、完全関数従属ではないとする。すると、$B_1,B_2,\ldots,B_n$ は $A_1,A_2,\ldots,A_m $ の(全部ではなく)ある一部分を抜き出してできる組 $A_{i_1},A_{i_2},\ldots,A_{i_s}$ (ただしここで $s\lt m$)に関数従属している。このようなとき、$B_1,B_2,\ldots,B_n$ は $A_1,A_2,\ldots,A_m $ に部分関数従属しているという。

受注番号受注年月日顧客番号項番商品名数量単価
00012023-10-0733251ボールペンA2120
00012023-10-0733252ノートA3150
00012023-10-0733253ノートB1130
00022023-10-0941101ボールペンB2100
00022023-10-0941102ノートA1150
00032023-10-0905561ボールペンA4120
受注

このリレーションでは、関数従属性として

受注番号, 項番 → 数量

が成り立っているが、ここから、例えば「受注番号」を取り除いてしまうと関数従属性は成り立たなくなる。つまり、「数量」は「受注番号, 項番」に完全関数従属している。

これに対し、

受注番号, 項番 → 顧客番号

という関数従属性では、「項番」を取り除いても関数従属性は成り立ったままである。つまり、「顧客番号」は「受注番号, 項番」に部分従属している。

関数従属性の推移律

あるリレーション $R$ とその属性の組 $A_1,A_2,\ldots,A_m$ 及び $B_1,B_2,\ldots,B_n$ 及び $C_1,C_2,\ldots,C_l$に注目したとき、$B_1,B_2,\ldots,B_n$ は $A_1,A_2,\ldots,A_m$ に関数従属し、$C_1,C_2,\ldots,C_l$ は $B_1,B_2,\ldots,B_n$ に関数従属していたとする。
つまり、

$$A_1,A_2,\ldots,A_m \to B_1,B_2,\ldots,B_n$$
かつ
$$B_1,B_2,\ldots,B_n \to C_1,C_2,\ldots,C_l$$

となっていたとする。このとき、$C_1,C_2,\ldots,C_l$ は $A_1,A_2,\ldots,A_m$ に関数従属する。つまり、

$$A_1,A_2,\ldots,A_m \to C_1,C_2,\ldots,C_l$$

が成り立つ。この事実は、関数従属性の推移律と呼ばれる。また、このようなとき、属性の組 $C_1,C_2,\ldots,C_l$ は属性の組 $A_1,A_2,\ldots,A_m$ に推移的に関数従属しているという。

受注番号受注年月日顧客番号項番商品名数量単価
00012023-10-0733251ボールペンA2120
00012023-10-0733252ノートA3150
00012023-10-0733253ノートB1130
00022023-10-0941101ボールペンB2100
00022023-10-0941102ノートA1150
00032023-10-0905561ボールペンA4120
受注

このリレーションでは、関数従属性として

受注番号, 項番 → 商品名

商品名 → 単価

が成り立っている。

よって、属性「単価」は属性の組「受注番号, 項番」に推移的に関数従属している。

自明な関数従属性

あるリレーション $R$ とその属性の組 $A_1,A_2,\ldots,A_m$ に対して、$A_1,A_2,\ldots,A_m$ はもちろん自分自身 $A_1,A_2,\ldots,A_m$ に関数従属している。つまり、

$$A_1,A_2,\ldots,A_m \to A_1,A_2,\ldots,A_m$$

は明らかに成り立つ。これは自明な関数従属性と呼ばれる。また、 $A_1,A_2,\ldots,A_m$ に任意の属性の組 $B_1,B_2,\ldots,B_m$ を加えてできる属性 $A_1,A_2,\ldots,A_m,B_1,B_2,\ldots,B_m$ から属性 $A_1,A_2,\ldots,A_m$ への関数従属性

$$A_1,A_2,\ldots,A_m,B_1,B_2,\ldots,B_m \to A_1,A_2,\ldots,A_m$$

も明らかに成り立つ。この事実も、自明な関数従属性と呼ばれる。

つまり、自明な関数従属性とは、ある属性の組を考えたとき、その属性の組全部または一部分からなる組は必ずその属性の組に関数従属しているという事実である。

正規化

リレーショナルデータモデルでは、非正規リレーションを扱うことはしないので、以下、すでに第1正規形となっているリレーションのみを考える。

第2正規化

あるリレーション $R$ は第1正規形であるとする。また、自明な関数従属性以外に、$R$ の候補キーに部分関数従属している属性または属性の組を持っているとする。このようなとき、リレーション $R$ は更新時異状を引き起こす可能性を抱えている。

受注番号受注年月日顧客番号項番商品名数量単価
00012023-10-0733251ボールペンA2120
00012023-10-0733252ノートA3150
00012023-10-0733253ノートB1130
00022023-10-0941101ボールペンB2100
00022023-10-0941102ノートA1150
00032023-10-0905561ボールペンA4120
受注

このリレーションでは、候補キーとして「受注番号、項番」という組を用いることができる。また、

受注番号, 項番 → 顧客番号

という関数従属性があるが、この関数従属性では「項番」を取り除いても関数従属性が成り立ったままとなる。つまり、「顧客番号」は候補キー「受注番号, 項番」に部分従属している。

その結果、受注番号の値が等しく、顧客番号の値も等しいようなタプルが複数存在できることになる。そして、例えば、何らかの理由で顧客番号 3225 の顧客の番号を修正する必要が出てきた場合、複数(この例では3つ)のタプルを修正しなければならず、修正時異状を引き起こす恐れがある。

また、同様に、「受注年月日」も候補キー「受注番号, 項番」に部分従属していため、やはり修正時異状を引き起こす恐れがある。

(このリレーションでは、たまたま、部分関数従属性を持つことによる挿入時異状や削除時異状の恐れはないが、後に例で説明するように、推移的関数従属性を持つことによる挿入時異状や削除時異状の恐れがある。)

このような、部分関数従属性が引き起こす問題を解決するために、次のように、部分従属している属性を取り出し、複数のリレーションに分割する。

受注番号受注年月日顧客番号
00012023-10-073325
00022023-10-094110
00032023-10-090556
受注
受注番号項番商品名数量単価
00011ボールペンA2120
00012ノートA3150
00013ノートB1130
00021ボールペンB2100
00022ノートA1150
00031ボールペンA4120
受注明細

この例のようにして得られた複数のリレーションはどれも、次の条件を満たすものとなる。

  1. 第1正規形である。
  2. どのような候補キーを選んだときにも候補キーに含まれることがない属性は、どのような候補キーを選んだとしても候補キーに完全関数従属している。

上記の条件を満たすリレーションは第2正規形と呼ばれ、第1正規形から第2正規形への改善を第2正規化という。

補足:どのような候補キーを選んだときにも候補キーに含まれることがない属性を非キー属性という。

第3正規化

あるリレーション $R$ は第2正規形であるとする。また、ある非キー属性または非キー属性の組が、$R$ のある候補キーに(候補キー以外の属性を介して)推移的に関数従属しているとする。このようなとき、リレーション $R$ は更新時異状を引き起こす可能性を抱えている。

受注番号項番商品名数量単価
00011ボールペンA2120
00012ノートA3150
00013ノートB1130
00021ボールペンB2100
00022ノートA1150
00031ボールペンA4120
受注明細

このリレーションでは、候補キーとして「受注番号、項番」という組を用いることができる。また、関数従属性として

受注番号, 項番 → 商品名

商品名 → 単価

が成り立っている。よって、属性「単価」は候補キー「受注番号, 項番」に(候補キー以外の属性を介して)推移的に関数従属している。

候補キー「受注番号、項番」の値が違っていても「商品名」の値は等しくなることは十分考えられ、そして、候補キーではない「商品名」から「単価」が決まるようになっているので、「商品名」の値が等しく、「単価」の値が等しいようなタプルが複数存在できることになる。そのため修正時異状を引き起こす恐れがある。

また、「単価」は「商品名」に関数従属しているが直接候補キー「受注番号、項番」に関数従属していない。ので、新商品を取り扱うことになったとしても「商品名」と「単価」の情報は受注がなければ登録できない。つまり挿入時異状を引き起こす。

さらに、ある候補キー「受注番号、項番」の値を持つタプルのみに存在している「商品」がある場合、そのタプルを削除するとその「商品」の情報が失われる。つまり、削除時異状が起きる。例えば、ボールペンB は受注番号が 0002 で項番が 1 のタプルのみに存在しているのでこのタプルを削除するとボールペンB の情報が失われる。

このような、推移的関数従属性が引き起こす問題を解決するために、次のようにして、推移的に従属している属性をとりだし、リレーションを複数のリレーションに分割する。

受注番号項番商品名数量
00011ボールペンA2
00012ノートA3
00013ノートB1
00021ボールペンB2
00022ノートA1
00031ボールペンA4
受注明細
商品名単価
ボールペンA120
ボールペンB130
ノートA150
ノートB130
商品

以上のようにして得られる複数のリレーションはどれも、次の条件を満たすものとなる。

  1. 第2正規形である。
  2. どのような候補キーを選んだときにも候補キーに含まれることがない属性は、どのような候補キーを選んだとしてもその候補キーに(候補キー以外の属性を介して)推移的に関数従属していない。

上記の条件を満たすリレーションは第3正規形と呼ばれ、第2正規形から第3正規形への改善を第3正規化という。

ボイスコッド正規化

あるリレーション $R$ は第3正規形であるとする。また、複数の属性からなる候補キーが複数存在するとする。そして、ある候補キーに含まれるある属性が別の候補キーに含まれるある属性に従属しているとする。このようなとき、リレーション $R$ は更新時異状(修正時異状、挿入時異状、削除時異状)を引き起こす可能性を抱えている。

ある学校で学生が部活に所属している状況を考える。そして、次のような決まりがあるとする。

  • 学生は複数の部活に入ることができる。
  • 部活には必ず1人だけ顧問がいる。
  • 顧問を兼任することはできない。
  • 同姓同名の顧問はいない。

このとき、リレーションとして次のようなものができたとする。

学生番号部活名顧問名入部年
1001野球小林 聡2021
1002サッカー野田 隆2023
1003吹奏楽高橋 香織2020
1003美術牧田 祐介2021
1004サッカー野田 隆2020
1005野球小林 聡2022
1006野球小林 聡2021
1007野球小林 聡2022
1007演劇島田 翔平2023

このリレーションでは、「学生番号, 部活名」という候補キーと「学生番号, 顧問名 」という候補キーが存在している。

よって、非キー属性は「入部年」だけである。

「入部年」はどちらの候補キーにも完全関数従属しているので、これは第2正規形である。

「入部年」はどちらの候補キーにも推移的に従属していないので、これは第3正規形である。

ところが、このリレーションでは、候補キー「学生番号, 顧問名」に含まれる属性「顧問名」は別の候補キー「学生番号, 部活名」に含まれる属性「部活名」に従属している。つまり、非キー属性ではない属性「顧問名」が候補キー「学生番号, 部活名」に部分従属している。このようなときはやはり更新時異状を引き起こす可能性を抱えることになる。

このような、ある候補キーのある属性から別の候補キーのある属性への関数従属性が引き起こす問題を解決するために、次のようにしてリレーションを複数のリレーションに分割する。

学生番号部活名入部年
1001野球2021
1002サッカー2023
1003吹奏楽2020
1003美術2021
1004サッカー2020
1005野球2022
1006野球2021
1007野球2022
1007演劇2023
部活名顧問名
野球小林 聡
サッカー野田 隆
吹奏楽高橋 香織
美術牧田 祐介
演劇島田 翔平

以上のようにして得られる複数のリレーションはどれも、次の条件を満たすものとなる。

$A$ と $B$ をそれぞれリレーション $R$ の属性または属性の組とし、$A\to B$ を関数従属性とする。
$A\to B$ は自明な関数従属性であるか、そうでなければ $A$ は候補キーである。

上記の条件を満たすリレーションはボイスコッド正規形と呼ばれ、ボイスコッド正規化への改善をボイスコッド正規化という。


Warning: Undefined array key 1 in /home/gajyuko/lifenlogic.com/public_html/wp-content/plugins/echo-knowledge-base/includes/features/articles/class-epkb-articles-setup.php on line 697
Table of Contents
上部へスクロール