データベース設計に関心のある方なら,6NF って用語,どこかで目にしたり耳にしたりしたことありませんか?リレーションの第 6 正規形(sixth normal form)のことです.一体何なんでしょうか?
これまでリレーショナルデータベースの正規化理論では,リレーションを幾つかの射影に分解して,得られた結果を自然結合演算で再合成して元に戻ることができる(情報無損失分解)か否かで正規化の体系を創り上げてきました.関数従属性(FD)や多値従属性(MVD)は 2 分解,つまり 1 枚のリレーションを 2 つの射影に分解する考え方でリレーションの情報無損失分解を規定します.FDにより第 2 正規形,第 3 正規形,Boyce-Codd 正規形(BCNF)が規定されました.FD を概念拡張した MVD により第 4 正規形(4NF)が規定されました.FD や MVD はリレーションを 2 分解しますが,MVD をさらに概念拡張して結合従属性(JD)が導入されると,JD は一般にリレーションが n(n≧2)個の射影に情報無損失分解されるための必要かつ十分条件となり,第 5 正規形(5NF)が明らかとなりました.JD は n を 2 に限定しないので,与えられたリレーションを幾つかの射影に情報無損失分解して更新時異状を解消しようというリレーションの正規化理論の枠組みは,JD が規定する 5NF で打ち止めとなり,6NF という正規形は「ない」と理解されています.これは皆さんも納得済みのことでしょう.
ところが,第 6 正規形(6NF)という言葉が聞こえてくるわけです.一体何なんでしょうか?これは C. J. Date が言い出した正規形で,彼は 5NF が従来の枠組みでは最も高い正規度であると認識しているといいながらも,6NF を主張しているのです.まず,彼の与えた 6NF の定義を見てみましょう[1].
【定義1】(Sixth normal form for regular data by C.J. Date)
Relvar R is in sixth normal form (6NF) if and only if the only JDs that hold in R are trivial ones.¹
では,これは何を意味しているのでしょうか?そのためには,少し寄り道をする必要があります.次に,彼の与えた JD の定義を確認します.
1 “regular data” は temporal data と区別しての言い方で,”relvar”はリレーションと読み替えてよい. Trivial については脚注4 の意味に同じ.
【定義2】(結合従属性(JD)by Date)
Let X1, …, Xn be subsets of the heading H of relvar R²; then the join dependency (JD) { X1 , … , Xn } holds in R if and only if R can be nonloss decomposed into its projections on X1, … , Xn.
この定義は,表現こそ異なりますが,次に示す従来知られている結合従属性(JD)の定義と同じです³.
2 the heading H of relvar R とは,従来の言葉で表せば H がリレーション R の全属性集合という意味です.従来,結合従属性は*{}と書いてきましたが, Date は*の対象がリレーションではなく属性集合なので,それはおかしいと異議を唱え,*を使わず(星印)を使うとしています.表現の違いだけで中身は同じです.ここでは特別に留意しない限り,*を使います.
3 従来の定義や関連する事項は拙著[2]を参照して下さい.
【定義3】(JD)
R(A, B, …, C)をリレーションスキーマ,ここに H={A, B, …, C},とするとき,R の任意のインスタンス R がその n 個の射影 R[X1],R[X2],… ,R[Xn]に情報無損失分解される,つまり R=R[X1]*R[X2]* … *R[Xn]が成立するとき,R に JD *(X1, X2… , Xn)が存在するという.
そして,このとき,JD を使って 5NF は次のように定義されます.
【定義4】(5NF)
リレーション R が 5NF であるとは,*(X1, X2, … , Xn)を R の JD とするとき,次のいずれかが成立するときをいう.
(1) *(X1, X2, …, Xn)は自明な結合従属性である4.
(2) 各 Xi は R のスーパキーである.
一方,Date が与えた 5NF の定義は次の通りです.
4 JD *(X1, X2, … , Xn が trivial (自明)とは X1, X2, …, Xn のうちの一つが R の全属性集合に等しいときをいいます.
【定義5】(5NF by Date)
Relvar R is in fifth normal form (5NF) if and only if every JD of R is implied by the keys of R.
さて,定義4 と定義5 を見比べてみると,微妙な差に気づきますね.即ち,Date の 5NF の定義は従来の 5NF の定義の(2)項の条件を満たしているときと定義しているというわけです.
では,従来の 5NF の定義の(1)項に相当する場合の 5NF リレーションは,Date では一体どこでどのように定義されているのでしょうか?定義1 を見直してください.それはまさしく従来の 5NF の定義の(1)項のことです.つまり,Date の定義した 6NF は従来の 5NF の定義の(1)項の条件が成立するときの 5NF を言っているということになります.
では,なぜそれを特に 6NF ということにしたのでしょうか?Date の真意は測りかねますが,できるだけ彼の立場に立って考えてみましょう.そこで,Date の著書[1]に記載されている例を引用して,そこで定義されているリレーションの正規度を考察してみます.3 つのリレーション S,P,SP があるとします.ここに,S は suppliers,P は parts,そして SP は shipments を表すリレーションで,SNO は supplier number,PNO は part number,STATUS は status value,CITY は location,QTY は quantity などを表します.アンダーラインが引かれている属性が主キーです.また,S には関数従属性 CITY→STATUS があるとします.
S(SNO, SNAME, STATUS, CITY)
P(PNO, PNAME, COLOR, WEIGHT, CITY)
SP(SNO, PNO, QTY)
そうすると,S は第 3 正規形にもなっていなく,P は 5NF であるが 6NF ではなく,SP は 6NF となります.なぜでしょうか?
まず,S が第 3 正規形にもなっていないことは遷移的関数従属性 SNO→CITY→STATUS の存在で明らかでしょう.P には *({ PNO, PNAME }, { PNO, COLOR, WEIGHT, CITY }), *({PNO, COLOR}, {PNO, PNAME, WEIGHT, CITY }), *({PNO, PNAME, COLOR}, {PNO, EIGHT, CITY }), … , *({PNO, PNAME}, {PNO, COLOR}, {PNO, WEIGHT}, {PNO, CITY}) など多数の JD があることが分かりますが,これらすべての JD は P の自明でない情報無損失分解を誘引し定義4(5NF)の(2)項の条件を満たすので 5NF であり,かつこれらの JD は自明ではないので 6NF ではないことが分かります.一方,SP では { SNO, PNO}→QTY なので,この FD を用いて SP を情報無損失分解しても SP そのものにしかならず,これを JD で表せば *({SNO, PNO, QTY})となり,定義4(5NF)の(1)項の条件を満たす,つまり定義1 を満たすので,従って 6NF ということになります.
そこで,6NF の意味ですが,5NF である P を JD *({PNO, PNAME}, {PNO, COLOR}, {PNO, WEIGHT}, {PNO, CITY}) を使って情報無損失分解すると,P[PNO, PNAME], P[PNO, COLOR], P[PNO, WEIGHT], P[PNO, CITY] とそれぞれが 6NF のリレーションに情報無損失分解できることになります.言い換えると,P の場合,P 自体では parts の PNAME, COLOR, WEIGHT, CITY という 4 つの属性を合わせて一つの意味を持つリレーションとして設計されたのですが,それを 5NF ではあるが 6NF ではないという理由で 4 つに情報無損失分解すると,例えば P[PNO, PNAME] という成分は parts の NAME のみを属性として持つリレーションということになります.
つまり,Date の主張したいことは,データベースを設計するにあたり,リレーション P を例にとれば,P のままでは「この part の名前は P1で,色は L1で,重さは W1で,その part の保管場所は C1 である」という 4 つの事象を一括して格納するリレーションを定義したことになりますが,それは望ましくなく,5NF ではあっても 6NF でなければ,「この part の名前は P1 である」,「この part の色は L1 である」,「この part の重さは W1 である」,「この part の保管場所は C1 である」という具合に,4 つの事象を個別に格納する 4 つのリレーションを定義するべきだと Date は主張したかったということになります.
みなさん,いかがでしょう?ここまで細分化したリレーショナルデータベース設計をやりますか?やるとしたら,どのような時?もしあったら是非教えてください.
結びですが,6NF ってなんだか tricky だな,と筆者は感じています.なぜならば,Date は従来の 5NF の定義を「定義4(5NF)」ではなく「定義5(5NF by Date)」で与えることによって,その間隙を埋めるべく 6NF を持ち出しているからです.確かに,5NF を定義5 のように定義する文献も見受けられますが,FD が自明であることや MVD が自明であることは,リレーションがそれぞれ BCNF や 4NF であるための条件となっています.したがって,5NF の定義は定義4(5NF)でよいのではないかと思うわけです.そうすれば,6NF を言い出す隙はありません.そのようなわけで,6NF に直面したら(ギョッとするのではなく)あくまで 5NF の一つという認識で臨むのが正解かなと考える次第です.
【文献】
[1] C.J. Date. Database Design and Relational Theory. O’Reilly Media, Inc., 2012.
[2] 増永良文.リレーショナルデータベース入門[第3版],サイエンス社,2017.