<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>3NF &#8211; SRA OSS Tech Blog</title>
	<atom:link href="https://www.sraoss.co.jp/tech-blog/tag/3nf/feed/index.xml" rel="self" type="application/rss+xml" />
	<link>https://www.sraoss.co.jp/tech-blog/</link>
	<description>OSS専門の技術ブログ。PostgreSQL、Zabbixを中心に10種類以上のOSSの解説、アップデート情報、運用ヒントを提供。</description>
	<lastBuildDate>Wed, 04 Nov 2026 06:40:30 +0000</lastBuildDate>
	<language>ja</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=7.1.3</generator>

<image>
	<url>https://www.sraoss.co.jp/tech-blog/wp-content/uploads/2018/07/blog-icon-150x150.png</url>
	<title>3NF &#8211; SRA OSS Tech Blog</title>
	<link>https://www.sraoss.co.jp/tech-blog/</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>増永教授のDB特論⑥「RDB 設計のための分解的 vs. 合成的アプローチ」</title>
		<link>https://www.sraoss.co.jp/tech-blog/db-special-lecture/masunaga-db-special-lecture-6/</link>
		
		<dc:creator><![CDATA[増永良文 (Yoshifumi Masunaga)]]></dc:creator>
		<pubDate>Wed, 08 Jun 2022 04:00:52 +0000</pubDate>
				<category><![CDATA[増永教授のDB特論]]></category>
		<category><![CDATA[3NF]]></category>
		<category><![CDATA[RDB]]></category>
		<category><![CDATA[リレーショナルデータベース]]></category>
		<guid isPermaLink="false">https://www.sraoss.co.jp/tech-blog/?p=10072</guid>

					<description><![CDATA[&#160; 1. はじめに &#8195;リレーショナルデータベース（RDB）設計には分解的アプローチと合成的アプローチの 2 つがあることは皆さんよくご存じのことと思います． &#8195;分解的アプローチ（decomp ...]]></description>
										<content:encoded><![CDATA[<p>&nbsp;<br />
<span id="more-10072"></span></p>
<h4>1. はじめに</h4>
<p style="margin-top: -10px;">
&emsp;リレーショナルデータベース（RDB）設計には分解的アプローチと合成的アプローチの 2 つがあることは皆さんよくご存じのことと思います．<br />
&emsp;<b>分解的アプローチ</b>（decomposition approach）はリレーショナルデータモデルを考案したコッド（E.F. Codd）により導入された「リレーションの正規化理論」[1, 2]に依って立つ RDBの設計法で，これまで多くの説明がなされているのでその認知度は大変高いと思います．このアプローチでは更新時異状（update anomaly）を解消するために，リレーションを関数従属性（FD）や多値従属性（MVD），<br />
あるいは結合従属性（JD）を使って情報無損失分解して，第 1 正規形（1NF）から第 2 正規形（2NF），第 3 正規形（3NF），ボイス‐コッド正規形（BCNF），第 4 正規形（4NF），第 5 正規形（5NF）へと正規度を高めていきます．しかしながら，情報無損失分解と関数従属性保存は独立した概念なので，正規化により関数従属性が保存されない場合が生じることに十分注意する必要があります[3]．<br />
&emsp;一方，<b>合成的アプローチ</b>（synthetic approach）はバーンシュタイン（P.A. Bernstein）によって提案された RDB の設計法 [4] で，RDB を設計するにあたり，データベース化の対象となった世界をリレーションスキーマ <b><span style="font-style: italic;">R</span></b>(A<sub>1</sub>, A<sub>2</sub>, <sub>…</sub>, A<sub>n</sub>)と所与の FD 集合 <span style="font-style: italic;">F</span> を指定して，それを基に「関数従属性保存・3NF・情報無損失分解」と三拍子揃った RDB を設計する手法です．このアプローチでは，<span style="font-style: italic;">F</span> を構成している FD は必ず設計された RDB を構成するいずれかのリレーションスキーマの FD として定義されるので，関数従属性保存となります．</p>
<p>&emsp;以下で見るように，データベース化の対象となった世界は同一でも，分解的アプローチにより設計された RDB と合成的アプローチにより設計された RDB は一般的には異なった構成となります．では，どう違うのでしょうか？また，その差異はどのように説明されるのでしょうか？本稿では，この 2 つに焦点を当てて<ruby>蘊蓄<rt style="background-color: #DDDDDD;">うんちく</rt></ruby>を傾けてみたいと思います．</p>
<h4>2. 基礎的事項</h4>
<p style="margin-top: -10px;">
&emsp;RDB 設計の分解的アプローチとそれに係る基礎的事項は本稿の読者には改めて説明する必要はないと考えられるので省略します．ここでは，合成的アプローチの理解に必要な事項のみを掻い摘んで説明します．</p>
<p>&emsp;まず，リレーションスキーマの定義とそれに関連する定義を示します．<br />
<strong>【定義 1】</strong>（リレーションスキーマ）<br />
&emsp;リレーションスキーマ <b><span style="font-style: italic;">R</span></b> とはリレーション名 R と属性集合 Ω<sub><b><span style="font-style: italic;">R</span></b></sub>={A<sub>1</sub>, A<sub>2</sub>,<sub> …</sub, A<sub>n</sub>} からなり，<b><span style="font-style: italic;">R</span></b>(A<sub>1</sub>, A<sub>2</sub>,<sub> …</sub>, A<sub>n</sub>)と表される．リレーションスキーマ <b><span style="font-style: italic;">R</span></b> に所与の FD 集合 <span style="font-style: italic;">F</span>={f<sub>1</sub>, f<sub>2</sub>,<sub> …</sub>, f<sub>p</sub>}を指定することができる．リレーションスキーマ <b><span style="font-style: italic;">R</span></b>(A<sub>1</sub>, A<sub>2</sub>,<sub> …</sub>, A<sub>n</sub>)に所与の FD 集合 <span style="font-style: italic;">F<sub>R</sub></span> が指定されていることを明示したいとき，<b><span style="font-style: italic;">R</span></b>=(Ω<sub><span style="font-style: italic;">R</sub></span>, <span style="font-style: italic;">F<sub>R</sub></span>)と表すこととする．ここに，Ω<sub><span style="font-style: italic;">R</sub></span> ={A<sub>1</sub>, A<sub>2</sub>,<sub> …</sub>, A<sub>n</sub>}，<span style="font-style: italic;">F<sub>R</sub></span>={f<sub>1</sub>, f<sub>2</sub>,<sub> …</sub>, f<sub>p</sub>}である．</p>
<p><strong>【定義 2】</strong>（リレーションスキーマタの等価）<br />
&emsp;<b><span style="font-style: italic;">R</span></b><sub>1</sub>=(Ω<sub><span style="font-style: italic;">R</sub></span><sub>1</sub>, <span style="font-style: italic;">F<sub>R</sub></span><sub>1</sub>)と<b><span style="font-style: italic;">R</span></b><sub>2</sub>=(Ω<sub><span style="font-style: italic;">R</sub></span><sub>2</sub>, <span style="font-style: italic;">F<sub>R</sub></span><sub>2</sub>)をリレーションスキーマタとする．<b><span style="font-style: italic;">R</span></b><sub>1</sub> と <b><span style="font-style: italic;">R</span></b><sub>2</sub> が<b>等価</b>（equivalent，同値ともいう）とは次の条件が成立するときとし，<b><span style="font-style: italic;">R</span></b><sub>1</sub>≡<b><span style="font-style: italic;">R</span></b><sub>2</sub> と表すこととする．ここに，∧は論理積，<span style="font-style: italic;">F<sub>R</sub></span><sub>1</sub><sup>+</sup> は <span style="font-style: italic;">F<sub>R</sub></span><sub>1</sub> の閉包（定義 3 参照）を表す（<span style="font-style: italic;">F<sub>R</sub></span><sub>2</sub><sup>+</sup> についても同様）．iff は if and only if を表す．<br />
&emsp;&emsp;&emsp;<b><span style="font-style: italic;">R</span></b><sub>1</sub>≡<b><span style="font-style: italic;">R</span></b><sub>2</sub> iff Ω<sub><span style="font-style: italic;">R</sub></span><sub>1</sub>=Ω<sub><span style="font-style: italic;">R</sub></span><sub>2</sub> ∧ <span style="font-style: italic;">F<sub>R</sub></span><sub>1</sub><sup>+</sup>= <span style="font-style: italic;">F<sub>R</sub></span><sub>2</sub><sup>+</sup></p>
<p><strong>【例題 1】</strong><br />
&emsp;例えば，<b><span style="font-style: italic;">R</span></b><sub>1</sub>=({A, B, C}, {A→B, B→C})，<b><span style="font-style: italic;">R</span></b><sub>2</sub>=({A, B, C}, {A→B, B→C, A→C})，<b><span style="font-style: italic;">R</span></b><sub>3</sub>=({A, B, C}, {A→B, A→C})があった時，<b><span style="font-style: italic;">R</span></b><sub>1</sub> と <b><span style="font-style: italic;">R</span></b><sub>2</sub> は属性集合が同じでかつ{A→B, B→C}<sup>+</sup>={A→B, B→C, A→C}<sup>+</sup> なので等価である（ <b><span style="font-style: italic;">R</span></b><sub>1</sub>≡<b><span style="font-style: italic;">R</span></b><sub>2</sub> ）が，<b><span style="font-style: italic;">R</span></b><sub>1</sub> と <b><span style="font-style: italic;">R</span></b><sub>3</sub> は属性集合は同じであるものの{A→B, B→C}<sup>+</sup>≠{A→B, A→C}<sup>+</sup>なので等価でない（<b><span style="font-style: italic;">R</span></b><sub>1</sub>&#x2262;<b><span style="font-style: italic;">R</span></b><sub>3</sub>）．</p>
<p>&emsp;この等価関係は反射律，推移律，対称律を満たします．リレーションスキーマタの等価関係に言及したのは，後段で，設計された RDB の関数従属性保存を議論するときに必用となるからです．</p>
<p><strong>■　関数従属性の集合 <span style="font-style: italic;">F</span> の極小被覆</strong><br />
&emsp;関数従属性の集合 <span style="font-style: italic;">F</span> が与えられたとき，その<strong>極小被覆</strong>（minimal cover）<span style="font-style: italic;">G</span> を求めるアルゴリズムを示します．このアルゴリズムの時間計算量は多項式時間であり，扱いやすい（tractable）問題です．この証明に興味を抱いた者は拙著 [5] を参照してください．<br />
&emsp;まず，FD の集合 <span style="font-style: italic;">F</span> の閉包 <span style="font-style: italic;">F</span><sup>+</sup> を定義する必要があります．<br />
<strong>【定義 3】</strong>（FD 集合の閉包）<br />
&emsp;リレーションスキーマ <b><span style="font-style: italic;">R</span></b>(A<sub>1</sub>, A<sub>2</sub>, <sub>…</sub>, A<sub>n</sub>) に所与の FD 集合 <span style="font-style: italic;">F</span> が指定されているとする．このとき，　<strong><b><span style="font-style: italic;">F</span></b> の閉包 <b><span style="font-style: italic;">F</span></b><sup>+</sup></strong> は次のように定義される．ここに，<span style="font-style: italic;">F</span> ⊨ X→Y は X→Y がアームストロングの公理系のもとで <span style="font-style: italic;">F</span> から導出されることを表す．</p>
<p>&emsp;&emsp;&emsp;<span style="font-style: italic;">F</span><sup>+</sup>={X→Y | X, Y⊆Ω<b><sub><span style="font-style: italic;">R</span></sub></b> ∧ F ⊨ X→Y}</p>
<p>&emsp;続いて，極小被覆を定義します．<br />
<strong>【定義 4】</strong>（FD 集合の極小被覆）<br />
&emsp;関数従属性の集合 <span style="font-style: italic;">G</span> が関数従属性の集合 <span style="font-style: italic;">F</span> の極小被覆（minimal cover）であるとは，次の条件を満たすときをいう．<br />
&emsp;&emsp;(a)　<span style="font-style: italic;">G</span> と <span style="font-style: italic;">F</span> は等価（equivalent，同値ともいう），すなわち，<span style="font-style: italic;">G</span><sup>＋</sup>＝<span style="font-style: italic;">F</span><sup>+</sup> である．<br />
&emsp;&emsp;(b)　<span style="font-style: italic;">G</span> の全ての関数従属性は X→A，ここに A は単一の属性，の形をしている．<br />
&emsp;&emsp;(c)　<span style="font-style: italic;">G</span> に，ある関数従属性 X→A と X の真部分集合 Z（Z⊂X）が存在して，<br />
&emsp;&emsp;&emsp;&emsp; <span style="font-style: italic;">G</span>−{X→A}∪{Z→A} と <span style="font-style: italic;">G</span> が等価になることはない．ここに，− は差集合演算である．<br />
&emsp;&emsp;(d)　<span style="font-style: italic;">G</span> に，ある関数従属性 g が存在して，<span style="font-style: italic;">G</span>−{g} と <span style="font-style: italic;">G</span> が等価になることはない．</p>
<p>&emsp;極小被覆を求めるアルゴリズムは次の通りです．<br />
<strong>【FD 集合 <span style="font-style: italic;">F</span> の極小被覆 <span style="font-style: italic;">G</span> を求めるアルゴリズム】</strong><br />
&emsp; (ステップ 1)　<span style="font-style: italic;">G</span> = <span style="font-style: italic;">F</span> とおく．<br />
&emsp; (ステップ 2)　<span style="font-style: italic;">G</span> 中の各関数従属性で右辺（＝被決定子（resultant））が単一の属性で<br />
&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;ないものがあれば（これを X→{ A<sub>1</sub>, A<sub>2</sub>, · · ·, A<sub>p</sub> } とする），右辺が単一<br />
&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;の属性である p 個の関数従属性 X→A<sub>1</sub>, X→A<sub>2</sub>, · · ·, X→A<sub>p</sub> で置き換える．<br />
&emsp; (ステップ 3)　<span style="font-style: italic;">G</span> 中の各関数従属性 X→A に対して，X を構成する各属性 B に対して，<br />
&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;<span style="font-style: italic;">G</span>−{X→A}∪{{X−B}→A} と <span style="font-style: italic;">G</span> が等価ならば，<span style="font-style: italic;">G</span> の X→A を {X−B}→A<br />
&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;で置き換える．<br />
&emsp; (ステップ 4)　<span style="font-style: italic;">G</span> の各関数従属性 X→A に対して，<span style="font-style: italic;">G</span>−{X→A} が <span style="font-style: italic;">G</span> と等価ならば，<br />
&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;<span style="font-style: italic;">G</span> から X→A を取り除く．</p>
<p>&emsp;ステップ 3 とステップ 4 はこの順番で行う必要があります．例えば，リレーションスキーマ <b><span style="font-style: italic;">R</span></b>(A, B, C)に所与の FD 集合 <span style="font-style: italic;">F</span>={AB→C, C→B, A→B} が指定されているとき，もし，まずステップ 4 を，続いてステップ 3 を適用すると，結果として極小被覆もどきの集合 <span style="font-style: italic;">H</span>= {A→C, C→B, A→B} が得られますが，これは <span style="font-style: italic;">I</span>= <span style="font-style: italic;">H</span>－{ A→B } とすると，A→B は A→C と C→B に推移律を適用すると得られる関数従属性であることから分かるように，<span style="font-style: italic;">H</span><sup>+</sup> = <span style="font-style: italic;">I</span><sup>+</sup> であり，<span style="font-style: italic;">H</span> は極小被覆にはなっていません．</p>
<p>&emsp;ここで，極小被覆を求める簡単な例を示します．<br />
<strong>【例題 2】</strong>（極小被覆を求める）<br />
&emsp;リレーションスキーマ <b><span style="font-style: italic;">R</span></b>(A, B, C, D)に所与の FD 集合 <span style="font-style: italic;">F</span> = {AB→CD, C→D} が指定されているとする．<span style="font-style: italic;">F</span> の極小被覆を求めなさい．<br />
<b>(解答)</b><br />
&emsp;<span style="font-style: italic;">F</span> にステップ 1 とステップ 2 を適用することにより <span style="font-style: italic;">G</span> ={AB→C, AB→D, C→D} となる．ステップ 3 を行う．まず，AB→C の左辺に注目し，A あるいは B が余分ではないか検証する．そこで，A が余分であるかどうかを検証するために，H = G−{AB→C}∪{B→C} とし，<span style="font-style: italic;">H</span><sup>+</sup>= <span style="font-style: italic;">G</span><sup>+</sup> かどうかをチェックする．<span style="font-style: italic;">H</span><sup>+</sup> ⊇ <span style="font-style: italic;">G</span><sup>+</sup> は明らかなので，<span style="font-style: italic;">H</span><sup>+</sup>⊆<span style="font-style: italic;">G</span><sup>+</sup> かどうかをチェックする．そのため <span style="font-style: italic;">H</span> にあり <span style="font-style: italic;">G</span> にない関数従属性 B→C が <span style="font-style: italic;">G</span><sup>+</sup> の元かチェックするが，B の <span style="font-style: italic;">G</span> に関する閉包 B<sup>+</sup> を求めれば，適用する <span style="font-style: italic;">G</span> 中の関数従属性がないので B<sup>+</sup>= {B} である．明らかに，C⊆{B} ではないので，<span style="font-style: italic;">H</span><sup>+</sup>⊆<span style="font-style: italic;">G</span><sup>+</sup> ではなく，よって <span style="font-style: italic;">H</span><sup>+</sup>≠<span style="font-style: italic;">G</span><sup>+</sup> である．以下同様な論理でステップ 3 を実行した結果，置き換えられる <span style="font-style: italic;">G</span> の関数従属性はないことが分かる．続いてステップ 4 を行う．<span style="font-style: italic;">I</span> = <span style="font-style: italic;">G</span>−{AB→D} とし，<span style="font-style: italic;">I</span><sup>+</sup> = <span style="font-style: italic;">G</span><sup>+</sup> をチェックする．<span style="font-style: italic;">G</span> の関数従属性 AB→D について，{A, B} の <span style="font-style: italic;">I</span> に関する閉包を求めると，X<sup>(0)</sup> ={A, B}, X<sup>(1)</sup> = X<sup>(0)</sup>∪{C}, X<sup>(2)</sup> = X<sup>(1)</sup>∪{D} (= {A, B, C, D}) = X<sup>(3)</sup>となり，D∈X<sup>(3)</sup> である．したがって，<span style="font-style: italic;">I</span> = {AB→C, C→D} が <span style="font-style: italic;">F</span> の極小被覆となる．この例では <span style="font-style: italic;">I</span> 以外に <span style="font-style: italic;">F</span> の極小被覆はない．</p>
<p style="text-align: right; margin-top: -26px; "><b>(解答終)</b></p>
<p>&emsp;なお，一般に <span style="font-style: italic;">F</span> の極小被覆 <span style="font-style: italic;">G</span> はただ 1 つとは限りません．したがって，最小（minimum）とは言わずに極小（minimal）というわけです．一般に極小被覆が複数個ある簡単な例を示しておきます．</p>
<p><strong>【例題 3】</strong>（一般に極小被覆は複数個ある）<br />
&emsp;リレーションスキーマ <b><span style="font-style: italic;">R</span></b>(A, B, C)に所与の FD 集合 <span style="font-style: italic;">F</span> = {A→BC, B→AC, C→AB} が指定されているとする．<span style="font-style: italic;">F</span> の極小被覆を求めなさい．<br />
<b>(解答)</b><br />
&emsp;<span style="font-style: italic;">G</span>={A→B, A→C, B→A, B→C, C→A, C→B} として，極小被覆を求めるアルゴリズムを稼働すると次の 5 つを得る．<br />
&emsp;&emsp;①　A→B, A→C, B→A, C→A<br />
&emsp;&emsp;②　B→A, B→C, A→B, C→B<br />
&emsp;&emsp;③　C→A, C→B, A→C, B→C<br />
&emsp;&emsp;④　A→B, B→C, C→A<br />
&emsp;&emsp;⑤　A→C, B→A, C→B</p>
<p style="text-align: right; margin-top: -26px; "><b>(解答終)</b></p>
<p><strong>■　関数従属性保存</strong><br />
&emsp;リレーションスキーマ <b><span style="font-style: italic;">R</span></b> が情報無損失分解されたとき，<b><span style="font-style: italic;">R</span></b> 上で成立していた FD が定義できなくなくなることはない，つまり保存されているという概念が関数従属性保存です．そのためには，まず FD 集合の閉包の射影を定義することが必要です．</p>
<p><strong>【定義 5】</strong>（FD 集合の閉包の射影）<br />
&emsp;リレーションスキーマ <b><span style="font-style: italic;">R</span></b> に所与の関数従属性の集合 <span style="font-style: italic;">F</span> が指定されているとする．このとき，一般に Z⊆Ω<sub><b><span style="font-style: italic;">R</span></b></sub> として，<b><span style="font-style: italic;">F</span><sup>+</sup>の Z 上の射影 <span style="font-style: italic;">F</span><sup>+</sup>[Z]</b>は次のように定義される．<br />
&emsp;&emsp;&emsp;<span style="font-style: italic;">F</span><sup>+</sup>[Z]={X→Y|X→Y∈<span style="font-style: italic;">F</span><sup>+</sup> ∧ X∪Y⊆Z}</p>
<p>&emsp;&emsp;この定義を用いて関数従属性保存の定義を与えることができます．<br />
<strong>【定義 6】</strong>(関数従属性保存)<br />
&emsp;リレーションスキーマ <b><span style="font-style: italic;">R</span></b> に所与の関数従属性の集合 <span style="font-style: italic;">F</span> が指定されているとする．X→Y∈<span style="font-style: italic;">F</span><sup>+</sup>として，X→Yによる <b><span style="font-style: italic;">R</span></b> の <b><span style="font-style: italic;">R</span></b>[X, Y]と <b><span style="font-style: italic;">R</span></b>[Ω<sub><b><span style="font-style: italic;">R</span></b></sub>－Y]への情報無損失分解が関数従属性保存であるとは，次が成立するときをいう．<br />
&emsp;&emsp;&emsp;(<span style="font-style: italic;">F</span><sup>+</sup>[X∪Y]∪<span style="font-style: italic;">F</span><sup>+</sup>[Ω<sub><b><span style="font-style: italic;">R</span></b></sub>－Y])<sup>+</sup>=<span style="font-style: italic;">F</span><sup>+</sup></p>
<p>&emsp;以上で，基礎的事項の説明は終了です．<span style="font-style: italic;">F</span><sup>+</sup> を求める具体例や，リレーションスキーマを FD で情報無損失分解した場合に，どのようなときに関数従属性が保存されない状況が発生するのかなどの例題は SRA OSS Tech Blog に収録されている拙稿 [3]に掲載されているので，参照してください．<br />
&emsp;続いて，RDB 設計の合成的アプローチの説明に移りましょう．</p>
<h4>3. RDB 設計の合成的アプローチ</h4>
<p style="margin-top: -10px;">
&emsp;1976 年にバーンシュタイン（P.A. Bernstein）が提案した RDB 設計の<b>合成的アプローチ</b>（synthetic approach）[4] は，データベース化の対象となった世界を表すリレーションスキーマ <b><span style="font-style: italic;">R</span></b>(A<sub>1</sub>, A<sub>2</sub>,<sub> …</sub>, A<sub>n</sub>)に所与の FD 集合 <span style="font-style: italic;">F</span> が指定されているとして，それを基に「関数従属性保存・3NF・情報無損失分解」と三拍子揃った RDB を設計するという手法です．そのアルゴリズムは次の通りです．<br />
<strong>【合成的アプローチによる RDB 設計アルゴリズム】</strong><br />
&emsp; リレーションスキーマ <b><span style="font-style: italic;">R</span></b> に所与の関数従属性の集合 <span style="font-style: italic;">F</span> が指定されているとする．このとき，合成的アプローチによる RDB 設計のアルゴリズムは次の通りである．</p>
<p>(ステップ 1)　<span style="font-style: italic;">F</span> の極小被覆 <span style="font-style: italic;">G</span> を一つ見つける．<br />
(ステップ 2)　X を決定子（determinant）に持つ <span style="font-style: italic;">G</span> の全ての関数従属性 X→B<sub>1</sub>, X→B<sub>2</sub>, · · ·, X→B<sub>k</sub><br />
&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;  に対して（<span style="font-style: italic;">G</span> が極小だから各 B<sub>i</sub> は単一属性），Y = {B<sub>1</sub>, B<sub>2</sub>, …, B<sub>k</sub>} とし，リレー<br />
&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;  ションスキーマ <b><span style="font-style: italic;">R</span></b>(X, Y) を作る．この操作を <span style="font-style: italic;">G</span> の全ての関数従属性に対して行う．<br />
&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;  その結果，リレーションスキーマタ <b><span style="font-style: italic;">R</span></b><sub>1</sub>(X<sub>1</sub>, Y<sub>1</sub>), <b><span style="font-style: italic;">R</span></b><sub>2</sub>(X<sub>2</sub>, Y<sub>2</sub>), · · · , <b><span style="font-style: italic;">R</span></b><sub>m</sub>(X<sub>m</sub>, Y<sub>m</sub>) を得る．<br />
 (ステップ 3)　もし，ステップ 2 で作ったリレーションスキーマタ <b><span style="font-style: italic;">R</span></b><sub>1</sub>, <b><span style="font-style: italic;">R</span></b><sub>2</sub>, · · · , <b><span style="font-style: italic;">R</span></b><sub>m</sub> の中に，<b><span style="font-style: italic;">R</span></b> の<br />
&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;  候補キーを含むリレーションスキーマが存在すれば，{ <b><span style="font-style: italic;">R</span></b><sub>1</sub>, <b><span style="font-style: italic;">R</span></b><sub>2</sub>, · · · , <b><span style="font-style: italic;">R</span></b><sub>m</sub> } が所望の<br />
&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;  分解であり，もしそうでなければ <b><span style="font-style: italic;">R</span></b> の候補キーのひとつを K として <b><span style="font-style: italic;">R</span></b><sup>’</sup> (K) を作る<br />
&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;  と（作り方から，<b><span style="font-style: italic;">R</span></b><sup>’</sup> 上には自明でない関数従属性は存在していない），{<b><span style="font-style: italic;">R</span></b><sup>’</sup> (K), <b><span style="font-style: italic;">R</span></b><sub>1</sub>,<br />
&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;  <b><span style="font-style: italic;">R</span></b><sub>2</sub>, · · · , <b><span style="font-style: italic;">R</span></b><sub>m</sub>} が所望の分解である．</p>
<p>&emsp;前述の通り，一般に <span style="font-style: italic;">F</span> の極小被覆 <span style="font-style: italic;">G</span> はただ 1 つとは限らないので，求められた <span style="font-style: italic;">G</span> の違いで，得られる RDB が異なってくる可能性があることに注意します．<br />
&emsp;また，このアルゴリズムの正しさ，つまりこのアルゴリズムにより <b><span style="font-style: italic;">R</span></b> の関数従属性保存で情報無損失な 3NF への分解が得られることは，ステップ 2 とステップ 3 で行った <b><span style="font-style: italic;">R</span></b> の分解が，(1) 関数従属性保存であること，続いて，(2) （各成分リレーションスキーマが）3NFであること，そして，(3) 情報無損失分解であることを証明することで示されます．特に(3)の証明は結構難易度が高いので，ここでは立ち入らないことにしますが，アルゴリズムの正しさの証明は拙著 [5] でも与えられているので，興味を抱いた読者はご参照ください．<br />
&emsp;なお，この手法が合成的と呼ばれるのは，ステップ 2 で同じ決定子を持つ関数従属性がまとめ上げられて 1 つの候補キーが合成されて（synthesized），その結果，1 つのリレーションスキーマが合成されることからきています．</p>
<p><strong>■　実は，3NF より正規度の高い BCNF であること</strong><br />
&emsp;1993年にビンセント（M.W. Vincent）らにより「重複する候補キーのペアがない 3NF リレーションスキーマは BCNF であること」が証明されました[6]．上記，合成的アプローチによる RDB 設計アルゴリズムのステップ 2 を見て分かるように，得られるリレーションスキーマ <b><span style="font-style: italic;">R</span></b>(X, Y)では X のみが候補キーで，<b><span style="font-style: italic;">R</span></b> に重複する候補キーのペアはあり得ません．したがって，合成的アプローチで設計された RDB は BCNF のリレーションスキーマタからなると言えます（もちろん，3NF です）．よって，合成的アプローチは「関数従属性保存・<b>BCNF</b>・情報無損失分解」と三拍子揃った RDB を設計する手法と言い換えた方が正確でしょう．3NF ではなく BCNF となっていることで，3NF ではあるが BCNF ではないリレーションで発生する更新時異状を合成的アプローチで RDB を設計することで抑制することが可能となってきます．このことについては，例題 6 でより具体的に論じます．なお，以下ではこのことを十分に承知したうえで「関数従属性保存・3NF・情報無損失分解」という伝統的な表現を使用します．</p>
<p>&emsp;次章では，上記のアルゴリズムの下で RDB がどのように設計されていくかについてその感触をつかんでいただくと共に，分解的アプローチと合成的アプローチでは，たとえ最初に与えられたリレーションスキーマが同一でも得られた RDB は一般には異なることを観察してみたいと思います．</p>
<h4>4. 分解的 vs. 合成的アプローチ―その差異の本質は？―</h4>
<p style="margin-top: -10px;">
&emsp;本章では，RDB を分解的アプローチと合成的アプローチで設計してみて，両アプローチの違いを観察することによって，特に合成的アプローチの持っている意味合いについて検証してみたいと思います．合成的アプローチの目標は「情報無損失・3NF・関数従属性保存」の RDB を設計することなので，それに合わせて分解的アプローチでの RDB 設計のゴールは「情報無損失・3NF」のリレーションスキーマタからなる RDB を設計することとします．分解的アプローチでは一般に関数従属性は保存されませんから[3]，両者を比較するには妥当な条件設定と考えられます．<br />
&emsp;それでは，幾つかの例題を通して両アプローチで得られた結果を比較し，その差異を検討してみましょう．</p>
<p><strong>【例題 4】</strong><br />
&emsp;リレーションスキーマ <b><span style="font-style: italic;">R</span></b>(A, B, C, D)に所与の FD 集合 <span style="font-style: italic;">F</span>={A→B,B→C} が指定されているとする．RDB を合成的アプローチと分解的アプローチで設計してみなさい．<br />
<b>(解答)</b><br />
&emsp;(1) 分解的アプローチで設計した RDB<br />
&emsp;&emsp;  <b><span style="font-style: italic;">R</span></b> の候補キーは{A, D}で，<b><span style="font-style: italic;">R</span></b> の非キー属性は B と C であり，B と C は A に関数従属している，<br />
&emsp;&emsp;  つまり{A, D}には完全関数従属していないので <b><span style="font-style: italic;">R</span></b> は 2NF ではない．そこで，B→C を使って<br />
&emsp;&emsp;  <b><span style="font-style: italic;">R</span></b> を <b><span style="font-style: italic;">R</span></b>[<u>B</u>,C] と <b><span style="font-style: italic;">R</span></b>[<u>A</u>, B, <u>D</u>] に情報無損失分解すると，<b><span style="font-style: italic;">R</span></b>[<u>A</u>, B, <u>D</u>]も 2NF ではないので，それを<br />
&emsp;&emsp;  A→B で <b><span style="font-style: italic;">R</span></b>[<u>A</u>, B]と <b><span style="font-style: italic;">R</span></b>[<u>A</u>, <u>D</u>]に情報無損失分解する．その結果，{<b><span style="font-style: italic;">R</span></b>[<u>A</u>, B], <b><span style="font-style: italic;">R</span></b>[<u>B</u>,C], <b><span style="font-style: italic;">R</span></b>[<u>A</u>, <u>D</u>]}が<br />
&emsp;&emsp;  所望の RDB となる．この場合，関数従属性保存であることは A→B が <b><span style="font-style: italic;">R</span></b>[<u>A</u>, B]で，B→C が<br />
&emsp;&emsp;  <b><span style="font-style: italic;">R</span></b>[<u>B</u>,C]で定義されていることから分かる．<br />
&emsp;(2) 合成的アプローチで設計した RDB<br />
&emsp;&emsp;  <span style="font-style: italic;">F</span> 自体が <span style="font-style: italic;">F</span> の極小被覆である(ステップ 1)．A→B の決定子 A と B→C の決定子 B は異<br />
&emsp;&emsp;  なるので，リレーションスキーマタ <b><span style="font-style: italic;">R</span></b><sub>1</sub>(<u>A</u>, B), <b><span style="font-style: italic;">R</span></b><sub>2</sub>(<u>B</u>, C) を得る（ステップ 2）．ところで，<br />
&emsp;&emsp;  <b><span style="font-style: italic;">R</span></b> の候補キーは {A, D} であるが，これは <b><span style="font-style: italic;">R</span></b><sub>1</sub> にも <b><span style="font-style: italic;">R</span></b><sub>2</sub> にも含まれないので，<b><span style="font-style: italic;">R</span></b><sup>’</sup>(<u>A</u>, <u>D</u>) を作<br />
&emsp;&emsp;  る(ステップ 3)．その結果，{<b><span style="font-style: italic;">R</span></b><sub>1</sub>(<u>A</u>, B), <b><span style="font-style: italic;">R</span></b><sub>2</sub>(<u>B</u>, C), <b><span style="font-style: italic;">R</span></b><sup>’</sup>(<u>A</u>, <u>D</u>)}が所望の RDB である．</p>
<p style="text-align: right; margin-top: -26px; "><b>(解答終)</b></p>
<p>&emsp;この例では，どちらのアプローチをとっても，設計された RDB は同一で，共に「情報無損失分解・3NF・関数従属性保存」となっていることが分かります．</p>
<p><strong>【例題 5】</strong><br />
&emsp;リレーションスキーマ <b><span style="font-style: italic;">R</span></b>(A, B, C, D)に所与の FD 集合 <span style="font-style: italic;">F</span>={A→B, B→C, A→D, D→C}が指定されているとする．RDB を分解的アプローチと合成的アプローチで設計してみなさい．<br />
<b>(解答)</b><br />
&emsp;(1) 分解的アプローチで設計した RDB<br />
&emsp;&emsp;  <b><span style="font-style: italic;">R</span></b> の候補キーは A で，<b><span style="font-style: italic;">R</span></b> の非キー属性 B, C, D は A に完全関数従属しているので，<b><span style="font-style: italic;">R</span></b> は 2NF<br />
&emsp;&emsp;  である．しかし，A→B→C と A→D→Cという推移的関数従属性が存在するので 3NF ではない．<br />
&emsp;&emsp;  そこで，A→B→C を解消するべく，<b><span style="font-style: italic;">R</span></b> を B→C を使って <b><span style="font-style: italic;">R</span></b>[<u>B</u>, C] と <b><span style="font-style: italic;">R</span></b>[<u>A</u>, B, D] に情報無損失<br />
&emsp;&emsp;  分解すると，それらは 3NF になるが D→C を保存できなく，この情報無損失分解は関数従属性<br />
&emsp;&emsp;  保存ではないことが分かる．同様に，A→D→C を解消するべく，<b><span style="font-style: italic;">R</span></b> を D→C を使って <b><span style="font-style: italic;">R</span></b>[<u>D</u>, C]<br />
&emsp;&emsp;  と <b><span style="font-style: italic;">R</span></b>[<u>A</u>, B, D] に情報無損失分解すると，それらは 3NF になるが B→C を保存できなく，この<br />
&emsp;&emsp;  情報無損失分解も関数従属性保存ではないことが分かる[3]．したがって，設計された RDB<br />
&emsp;&emsp;  {<b><span style="font-style: italic;">R</span></b>[<u>B</u>, C], <b><span style="font-style: italic;">R</span></b>[<u>A</u>, B, D]} と {<b><span style="font-style: italic;">R</span></b>[<u>D</u>, C], <b><span style="font-style: italic;">R</span></b>[<u>A</u>, B, D]} はいずれも「情報無損失分解・3NF」ではある<br />
&emsp;&emsp;  ものの関数従属性保存ではない．<br />
&emsp;(2) 合成的アプローチで設計した RDB<br />
&emsp;&emsp;  <span style="font-style: italic;">F</span> 自体が <span style="font-style: italic;">F</span> の極小被覆である(ステップ 1)．A→B，A→D であり，B→C，D→C であるので，<br />
&emsp;&emsp;  リレーションスキーマタ <b><span style="font-style: italic;">R</span></b><sub>1</sub>(<u>A</u>, B, D), <b><span style="font-style: italic;">R</span></b><sub>2</sub>(<u>B</u>, C), <b><span style="font-style: italic;">R</span></b><sub>3</sub>(<u>D</u>, C) を得る（ステップ 2）ところで，<b><span style="font-style: italic;">R</span></b><br />
&emsp;&emsp;  の候補キーは A であるが，A は <b><span style="font-style: italic;">R</span></b><sub>1</sub> に含まれているので，{<b><span style="font-style: italic;">R</span></b><sub>1</sub>(<u>A</u>, B, D), <b><span style="font-style: italic;">R</span></b><sub>2</sub>(<u>B</u>, C) , <b><span style="font-style: italic;">R</span></b><sub>3</sub>(<u>D</u>, C)}<br />
&emsp;&emsp;  が所望の RDB である(ステップ 3)．合成的アプローチをとったことにより，得られた RDB<br />
&emsp;&emsp;  は「情報無損失分解・3NF・関数従属性保存」である．</p>
<p style="text-align: right; margin-top: -26px; "><b>(解答終)</b></p>
<p>&emsp;では，この例で、もう少し詳しく両アプローチを比較・検討してみましょう．両アプローチの下で設計された RDB は次のようでした．</p>
<p>&emsp;&emsp;分解的アプローチ：{<b><span style="font-style: italic;">R</span></b>[<u>B</u>, C], <b><span style="font-style: italic;">R</span></b>[<u>A</u>, B, D]}，あるいは{<b><span style="font-style: italic;">R</span></b>[<u>D</u>, C], <b><span style="font-style: italic;">R</span></b>[<u>A</u>, B, D]}<br />
&emsp;&emsp;合成的アプローチ：{<b><span style="font-style: italic;">R</span></b><sub>1</sub>(<u>A</u>, B, D), <b><span style="font-style: italic;">R</span></b><sub>2</sub>(<u>B</u>, C), <b><span style="font-style: italic;">R</span></b><sub>3</sub>(<u>D</u>, C)}</p>
<p>&emsp;以下，一般性を失うことなく，分解的アプローチで設計された RDB は{<b><span style="font-style: italic;">R</span></b>[<u>B</u>, C], <b><span style="font-style: italic;">R</span></b>[<u>A</u>, B, D]} であるとして議論を進めます．<br />
&emsp;そこで，両者の違いを理解するために，具体的にリレーション R へのタップルの挿入を想定して，その時に観察される現象を見てみることにします．分かり易さのため，<b><span style="font-style: italic;">R</span></b> のインスタンス R は単純に 1 本のタップル (a, b, c, d) からなっている，すなわち R={(a, b, c, d)}，とします．すると，(a, b, c, d) は分解的アプローチでは R[<u>B</u>, C] ={(b, c)}, R[<u>A</u>, B, D] ={(a, b, d)}} と格納され，合成的アプローチでは R<sub>1</sub>(<u>A</u>, B, D) ={(a, b, d)}, R<sub>2</sub>(<u>B</u>, C) ={(b, c)}, R<sub>3</sub>(<u>D</u>, C) ={(d, c)} と格納されます．そこで，R に D→C に抵触するタップル(a’, b’, c’, d)，ここに a’≠a, b≠’b, c≠’c，を挿入しようと<ruby>目論<rt style="background-color: #DDDDDD;">もくろく</rt></ruby>んだ場合，何が起こるのか観察してみます（もちろん，R では D→C が成立していますから (a’, b’, c’, d) を挿入することはできません）．両アプローチの下で設計された RDB で発生する現象は次の通りです．<br />
&emsp;(1) 分解的アプローチで観察される現象</p>
<p style="margin-top: -30px;" >
<table style="border:none; margin-top: -0px; margin-left: 30px; margin-bottom: -00px;" align="left" >
<tbody style="border:none;">
<td style="width: 800px; border:none;">
&emsp;R[<u>B</u>, C] への (b’, c’) の挿入は既存の (b, c) と抵触しないので行えます．また，R[<u>A</u>, B, D] への (a’, b’, d) の挿入は既存の (a, b, d) と抵触しないので行えます．したがって，R[<u>B</u>, C]={(b, c), (b’, c’)}，R[<u>A</u>, B, D]={(a, b, d), (a’, b’, d)} となります．そこで，R[<u>B</u>, C]*R[<u>A</u>, B, D] をとってみると，R[<u>B</u>, C]*R[<u>A</u>, B, D]={(a, b, c, d), (a’, b’, c’, d)} となります．R[<u>B</u>, C] と R[<u>A</u>, B, D] は R の B→C による情報無損失分解なので，これは R= R[<u>B</u>, C]*R[<u>A</u>, B, D]={(a, b, c, d), (a’, b’, c’, d)} を意味することになりますが，R に所与の D→C に抵触することは明らかです．これが B→C による <b><span style="font-style: italic;">R</span></b> の{<b><span style="font-style: italic;">R</span></b>[<u>B</u>, C], <b><span style="font-style: italic;">R</span></b>[<u>A</u>, B, D]} への情報無損失分解が関数従属性保存でないことによる結果なわけです．<br />
&emsp;この現象はよりフォーマルに次のように説明できるでしょう．<br />
&emsp;まず，リレーションスキーマ <b><span style="font-style: italic;">R</span></b>(A, B, C, D) の B→C による分解は情報無損失分解ですが，それは次式を意味します．ここに，(∀R∈<b><span style="font-style: italic;">R</span></b>)は R は <b><span style="font-style: italic;">R</span></b> の任意のインスタンスを表します．<br />
&emsp;(∀R∈<b><span style="font-style: italic;">R</span></b>)(R=R[B, C]*R[A, B, D])<br />
&emsp;次に，リレーションスキーマ <b><span style="font-style: italic;">R</span></b> の定義は次の通りです．<br />
&emsp;<b><span style="font-style: italic;">R</span></b>=(Ω<sub><b><span style="font-style: italic;">R</span></b></sub>, <span style="font-style: italic;">F</span><sub><b><span style="font-style: italic;">R</span></b></sub>)，ここに，Ω<sub><b><span style="font-style: italic;">R</span></b></sub> ={A, B, C, D}，<span style="font-style: italic;">F</span><sub><b><span style="font-style: italic;">R</span></b></sub>={A→B, B→C, A→D, D→C}．<br />
&emsp;一方，<b><span style="font-style: italic;">R</span></b>[<u>B</u>, C]*<b><span style="font-style: italic;">R</span></b>[<u>A</u>, B, D] のリレーションスキーマとしての定義は次の通りとなります．<br />
&emsp;<b><span style="font-style: italic;">R’</span></b>=<b><span style="font-style: italic;">R</span></b>[<u>B</u>, C]*<b><span style="font-style: italic;">R</span></b>[<u>A</u>, B, D]= (Ω<sub><b><span style="font-style: italic;">R’</span></b></sub>, F<sub><b><span style="font-style: italic;">R’</span></b></sub>)，ここに，Ω<sub><b><span style="font-style: italic;">R’</span></b></sub> ={A, B, C, D}，<span style="font-style: italic;">F</span><sub><b><span style="font-style: italic;">R’</span></b></sub> ={A→B, B→C, A→D}．<br />
&emsp;そこで，<b><span style="font-style: italic;">R</span></b>=(Ω<sub><b><span style="font-style: italic;">R</span></b></sub>, F<sub><b><span style="font-style: italic;">R</span></b></sub>) と <b><span style="font-style: italic;">R’</span></b> =(Ω<sub><b><span style="font-style: italic;">R’</span></b></sub>, F<sub><b><span style="font-style: italic;">R’</span></b></sub>)を比較してみると，Ω<sub><b><span style="font-style: italic;">R</span></b></sub>=Ω<sub><b><span style="font-style: italic;">R’</span></b></sub> ですが，<span style="font-style: italic;">F</span><sub><b><span style="font-style: italic;">R</span></b></sub><sup>+</sup>≠<span style="font-style: italic;">F</span><sub><b><span style="font-style: italic;">R’</span></b></sub><sup>+</sup>です．つまり，<b><span style="font-style: italic;">R</span></b> と <b><span style="font-style: italic;">R’</span></b> はリレーションスキーマとして等価でないことが分かります．<br />
&emsp;従って，分解的アプローチで得られた RDB については，次が成立しているといえます．</p>
<p>&emsp;&emsp;&emsp;(∀R∈<b><span style="font-style: italic;">R</span></b>)(R=R[B, C]*R[A, B, C]) ∧<br />
&emsp;&emsp;&emsp;<b><span style="font-style: italic;">R</span></b> ≢<b><span style="font-style: italic;">R</span></b>[<u>B</u>, C]*R[<u>A</u>, B, D]&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;・・・・・・・・・・(1)
</td>
</tbody>
</table>
<p>&emsp;(2) 合成的アプローチで観察される現象</p>
<p style="margin-top: -30px;" >
<table style="border:none; margin-top: -0px; margin-left: 30px; margin-bottom: -00px;" align="left" >
<tbody style="border:none;">
<td style="width: 800px; border:none;">
&emsp;R<sub>2</sub>(<u>B</u>, C) への (b’, c’) の挿入は既存の (b, c) と抵触しないので行えます．また，R<sub>1</sub>(<u>A</u>, B, D) への (a’, b’, d) の挿入は既存の (a, b, d) と抵触しないので行えます．これらは分解的アプローチでの R[<u>B</u>, C] への (b’, c’) の挿入と R[<u>A</u>, B, D] への (a’, b’, d) の挿入に対応しています．しかし，<br />R<sub>3</sub>(D,C)への (d, c’) の挿入は R<sub>3</sub> (D,C) で D→C が成立しているので既存の (d, c) と抵触しそれを行えません．したがって，よしんば R<sub>2</sub> と R<sub>1</sub> へそれぞれ (b’, c’) と (a’, b’, d) が挿入され，R<sub>2</sub>(<u>B</u>, C)={(b, c), (b’, c’)}，R<sub>1</sub>(<u>A</u>, B, D)={(a, b, d), (a’, b’, d)}となったとしても，R<sub>3</sub> には (d, c’) の挿入は許されずに R<sub>3</sub>(<u>D</u>, C)={(d, c)}のままなので，R=R<sub>2</sub>(<u>B</u>, C)*R<sub>1</sub>(<u>A</u>, B, D)*R<sub>3</sub>(<u>D</u>, C)={(a, b, c, d)}となり，R に D→C に抵触するようなタップルの挿入は許されない仕組みとなっています．つまり，<b><span style="font-style: italic;">R</span></b> の {<b><span style="font-style: italic;">R</span></b><sub>1</sub>(<u>A</u>, B, D), <b><span style="font-style: italic;">R</span></b><sub>2</sub>(<u>B</u>, C), <b><span style="font-style: italic;">R</span></b><sub>3</sub>(<u>D</u>, C)}への分解は情報無損失でかつ関数従属性保存の分解となっています．そして，この現象はよりフォーマルに次のように説明できます．<br />
&emsp;<b><span style="font-style: italic;">R”</span></b>=<b><span style="font-style: italic;">R</span></b><sub>2</sub>(<u>B</u>, C)*<b><span style="font-style: italic;">R</span></b><sub>1</sub>(<u>A</u>, B, D)*<b><span style="font-style: italic;">R</span></b><sub>3</sub>(<u>D</u>, C)= (Ω<sub><b><span style="font-style: italic;">R”</span></b></sub>, <span style="font-style: italic;">F</span><sub><b><span style="font-style: italic;">R”</span></b></sub>) とすると，Ω<sub><b><span style="font-style: italic;">R”</span></b></sub>={A, B, C, D}，<span style="font-style: italic;">F</span><sub><b><span style="font-style: italic;">R”</span></b></sub>={A→B, B→C, A→D, D→C} となり，<b><span style="font-style: italic;">R</span></b> と <b><span style="font-style: italic;">R”</span></b> は等価です．つまり，合成的アプローチで得られた RDB については，次が成立していることとなります．</p>
<p>&emsp;&emsp;&emsp;(∀R∈<b><span style="font-style: italic;">R</span></b>)( R=R<sub>1</sub>(<u>A</u>, B, D)* R<sub>2</sub>(<u>B</u>, C)*R<sub>3</sub>(<u>D</u>, C)) ∧<br />
&emsp;&emsp;&emsp;<b><span style="font-style: italic;">R</span></b>≡<b><span style="font-style: italic;">R</span></b><sub>1</sub>(<u>A</u>, B, D)*<b><span style="font-style: italic;">R</span></b><sub>2</sub>(<u>B</u>, C)*<b><span style="font-style: italic;">R</span></b><sub>3</sub>(<u>D</u>, C) ・・・・・・・・・・(2)
</td>
</tbody>
</table>
<p>&emsp;(1)式と(2)式は分解的アプローチと合成的アプローチの差異をフォーマルに表現していることになります．繰り返しになりますが，両アプローチで設計された RDB は共に情報無損失分解であることは保証されてはいますが，(1)式により分解的アプローチで設計された RDB はリレーションスキーマタの等価関係の不成立により関数従属性保存ではないことを，一方，(2)式により合成的アプローチで設計された RDB はリレーションスキーマタの等価関係の成立により関数従属性保存であることが明確に読み取れます．</p>
<p>&emsp;さて，分解的アプローチで設計された RDB と合成的アプローチで設計された RDB を見比べると，<b><span style="font-style: italic;">R</span></b>[<u>B</u>, C]≡<b><span style="font-style: italic;">R</span></b><sub>2</sub>(<u>B</u>, C), <b><span style="font-style: italic;">R</span></b>[<u>A</u>, B, D]≡<b><span style="font-style: italic;">R</span></b><sub>1</sub>(<u>A</u>, B, D) なので，合成的アプローチで設計された RDB では，分解的アプローチにより設計された RDB と比べて <b><span style="font-style: italic;">R</span></b><sub>3</sub>(<u>D</u>, C) だけ余計（？）に設計されている，と感じるかもしれません．実際，リレーションを RDB に格納するとなると，その分だけ余計にメモリを食うことになります．しかし，上で見た通り，これが関数従属性保存を保証する代償であったわけです．</p>
<p>&emsp;RDB の設計にあたっては，設計者は分解的アプローチを採用するべきか，合成的アプローチを採用するべきか，その選択を迫られます．少し乱暴な表現をすれば，「（データを格納するための）メモリは食わないが関数従属性保存の確約はない分解的アプローチ」を選ぶか，「分解的アプローチに比べれば，一般にはメモリを食うものの関数従属性保存を保証してくれる合成的アプローチ」を選ぶか，その決断を RDB 設計者は行わなくてはならないということです．これが分解的 vs. 合成的アプローチのpros and cons（利点と問題点）の一面です．</p>
<p><strong>■　合成的アプローチでは BCNF にまでなっていることの恩恵</strong><br />
&emsp;ところで，3 章で述べた通り，<u>合成的アプローチで設計された RDB のリレーションスキーマタは 3NF より正規度の高い BCNF となっています</u>．このことが，両アプローチの pros and cons と大いに関係することになります．議論は RDB の更新時異状と絡みます．例題を挙げて論じてみましょう．</p>
<p><strong>【例題 6】</strong><br />
&emsp;ある学校での，学生（学生名で一意識別），学生が履修する科目（科目名で一意識別），そしてその科目を教授する教員（教員名で一意識別）の関係を表すリレーションスキーマを <b><span style="font-style: italic;">SCT</span></b>=(Ω<sub><span style="font-style: italic;">SCT</span></sub>, <span style="font-style: italic;">F</span><sub><span style="font-style: italic;">SCT</span></sub>)，ここに，Ω<sub><span style="font-style: italic;">SCT</span></sub> ={学生，科目名，教員名}，<span style="font-style: italic;">F</span><sub><span style="font-style: italic;">SCT</span></sub> ={{学生名, 科目名}→教員名，教員名→科目名}とする．RDB を分解的アプローチと合成的アプローチで設計してみなさい．<br />
<b>(解答)</b><br />
&emsp;(1) 分解的アプローチで設計した RDB<br />
&emsp;&emsp;  リレーションスキーマ <b><span style="font-style: italic;">SCT</span></b> の候補キーは{学生名, 科目名}と{学生名, 教員名} と 2 つある．<br />
&emsp;&emsp;  したがって，非キー属性は存在しないので 3NF である．そこで，一般性を失うことなく，<br />
&emsp;&emsp;  たとえば，{学生名, 科目名} を主キーとすれば，<b><span style="font-style: italic;">SCT</span></b>(<u>学生名</u>, <u>科目名</u>，教員名)が所望の<br />
&emsp;&emsp;  RDB である．<br />
&emsp;(2) 合成的アプローチで設計した RDB<br />
&emsp;&emsp;  <span style="font-style: italic;">F</span><sub><span style="font-style: italic;">SCT</span></sub> 自体がその極小被覆である(ステップ 1)．{学生名, 科目名}→教員名，教員名→科目名<br />
&emsp;&emsp;  なので，<b><span style="font-style: italic;">R</span></b><sub>1</sub>(<u>学生名</u>, <u>科目名</u>，教員名)と <b><span style="font-style: italic;">R</span></b><sub>2</sub> (<u>教員名</u>，科目名)が得られる(ステップ 2)．<b><span style="font-style: italic;">SCT</span></b><br />
&emsp;&emsp; の候補キーは{学生名, 科目名}と{学生名, 教員名}であるが，<b><span style="font-style: italic;">R</span></b><sub>1</sub> は候補キー{学生名, 科目名}<br />
&emsp;&emsp; を含んでいるので，<b><span style="font-style: italic;">R</span></b><sub>1</sub>(<u>学生名</u>, <u>科目名</u>，教員名)と <b><span style="font-style: italic;">R</span></b><sub>2</sub>(<u>教員名</u>，科目名)が所望の RDB の<br />
&emsp;&emsp; 設計結果となる(ステップ 3)．</p>
<p style="text-align: right; margin-top: -26px; "><b>(解答終)</b></p>
<p>&emsp;さて，両アプローチを比較・検討してみましょう．両アプローチの下で設計された RDB は次のようです．</p>
<p>&emsp;&emsp;&emsp;分解的アプローチ：<b><span style="font-style: italic;">SCT</span></b>(<u>学生名</u>, <u>科目名</u>，教員名)<br />
&emsp;&emsp;&emsp;合成的アプローチ：<b><span style="font-style: italic;">R</span></b><sub>1</sub>(<u>学生名</u>, <u>科目名</u>，教員名), <b><span style="font-style: italic;">R</span></b><sub>2</sub>(<u>教員名</u>，科目名)</p>
<p>この結果で注意しておくべき点は，<b><span style="font-style: italic;">SCT</span></b> と <b><span style="font-style: italic;">R</span></b><sub>1</sub> の属性集合は等しいものの，リレーションスキーマとしてきちんと表現すれば，<b><span style="font-style: italic;">SCT</span></b>=({学生名, 科目名，教員名}, {{学生名, 科目名}→教員名，教員名→科目名})，<b><span style="font-style: italic;">R</span></b><sub>1</sub>=({<u>学生名</u>, <u>科目名</u>，教員名}, {{学生名, 科目名}→教員名})であり，{{学生名, 科目名}→教員名，教員名→科目名}<sup>+</sup>≠{{学生名, 科目名}→教員名}<sup>+</sup>なので，<b><span style="font-style: italic;">SCT</span></b> ≢<b><span style="font-style: italic;">R</span></b><sub>1</sub> であること，もう一つは，<b><span style="font-style: italic;">R</span></b><sub>1</sub> では定義されていない 教員名→科目名 が <b><span style="font-style: italic;">R</span></b><sub>2</sub> で定義されていることです．</p>
<p>&emsp;さて，分解的アプローチではリレーションスキーマ <b><span style="font-style: italic;">SCT</span></b> そのものが RDB の設計ゴールとなり，この場合「情報無損失分解・3NF・関数従属性保存」となっています．一見，めでたしめでたし，と映りますが，よく知られているように，<b><span style="font-style: italic;">SCT</span></b> は 3NF であるが BCNF ではありません．なぜならば，重複する候補キーのペア {学生名, 科目名} と {学生名, 教員名} が存在するからです．したがって，BCNF ではないことによる「更新時異状が発生する」ことになります[5]．これらの異状は，「タップル挿入時異状」，「タップル削除時異状」，「タップル修正時異状」として現れますが，たとえばリレーション SCT が図 1 に示すようであったとすると，以下に示すような現象として観察されます．</p>
<p>&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp; SCT</p>
<p style="margin-top: -430px;" >
<center></p>
<table border=thick>
<tr>
<td style="solid; border-width: 3px; "><center>　　　<u>学生名</u>　　　</center></td>
<p>　　 </p>
<td style="solid; border-width: 3px; "><center>　　<u>科目名</u>　　</center></td>
<td style="solid; border-width: 3px; "><center>　　　教員名　　　</center></td>
</tr>
<tr>
<td style="solid; border-width: 3px; "><center>伊藤</center></td>
<p>　　</p>
<td style="solid; border-width: 3px; "><center>データベース</center></td>
<td style="solid; border-width: 3px; "><center>増永</center></td>
</tr>
<tr>　              </p>
<td style="solid; border-width: 3px; "><center>伊藤</center></td>
<p>　　</p>
<td style="solid; border-width: 3px; "><center>ソフトウェア</center></td>
<td style="solid; border-width: 3px; "><center>西川</center></td>
</tr>
<tr>　              </p>
<td style="solid; border-width: 3px; "><center>中村</center></td>
<p>　　</p>
<td style="solid; border-width: 3px; "><center>データベース</center></td>
<td style="solid; border-width: 3px; "><center>大林</center></td>
</tr>
<tr>　              </p>
<td style="solid; border-width: 3px; "><center>山本</center></td>
<p>　　</p>
<td style="solid; border-width: 3px; "><center>ハードウェア</center></td>
<td style="solid; border-width: 3px; "><center>北川</center></td>
</tr>
</table>
<p></center></p>
<p><center></p>
<p style="margin-top: -30px;" ><b>図 1　分解的アプローチで得られた RDB</b></p>
<p></center></p>
<p>&emsp;<u>タップル挿入時異状</u>：たとえば，新任教員の佐藤が赴任しプログラミングを担当することになったとします．まだ，佐藤先生のプログラミングを履修登録した学生がいないと，タップル(―，プログラミング，佐藤)はキー制約に抵触するので，リレーション SCT には挿入できません．ここに ― はナル（null）を表します．<br />
&emsp;<u>タップル削除時異状</u>：たとえば，学生の伊藤が西川先生の教えるソフトウェアが難しそうなので履修を取りやめたとすると，タップル(伊藤，ソフトウェア，西川)を削除することになりますが，西川先生の教えるソフトウェアを履修している学生が伊藤一人だったので，西川先生がソフトウェアを教えているという事実を SCT に保存できなくなります．もちろん，(―，ソフトウェア，西川)はキー制約に抵触するので挿入できません．<br />
&emsp;<u>タップル修正時異状</u>：たとえば，学生の伊藤がソフトウェアではなく北川先生のハードウェアに履修を変更すると，タップル(伊藤，ソフトウェア，西川)を(伊藤，ハードウェア，北川)に修正するのは良いが，同時に西川先生がソフトウェアを教えているという事実を SCT に保存できなくなります．この更新時異状を解消するために，分解的アプローチでは，SCT を SCT[<u>教員名</u>，科目名]と SCT[<u>学生名</u>，<u>教員名</u>]に情報無損失分解することになりますが，そうすると関数従属性 {学生名, 科目名}→教員名 が保存できなくなるという新たな異状に直面することになります．</p>
<p>&emsp;一方，合成的アプローチではどのような現象が観察されるのか見てみましょう．図 2 に合成的アプローチにより得られた RDB を示します．</p>
<p>&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp; R<sub>1</sub></p>
<p style="margin-top: -430px;" >
<center></p>
<table border=thick>
<tr>
<td style="solid; border-width: 3px; "><center>　　　<u>学生名</u>　　　</center></td>
<p>　　 </p>
<td style="solid; border-width: 3px; "><center>　　<u>科目名</u>　　</center></td>
<td style="solid; border-width: 3px; "><center>　　　教員名　　　</center></td>
</tr>
<tr>
<td style="solid; border-width: 3px; "><center>伊藤</center></td>
<p>　　</p>
<td style="solid; border-width: 3px; "><center>データベース</center></td>
<td style="solid; border-width: 3px; "><center>増永</center></td>
</tr>
<tr>　              </p>
<td style="solid; border-width: 3px; "><center>伊藤</center></td>
<p>　　</p>
<td style="solid; border-width: 3px; "><center>ソフトウェア</center></td>
<td style="solid; border-width: 3px; "><center>西川</center></td>
</tr>
<tr>　              </p>
<td style="solid; border-width: 3px; "><center>中村</center></td>
<p>　　</p>
<td style="solid; border-width: 3px; "><center>データベース</center></td>
<td style="solid; border-width: 3px; "><center>大林</center></td>
</tr>
<tr>　              </p>
<td style="solid; border-width: 3px; "><center>山本</center></td>
<p>　　</p>
<td style="solid; border-width: 3px; "><center>ハードウェア</center></td>
<td style="solid; border-width: 3px; "><center>北川</center></td>
</tr>
</table>
<p></center></p>
<p>&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp; R<sub>2</sub></p>
<p style="margin-top: -430px;" >
<center></p>
<table border=thick>
<tr>
<td style="solid; border-width: 3px; "><center>　　　<u>教員名</u>　　　</center></td>
<p>　　 </p>
<td style="solid; border-width: 3px; "><center>　　科目名　　</center></td>
</tr>
<tr>
<td style="solid; border-width: 3px; "><center>増永</center></td>
<p>                       　</p>
<td style="solid; border-width: 3px; "><center>データベース</center></td>
</tr>
<tr>　              </p>
<td style="solid; border-width: 3px; "><center>西川</center></td>
<p>　</p>
<td style="solid; border-width: 3px; "><center>ソフトウェア</center></td>
</tr>
<tr>　              </p>
<td style="solid; border-width: 3px; "><center>大林</center></td>
<p>　</p>
<td style="solid; border-width: 3px; "><center>データベース</center></td>
</tr>
<tr>　              </p>
<td style="solid; border-width: 3px; "><center>北川</center></td>
<p>　</p>
<td style="solid; border-width: 3px; "><center>ハードウェア</center></td>
</tr>
</table>
<p></center></p>
<p><center></p>
<p style="margin-top: -30px;" ><b>図 2　合成的アプローチで得られた RDB</b></p>
<p></center></p>
<p>&emsp;この場合，<u>分解的アプローチで指摘された更新時異状は発生しません</u>．たとえば，新任教員の佐藤が赴任しプログラミングを担当することになったとすれば，R<sub>2</sub> にタップル（佐藤，プログラミング）を挿入すればそれで済みます．したがって，タップル挿入時異状は発生しません．学生の伊藤が西川先生の教えるソフトウェアが難しそうなので履修を取りやめたとすると，R<sub>1</sub> からタップル(伊藤，ソフトウェア，西川)を削除することになりますが，西川先生がソフトウェアを教えているという事実は R<sub>2</sub> にしっかり保存されています．したがって，タップル削除時異状は観察されません．たとえば，学生の伊藤がソフトウェアではなく北川先生のハードウェアに履修を変更すると，R<sub>1</sub> のタップル(伊藤，ソフトウェア，西川)を(伊藤，ハードウェア，北川)に修正するだけでよく，西川先生がソフトウェアを教えているという事実は R<sub>2</sub> に保存されており，タップル修正時異状は発生しません．</p>
<p>&emsp;フォーマルに上記の議論をまとめておくと，次のようです．<br />
&emsp;分解的アプローチで得られた RDB については，次が成立しています．</p>
<p>&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;(∀R∈<b><span style="font-style: italic;">R</span></b>)(R=R) ∧ <b><span style="font-style: italic;">R</span></b>≡<b><span style="font-style: italic;">R</span></b>&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;・・・・・・・・・・・・・(3)</p>
<p>&emsp;一方，合成的アプローチで得られた RDB については，次が成立していいます．</p>
<p>&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;(∀R∈<b><span style="font-style: italic;">R</span></b>)( R=R<sub>1</sub>(<u>学生名</u>, <u>科目名</u>，教員名)*R<sub>2</sub>(<u>教員名</u>，科目名)) ∧<br />
&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;<b><span style="font-style: italic;">R</span></b>≡<b><span style="font-style: italic;">R</span></b><sub>1</sub>(<u>学生名</u>, <u>科目名</u>，教員名)*<b><span style="font-style: italic;">R</span></b><sub>2</sub>(<u>教員名</u>，科目名) &emsp;・・・・・(4)</p>
<p>&emsp;分解的アプローチ，合成的アプローチ，共に情報無損失分解とリレーションスキーマタの等価関係が肯定的に示されましたが，分解的アプローチでは <b><span style="font-style: italic;">R</span></b> が 3NF ではあるものの BCNF ではありませんでした．一方，合成的アプローチで得られた <b><span style="font-style: italic;">R</span></b><sub>1</sub> と <b><span style="font-style: italic;">R</span></b><sub>2</sub> は共に BCNF です．この差が，分解的アプローチで RDB を設計した場合に，更新時異状発生の原因となったわけです．</p>
<p>&emsp;さて，上に示した現象は，RDB を設計するに当たり，分解的アプローチを採るのか合成的アプローチを採るのかという意思決定に際して，関数従属性保存を保証するために必要となるリレーションを格納するために「メモリ」が増加するという視点に加えて，3NF ではあるが BCNF ではないために発生する「更新時異状」という視点も勘案したうえで，どちらのアプローチを採るかを決定しないといけないということを主張しているということで，この 2 軸を勘案すると，これまた少し乱暴な表現となりますが，その選択は次のようにまとめられると思います．<br />
&emsp;<b>選択 1</b> :（データを格納するための）メモリは食わないが，設計された RDB が関数従属性保存であ<br />
&emsp;&emsp;&emsp;&emsp; るという確約はなく，また，RDB を構成するリレーションスキーマが 3NF ではあるものの<br />
&emsp;&emsp;&emsp;&emsp; BCNF の確約はないので，そのことにより更新時異状が発生するかもしれないというリスク<br />
&emsp;&emsp;&emsp;&emsp; のある分解的アプローチ<br />
&emsp;<b>選択 2</b> : 分解的アプローチに比べれば一般にメモリを食うものの，設計された RDB が関数従属性保<br />
&emsp;&emsp;&emsp;&emsp; 存で，また，RDB を構成するリレーションスキーマが BCNF であるので，3NF ではあるが<br />
&emsp;&emsp;&emsp;&emsp; BCNF ではないことによる更新時異状は発生しないことが約束されている合成的アプローチ</p>
<h4>5. おわりに</h4>
<p>&emsp;本稿では，RDB 設計のための「分解的アプローチ」と「合成的アプローチ」を俎上に上げて<ruby>蘊蓄<rt style="background-color: #DDDDDD;">うんちく</rt></ruby>を傾けました．RDB 設計にあたり与えられたリレーションスキーマと指定された所与の関数従属性の集合が同一でも，分解的アプローチと合成的アプローチでは一般に RDB の設計結果は異なります．分解的アプローチは設計された RDB が「情報無損失分解・3NF」であることは保障してくれますが，一般には関数従属性保存は保証してくれません．一方，合成的アプローチは「情報無損失分解・3NF・関数従属性保存」という 3 拍子揃った RDB 設計を保証してくれます．加えて，合成的アプローチでは作られたリレーションスキーマは厳密には BCNF まで正規度が上がっているので，いわゆるリレーションが 3NF ではあるが BCNF ではないために発生してしまう更新時異状も回避することができます．ただ，合成的アプローチは関数従属性保存を担保する代償として，分解的アプローチに比べて格納するべきデータ量は多くなり，メモリを食うことになります．<br />
&emsp;さて，この二者択一，貴方ならどちらを選択しますか？</p>
<p>【文献】</p>
<p style="margin-top: -10px;" >[1]</p>
<table style="border:none; margin-top: -62px; margin-left: 20px; margin-bottom: -00px;" align="left" >
<tbody style="border:none;">
<td style="width: 800px; border:none;">
E.F. Codd. A Relational Model of Data for Large Shared Data Banks. Communications of the ACM, Vol.13, No.6, pp.377-387, 1970.
</td>
</tbody>
</table>
<p style="margin-top: -22px;" >[2]</p>
<table style="border:none; margin-top: -62px; margin-left: 20px; margin-bottom: -00px;" align="left" >
<tbody style="border:none;">
<td style="width: 800px; border:none;">
E.F. Codd. Further Normalization of the Data Base Relational Model. R. Rustin (Ed.), Data Base Systems (Courant Computer Science Symposia 6). Prentice-Hall, Englewood Cliffs, NJ, 1972.
</td>
</tbody>
</table>
<p style="margin-top: -22px;" >[3]</p>
<table style="border:none; margin-top: -62px; margin-left: 20px; margin-bottom: -00px;" align="left" >
<tbody style="border:none;">
<td style="width: 800px; border:none;">
増永良文．増永教授のDB特論⑤「3NF分解と関数従属性保存」，SRA OSS Tech Blog, 2022.05.11.<br />
https://www.sraoss.co.jp/tech-blog/db-special-lecture/masunaga-db-special-lecture-5/
</td>
</tbody>
</table>
<p style="margin-top: -22px;" >[4]</p>
<table style="border:none; margin-top: -62px; margin-left: 20px; margin-bottom: -00px;" align="left" >
<tbody style="border:none;">
<td style="width: 800px; border:none;">
P.A. Bernstein. Synthesizing Third Normal Form Relations from Functional Dependencies. ACM Transactions on Database Systems, Vol.1, No.4, pp.277-298, 1976.
</td>
</tbody>
</table>
<p style="margin-top: -22px;" >[5]</p>
<table style="border:none; margin-top: -62px; margin-left: 20px; margin-bottom: -00px;" align="left" >
<tbody style="border:none;">
<td style="width: 800px; border:none;">
増永良文．リレーショナルデータベース入門[第3版]．サイエンス社，2017．
</td>
</tbody>
</table>
<p style="margin-top: -22px;" >[6]</p>
<table style="border:none; margin-top: -62px; margin-left: 20px; margin-bottom: -00px;" align="left" >
<tbody style="border:none;">
<td style="width: 800px; border:none;">
M.W. Vincent and B. Srinivasan. A Note on Relational Schemes Which Are in 3NF But Not in BCNF. Information Processing Letters 48(6), pp. 281–283, 1993.
</td>
</tbody>
</table>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>増永教授のDB特論⑤「3NF 分解と関数従属性保存」</title>
		<link>https://www.sraoss.co.jp/tech-blog/db-special-lecture/masunaga-db-special-lecture-5/</link>
		
		<dc:creator><![CDATA[増永良文 (Yoshifumi Masunaga)]]></dc:creator>
		<pubDate>Wed, 11 May 2022 06:20:55 +0000</pubDate>
				<category><![CDATA[増永教授のDB特論]]></category>
		<category><![CDATA[3NF]]></category>
		<category><![CDATA[RDB]]></category>
		<category><![CDATA[リレーショナルデータベース]]></category>
		<guid isPermaLink="false">https://www.sraoss.co.jp/tech-blog/?p=9814</guid>

					<description><![CDATA[1. はじめに &#8195;リレーショナルデータベース（RDB）を設計するにあたり，「リレーションは第 3 正規形（3NF）にしましょう」とはよく言われることです．リレーションの正規化理論によると，3NF への分解が情報 ...]]></description>
										<content:encoded><![CDATA[<h4>1. はじめに</h4>
<p style="margin-top: -10px;">
&emsp;リレーショナルデータベース（RDB）を設計するにあたり，「リレーションは第 3 正規形（3NF）にしましょう」とはよく言われることです．リレーションの正規化理論によると，3NF への分解が情報無損失であることは間違いのないことですが，その際，関数従属性は保存されるのか，されないのか？このことについて，どうも不確かな認識が流布しているのではないか？と思われる事例に遭遇したので，この記事を書く気になりました．</p>
<p><span id="more-9814"></span><br />
&emsp;その事例とは，何気なく過去の「データベーススペシャリスト試験問題」を眺めていた時に目に留まった次の設問と解答です．</p>
<p><center><u>平成 26 年度 春季 データベーススペシャリスト試験 午前Ⅱ 問題</u> [1]</center></p>
<p style="margin-top: -10px;" >　問 4</p>
<table style="border:none; margin-top: -62px; margin-left: 40px; margin-bottom: -00px;" align="left" >
<tbody style="border:none;">
<td style="width: 800px; border:none;">
&emsp;関係モデルにおいて，情報無損失分解ができ，かつ，関数従属性保存が成り立つ変換が必ず存在するものはどれか。ここで，情報無損失分解とは自然結合によって元の関係が必ず得られる分解をいう。
</td>
</tbody>
</table>
<p>&emsp;&emsp;ア　第 2 正規形から第 3 正規形への変換<br />
&emsp;&emsp;イ　第 3 正規形からボイスコッド正規形への変換<br />
&emsp;&emsp;ウ　非正規形から第 1 正規形への変換<br />
&emsp;&emsp;エ　ボイスコッド正規形から第 4 正規形への変換</p>
<p>&emsp;この問題の正解は「ア」とされています[2]．</p>
<p>&emsp;さて，この設問と正解を眺めていて釈然としない点が 2 つありました．<br />
&emsp;一つは，情報無損失分解の定義は与えられていますが，「関数従属性保存」の定義が与えられていません．果たして，どういう意味でこの用語を使っているのでしょうか？<br />
&emsp;もう一つは，「情報無損失分解ができ，かつ，関数従属性保存が成り立つ変換が<strong>必ず</strong>存在するもの」を問うていますが，「必ず」とは一体どのような意味で使っているのでしょうか？「ア」を正解とするということなので，「リレーションの第 2 正規形から第 3 正規形への変換は必ず情報無損失分解かつ関数従属性保存である」が出題者の意図ではないかと推察されますが，本当にそうなのでしょうか？<br />
&emsp;そこで，本稿では，この問題を少しばかり深堀してみることとしました．</p>
<h4>2. 基礎的事項</h4>
<p style="margin-top: -10px;">
&emsp;議論を進めるために必要な概念を整理しておきます．<br />
<strong>【定義 1】</strong>（リレーションスキーマとリレーション）<br />
&emsp;リレーションスキーマ <b><span style="font-style: italic;">R</span></b> とはリレーション名 R と属性のリスト A<sub>1</sub>, A<sub>2</sub>, <sub>…</sub>, A<sub>n</sub> からなり，<b><span style="font-style: italic;">R</span></b>(A<sub>1</sub>, A<sub>2</sub>, <sub>…</sub>, A<sub>n</sub>) と表される．dom をドメイン関数とするとき，R⊆dom(A<sub>1</sub>)×dom(A<sub>2</sub>)×<sub>…</sub>×dom(A<sub>n</sub>) をリレーションスキーマ <b><span style="font-style: italic;">R</span></b> のインスタンス，あるいは dom(A<sub>1</sub>)，dom(A<sub>2</sub>)，<sub>…</sub>，dom(A<sub>n</sub>) 上のリレーション R という．<br />
&emsp;リレーションスキーマ <b><span style="font-style: italic;">R</span></b> である性質 <span style="font-style: italic;">P</span> が成立するとは <b><span style="font-style: italic;">R</span></b> のすべてのインスタンス R で <span style="font-style: italic;">P</span> が成立するときおよびその時のみをいう．</P><br />
<strong>【定義 2】</strong>（関数従属性）<br />
&emsp;リレーションスキーマ <b><span style="font-style: italic;">R</span></b> で関数従属性（functional dependency, FD） f=X→Yが成立するとは，次が成立するときをいう．ここに，R∈<b><span style="font-style: italic;">R</span></b> は R が <b><span style="font-style: italic;">R</span></b> のインスタンスであることを表す．<br />
&emsp;&emsp;&emsp;&emsp;(∀R∈<b><span style="font-style: italic;">R</span></b>)(∀t, t<sup>’</sup>∈R)(t[X]=t<sup>&#8216;</sup>[X]⇒t[Y]=t<sup>&#8216;</sup>[Y])</p>
<p><strong>【定義 3】</strong>（所与の関数従属性集合）<br />
&emsp;リレーションスキーマ <b><span style="font-style: italic;">R</span></b> に所与の（given）関数従属性の集合 <span style="font-style: italic;">F</span>＝{f<sub>1</sub>, f<sub>2</sub>, <sub>…</sub>, f<sub>p</sub>}，ここに(∀i= 1, 2, …, p)(f<sub>i</sub>=X<sub>i</sub>→Y<sub>i</sub> ∧ X<sub>i</sub>, Y<sub>i</sub>⊆Ω<sub><b><span style="font-style: italic;">R</span></b></sub>)，を指定できる．ここで，Ω<sub><b><span style="font-style: italic;">R</span></b></sub> は <b><span style="font-style: italic;">R</span></b> の全属性集合 {A<sub>1</sub>, A<sub>2</sub>, <sub>…</sub>, A<sub>n</sub>} を表し，一般に X, Y を集合とするとき，X⊆Y は X が Y の部分集合であることを，X⊂Y は X が Y の真部分集合（proper subset）であることを表す．</p>
<p><strong>【定義 4】</strong>（関数従属性集合の閉包）<br />
&emsp;リレーションスキーマ <b><span style="font-style: italic;">R</span></b> に所与の関数従属性の集合 <span style="font-style: italic;">F</span> が指定されているとする．このとき， <b>F の閉包 <span style="font-style: italic;">F<sup>+</sup></span></b> は次のように定義される．ここに，<span style="font-style: italic;">F</span> ⊨ X→Y は X→Y がアームストロングの公理系のもとで <span style="font-style: italic;">F</span> から導出されることを表す．<br />
&emsp;&emsp;&emsp;&emsp;<span style="font-style: italic;">F</span><sup>+</sup>={X→Y | X, Y⊆Ω<sub><b><span style="font-style: italic;">R</span></b></sub> ∧ <span style="font-style: italic;">F</span> ⊨ X→Y}</p>
<p>&emsp;つまり，<span style="font-style: italic;">F</span><sup>+</sup> は <span style="font-style: italic;">F</span> が与えられたとき， <span style="font-style: italic;">F</span> を基にして <b><span style="font-style: italic;">R</span></b> 上で成立するすべての FD からなる集合を表します．<span style="font-style: italic;">F</span><sup>+</sup> を求めるアルゴリズムを示しますが，その前に，次が成立することに注目します．ここに，　X<sup>+</sup> は <span style="font-style: italic;">F</span> に関する X の閉包を表し，iff は if and only if，すなわち必要かつ十分条件を表します．<br />
&emsp;&emsp;&emsp;&emsp;(∀X, Y⊆Ω<sub><b><span style="font-style: italic;">R</span></b></sub>)(X→Y∈<span style="font-style: italic;">F</span><sup>+</sup> iff Y⊆X<sup>+</sup>)</p>
<p>&emsp;なお，X<sup>+</sup> を求めるアルゴリズムは次のとおりです．このアルゴリズムの時間計算量は多項式時間であり，扱いやすい（tractable）問題です．</p>
<p><strong>【X<sup>+</sup> を求めるアルゴリズム】</strong><br />
&emsp;1． X<sup>(0)</sup>=Xとおく．<br />
&emsp;2． X<sup>(i)</sup>= X<sup>(i－1)</sup>∪{A|A∈Z ∧ Y→Z∈F ∧ Y⊆X<sup>(i－1)</sup>} (i≧1)とする．<br />
&emsp;3． もし，X<sup>(i)</sup>= X<sup>(i－1)</sup> ならX<sup>+</sup>= X<sup>(i－1)</sup> とおく．そうでなければステップ 2 にいく．</p>
<p><strong>【例題1】</strong><br />
&emsp;リレーションスキーマ <b><span style="font-style: italic;">R</span></b>(A, B, C) に所与の FD 集合 <span style="font-style: italic;">F</span>={A→B, B→C}が指定されているとする．たとえば，X={A} としてX<sup>+</sup> を求めると，ステップ 1 で X<sup>(0)</sup>={A}, ステップ 2 と 3 を繰り返して，X<sup>(1)</sup>= X<sup>(0)</sup>∪{B}, X<sup>(2)</sup>= X<sup>(1)</sup>∪{C} (={A, B, C}), X<sup>(3)</sup>= X<sup>(2)</sup> となり, X<sup>+</sup>={A, B, C}を得る．</p>
<p>&emsp;さて，<span style="font-style: italic;">F</span><sup>+</sup> を求めるアルゴリズムは次のとおりです．</p>
<p><strong>【<span style="font-style: italic;">F</span><sup>+</sup> を求めるアルゴリズム】</strong><br />
&emsp;1． <span style="font-style: italic;">F</span><sup>+</sup>=Φ とおく．<br />
&emsp;2． 2<sup>ΩR</sup>－Φ の各元 X に対してその閉包 X<sup>+</sup>を求め，<span style="font-style: italic;">F</span><sup>+</sup> = <span style="font-style: italic;">F</span><sup>+</sup>∪{X→X<sup>+</sup>} とする．<br />
&emsp;3． ステップ 2 の操作が全て終了すれば，その時の <span style="font-style: italic;">F</span><sup>+</sup> が求める結果である．</p>
<p>&emsp;ステップ 2 で，2<sup>ΩR</sup>－Φ の各元 X に対してその閉包 X<sup>＋</sup> を求めていることから明らかなように，このアルゴリズムの時間計算量は <span style="font-style: italic;">O</span>(2<sup>|ΩR|</sup>)，ここに <span style="font-style: italic;">O</span> はオーダー関数，|Ω<sub><b><span style="font-style: italic;">R</span></b></sub> |は Ω<sub><b><span style="font-style: italic;">R</span></b></sub> の濃度を表す，と指数時間となり，扱いにくい（intractable）問題であることが分かります．つまり，上記のアルゴリズムは|Ω<sub><b><span style="font-style: italic;">R</span></b></sub> |が小さいときは問題なく動きますが，それが大きくなるにつれてとんでもない時間を要することになります．<br />
&emsp;なお，リレーションの情報無損失分解に係る関数従属性保存を論じるためには，<span style="font-style: italic;">F</span><sup>+</sup> の属性集合Z（⊆Ω<sub><b><span style="font-style: italic;">R</span></b></sub>）上の射影 <span style="font-style: italic;">F</span><sup>+</sup>[Z] を定義する必要がありますが（定義 5），それを端的に行うためにはステップ 3 をステップ 3’ に置き換えておくと都合がよいのでそのようにします（射影と関わらない議論はステップ 3 で得られた <span style="font-style: italic;">F</span><sup>+</sup> を念頭に置いて行っています）．<br />
&emsp;3&#8217;． ステップ 2 の操作が全て終了すれば，その時の <span style="font-style: italic;">F</span><sup>+</sup> が求める結果であるが，もし<br />
&emsp;&emsp;&emsp;<span style="font-style: italic;">F</span><sup>+</sup> の元 X→X<sup>+</sup> の被決定子が X<sup>+</sup>=A<sub>1</sub>A<sub>2</sub><sub>…</sub>A<sub>q</sub>（A<sub>i</sub>∈Ω<sub><b><span style="font-style: italic;">R</span></b></sub>, q≧2）のように単一の属性で<br />
&emsp;&emsp;&emsp;でなければ，X→X<sup>+</sup> をX→A<sub>1</sub>, X→A<sub>2</sub>, …, X→A<sub>q</sub>置き換えた <span style="font-style: italic;">F</span><sup>+</sup> を求める結果とする<br />
&emsp;&emsp;&emsp;（この置換えは，X→YZ iff X→Y ∧ X→Z が成立することによる）．<br />
&emsp;&emsp;&emsp;ここに，一般に A<sub>1</sub>A<sub>2</sub><sub>…</sub>A<sub>q</sub> は集合{A<sub>1</sub>, A<sub>2</sub>, <sub>…</sub> , A<sub>q</sub>} の簡略表現とする（以下，同様）．<br />
&emsp;&emsp;&emsp;したがって，たとえば AB={A, B}={B, A}=BA である．</p>
<p><strong>【例題2】</strong><br />
&emsp;リレーションスキーマ <b><span style="font-style: italic;">R</span></b>(A, B, C)に所与の FD 集合 <span style="font-style: italic;">F</span>={A→B, B→C} が指定されているとする．このとき，<span style="font-style: italic;">F</span><sup>+</sup> を求めると，2<sup>ΩR</sup>={Φ, A, B, C, AB, AC, BC, ABC} であるので，ステップ 1 で <span style="font-style: italic;">F</span><sup>+</sup>=Φ，ステップ 2 と 3 を繰り返して，A<sup>+</sup>=ABC, B<sup>+</sup>=BC, C<sup>+</sup>=C, AB<sup>+</sup>=ABC, AC<sup>+</sup>=ABC, BC<sup>+</sup>=BC, ABC<sup>+</sup>=ABC なので，ステップ 3 で <span style="font-style: italic;">F</span><sup>+</sup> は次のようになる．<br />
&emsp;<span style="font-style: italic;">F</span><sup>+</sup>={A→ABC, B→BC, C→C, AB→ABC, AC→ABC, BC→BC, ABC→ABC}<br />
<span style="font-style: italic;">F</span><sup>+</sup>をステップ 3 ではなくステップ 3’ を用いて求めた場合，それは次のようになる．<br />
&emsp;<span style="font-style: italic;">F</span><sup>+</sup>={A→A, A→B, A→C, B→B, B→C, C→C, AB→A, AB→B, AB→C, AC→A,<br />
&emsp;&emsp;&emsp;AC→B, AC→C, BC→B, BC→C, ABC→A, ABC→B, ABC→C}<br />
なお，一般に <span style="font-style: italic;">F</span><sup>+</sup> には A→A や AB→A など自明な FD も含まれているが，<span style="font-style: italic;">F</span><sup>+</sup> はそれらも含めて <b><span style="font-style: italic;">R</span></b> 上で成り立つ関数従属性の全てからなる集合を表しているということである．</p>
<p><strong>【定義5】</strong>（関数従属性集合の閉包の射影）<br />
&emsp;リレーションスキーマ <b><span style="font-style: italic;">R</span></b> に所与の関数従属性の集合 <span style="font-style: italic;">F</span> が指定されているとする．このとき，一般に Z⊆Ω<sub><b><span style="font-style: italic;">R</span></b></sub> として，<strong><span style="font-style: italic;">F</span><sup>+</sup> の Z 上の射影 <span style="font-style: italic;">F</span><sup>+</sup>[Z]</strong>は次のように定義される．ここに <span style="font-style: italic;">F</span><sup>+</sup> はステップ 3’ を用いて求められており，A∈Ω<b><sub><span style="font-style: italic;">R</span></sub></b> である．<br />
&emsp;&emsp;&emsp;<strong><span style="font-style: italic;">F</span><sup>+</sup>[Z]</strong>={X→A|X→A∈<span style="font-style: italic;">F</span><sup>+</sup> ∧ X∪A⊆Z}</p>
<p><strong>【例題3】</strong><br />
&emsp;リレーションスキーマ <b><span style="font-style: italic;">R</span></b>(A, B, C)に所与の FD 集合 <span style="font-style: italic;">F</span>={A→B, B→C} が指定されているとする．このとき，<span style="font-style: italic;">F</span><sup>+</sup> の {B, C} 上の射影，<span style="font-style: italic;">F</span><sup>+</sup>[B, C] は次のようになる．<br />
&emsp;<span style="font-style: italic;">F</span><sup>+</sup>[B, C]= {B→B, B→C, C→C, BC→B, BC→C }</p>
<p>&emsp;なお，B, C∈Ω<b><sub><span style="font-style: italic;">R</span></sub></b> としたとき，<span style="font-style: italic;">F</span><sup>+</sup>[B, C]は本来は <span style="font-style: italic;">F</span><sup>+</sup>[{B, C}]あるいは <span style="font-style: italic;">F</span><sup>+</sup>[BC]と書くべきであるが，慣習的に <span style="font-style: italic;">F</span><sup>+</sup>[B, C]と書くことも多く，本稿でもそれに倣っている．</p>
<p><strong>【定義6】</strong>（リレーションスキーマの情報無損失分解）<br />
&emsp;リレーションスキーマ <b><span style="font-style: italic;">R</span></b> の情報無損失分解は <span style="font-style: italic;">F</span><sup>+</sup> の元 X→Y （X，Y⊆Ω<sub><span style="font-style: italic;">R</span></sub></b>）を使って <b><span style="font-style: italic;">R</span></b> を 2 つの射影 <b><span style="font-style: italic;">R</span></b>[X∪Y]と <b><span style="font-style: italic;">R</span></b>[Ω<b><sub><span style="font-style: italic;">R</span></sub></b>－Y]，ここに － は差集合演算を表す，に分解することをいう．</p>
<p>&emsp;FD による分解はリレーションスキーマが 2 つの射影に情報無損失分解されるための十分条件なので，この分解は情報無損失，すなわち <b><span style="font-style: italic;">R</span></b>=<b><span style="font-style: italic;">R</span></b>[X∪Y]*<b><span style="font-style: italic;">R</span></b>[Ω<b><sub><span style="font-style: italic;">R</span></sub></b>－Y]が成立することは改めて言うまでもないことです．ここに * は自然結合演算を表しています．</p>
<p>&emsp;ここで，念のためにリレーションスキーマが第 2 正規形（2NF），第 3 正規形（3NF）そしてボイス‐コッド正規形（BCNF）であることの定義を確認しておきます．「リレーションスキーマ <b><span style="font-style: italic;">R</span></b> が第 2 正規形（2NF）であるとは，<b><span style="font-style: italic;">R</span></b> は 1NF であって，<b><span style="font-style: italic;">R</span></b> の全ての非キー属性は <b><span style="font-style: italic;">R</span></b> の各候補キーに完全関数従属している」こと，「リレーションスキーマ <b><span style="font-style: italic;">R</span></b> が第 3 正規形（3NF）であるとは，<b><span style="font-style: italic;">R</span></b> は 2NF であって，<b><span style="font-style: italic;">R</span></b> の全ての非キー属性は <b><span style="font-style: italic;">R</span></b> のいかなる候補キーにも推移的に関数従属しない」こと，そして，リレーションスキーマ <b><span style="font-style: italic;">R</span></b> がボイス‐コッド正規形（BCNF）であるとは，「X→Yを <b><span style="font-style: italic;">R</span></b> の関数従属性とするとき，X→Y は自明な FD であるか，あるいは X は <b><span style="font-style: italic;">R</span></b> のスーパーキーである」ことです．<br />
&emsp;なお，リレーショナルデータモデルと正規化理論の原典に立ち戻って RDB 設計の分解的手法を今一度整理しておきたい向きには文献[3, 4]を，本稿では立ち入らないが分解的手法と対極をなす RDB 設計の合成的手法の原典にあたりたい向きには文献[5]を，そしてそれらをカバーした書籍として拙著[6]を薦めます．</p>
<h4>3. 関数従属性保存とは</h4>
<p style="margin-top: -10px;">
&emsp;まず，リレーションスキーマの情報無損失分解に係る関数従属性保存の定義を与えます．<br />
<strong>【定義7】</strong>(関数従属性保存)<br />
&emsp;リレーションスキーマ <b><span style="font-style: italic;">R</span></b> に所与の関数従属性の集合 <span style="font-style: italic;">F</span> が指定されているとする．X→Y∈<span style="font-style: italic;">F</span><sup>+</sup> として，X→Y による <b><span style="font-style: italic;">R</span></b> の <b><span style="font-style: italic;">R</span></b>[X∪Y] と <b><span style="font-style: italic;">R</span></b>[Ω<b><sub><span style="font-style: italic;">R</span></sub></b>－Y]への情報無損失分解が関数従属性保存とは，次が成立するときをいう．<br />
&emsp;&emsp;&emsp;(<span style="font-style: italic;">F</span><sup>+</sup>[X∪Y]∪<span style="font-style: italic;">F</span><sup>+</sup>[Ω<b><sub><span style="font-style: italic;">R</span></sub></b>－Y])<sup>+</sup>=<span style="font-style: italic;">F</span><sup>+</sup></p>
<p>&emsp;つまり，<span style="font-style: italic;">F</span> の閉包 <span style="font-style: italic;">F</span><sup>+</sup> の X∪Y 上の射影 <span style="font-style: italic;">F</span><sup>+</sup>[X∪Y] とその Ω<b><sub><span style="font-style: italic;">R</span></sub></b>－Y 上の射影 <span style="font-style: italic;">F</span><sup>+</sup>[Ω<b><sub><span style="font-style: italic;">R</span></sub></b>－Y]の和集合の閉包 (<span style="font-style: italic;">F</span><sup>+</sup>[X∪Y]∪<span style="font-style: italic;">F</span><sup>+</sup>[Ω<b><sub><span style="font-style: italic;">R</span></sub></b>－Y])<sup>+</sup> が <span style="font-style: italic;">F</span><sup>+</sup> と等しいかどうかを問うていて，両者が等しいときに，関数従属性保存と言います．決して <span style="font-style: italic;">F</span>[X∪Y]∪<span style="font-style: italic;">F</span>[Ω<b><sub><span style="font-style: italic;">R</span></sub></b>－Y]=<span style="font-style: italic;">F</span> を問うているわけではないことに注意してください．あくまで，閉包レベルの概念です．</p>
<p>&emsp;なお，一般にリレーションスキーマ <b><span style="font-style: italic;">R</span></b> を X→Y で<b><span style="font-style: italic;">R</span></b>[X∪Y]と <b><span style="font-style: italic;">R</span></b>[Ω<b><sub><span style="font-style: italic;">R</span></sub></b>－Y]へ情報無損失分解したとき，もし <b><span style="font-style: italic;">R</span></b>[Ω<b><sub><span style="font-style: italic;">R</span></sub></b>－Y]に Z→W∈<span style="font-style: italic;">F</span><sup>+</sup>（ここに，Z∪W⊂Ω<b><sub><span style="font-style: italic;">R</span></sub></b>－Y）が存在していると，<b><span style="font-style: italic;">R</span></b>[Ω<b><sub><span style="font-style: italic;">R</span></sub></b>－Y]は <b><span style="font-style: italic;">R</span></b>[Z∪W]と <b><span style="font-style: italic;">R</span></b>[Ω<b><sub><span style="font-style: italic;">R</span></sub></b>－Y－W]へ情報無損失分解可能で，結果として <b><span style="font-style: italic;">R</span></b> は <b><span style="font-style: italic;">R</span></b>[X∪Y]と <b><span style="font-style: italic;">R</span></b>[Z∪W]と <b><span style="font-style: italic;">R</span></b>[Ω<b><sub><span style="font-style: italic;">R</span></sub></b>－Y－W]に情報無損失分解できます．このとき，上記の関数従属性保存の定義は素直に次のように拡張されます（この拡張はより一般的な形で可能です）．<br />
&emsp;&emsp;&emsp;(<span style="font-style: italic;">F</span><sup>+</sup>[X∪Y]∪<span style="font-style: italic;">F</span><sup>+</sup>[Z∪W]∪<span style="font-style: italic;">F</span><sup>+</sup>[Ω<b><sub><span style="font-style: italic;">R</span></sub></b>－Y－W])<sup>+</sup>=<span style="font-style: italic;">F</span><sup>+</sup></p>
<p>&emsp;以上で準備は整いました．ここからは 2NF ではあるが 3NF ではないリレーションスキーマの 3NF への情報無損失分解が関数従属性保存か否かを検証していきます．3 つのパターンが示されますが，それらの結果は大変興味深いものです．</p>
<h4>4. 3NF 分解が関数従属性保存である例</h4>
<p style="margin-top: -10px;">
<strong>【例題4】</strong><br />
&emsp;リレーションスキーマ <b><span style="font-style: italic;">R</span></b>(A, B, C) に所与の FD 集合 <span style="font-style: italic;">F</span>={A→B, B→C} が指定されているとする．このとき，<b><span style="font-style: italic;">R</span></b> は 2NF ではあるが 3NF ではない．<b><span style="font-style: italic;">R</span></b> の 3NF への情報無損失分解が関数従属性保存であるかどうかを検証してみよ．なお，図 1 に本例題での所与の FD 集合の様子を示す．<br />
<strong>(解答)</strong><br />
&emsp;例題 2 で示したように，<span style="font-style: italic;">F</span><sup>+</sup>={A→A, A→B, A→C, B→B, B→C, C→C, AB→A, AB→B, AB→C, AC→A, AC→B, AC→C, BC→B, BC→C, ABC→A, ABC→B, ABC→C} である．<br />
&emsp;まず，確認すれば <b><span style="font-style: italic;">R</span></b> は 2NF ではあるが 3NF ではない．なぜならば，推移的関数従属性 A→B→C が存在するからである．そこで，A→B→C の解消を図るため，B→C を用いて，<b><span style="font-style: italic;">R</span></b> を <b><span style="font-style: italic;">R</span></b>[B, C]と <b><span style="font-style: italic;">R</span></b>[A, B] に情報無損失分解する．このとき，<span style="font-style: italic;">F</span><sup>+</sup>[B, C]= {B→B, B→C, C→C, BC→B, BC→C}，<span style="font-style: italic;">F</span><sup>+</sup>[A, B]= {A→A, A→B, B→B, AB→A, AB→B}となる．<br />
&emsp;さて，<span style="font-style: italic;">G</span>=<span style="font-style: italic;">F</span><sup>+</sup>[B, C]∪<span style="font-style: italic;">F</span><sup>+</sup>[A, B]と置いて，<span style="font-style: italic;">F</span><sup>+</sup>と <span style="font-style: italic;">G</span> の元を見比べてみると，<span style="font-style: italic;">F</span><sup>+</sup> の元 A→C，AB→C，　AC→A，AC→B，AC→C，ABC→A，ABC→B，ABC→C が <span style="font-style: italic;">G</span> に入っていない．そこで，これらの元で自明でないA→C，AB→C， AC→B について，それらが <span style="font-style: italic;">G</span><sup>+</sup> の元であるかどうかを検証する．<br />
&emsp;まず，A→C は，(A→B∈<span style="font-style: italic;">F</span><sup>+</sup>[A, B])∧(B→C∈<span style="font-style: italic;">F</span><sup>+</sup>[B, C])なので，アームストロングの公理系の推移律から A→C∈<span style="font-style: italic;">G</span><sup>+</sup> であることが分かる（つまり，<span style="font-style: italic;">G</span> ⊨ A→C である）．AB→C は，(AB→B∈<span style="font-style: italic;">F</span><sup>+</sup>[A, B])　∧(B→C∈<span style="font-style: italic;">F</span><sup>+</sup>[B, C])なので，アームストロングの公理系の推移律から AB→C∈<span style="font-style: italic;">G</span><sup>+</sup> であることが分かる（<span style="font-style: italic;">G</span> ⊨ AB→C）．AC→B については，A→B∈<span style="font-style: italic;">F</span><sup>+</sup>[A, B]なので，アームストロングの公理系の添加律から AC→BC で，BC→B∈<span style="font-style: italic;">F</span><sup>+</sup>[B, C] なので，アームストロングの公理系の推移律から AC→B∈<span style="font-style: italic;">G</span><sup>+</sup> であることが分かる（<span style="font-style: italic;">G</span> ⊨ AC→B）．したがって，<span style="font-style: italic;">G</span><sup>+</sup>=<span style="font-style: italic;">F</span><sup>+</sup> となり，<u>この情報無損失分解は関数従属性保存で<strong>ある</strong></u>．</p>
<p><center><img decoding="async" src="https://www.sraoss.co.jp/tech-blog/wp-content/uploads/2022/05/drmasunaga-pic-01.png" alt="SQL code" style="margin-top: -22px; width: 300px" /></center><br />
<center>図1　リレーションスキーマ <b><span style="font-style: italic;">R</span></b>(A, B, C) に所与の FD 集合（例題4）</center></p>
<p>&emsp;前述の平成 26 年度 春季 データベーススペシャリスト試験 午前Ⅱ 問題 問 4 が（ア）を正解としたのは，例題 4 のような状況を想定しての設問だったのかもしれませんが，そのような但し書きは一切ありません，しかしながら，3NF 分解と関数従属性保存の関係性は常にこのように単純というわけではなく，以下に見るように，その出題意図に反した例を多々示すことができます．</p>
<h4>5. いかなる 3NF 分解も関数従属性保存でない例</h4>
<p style="margin-top: -10px;">
<strong>【例題5】</strong><br />
&emsp;リレーションスキーマ <b><span style="font-style: italic;">R</span></b>(A, B, C, D) に所与の FD 集合 <span style="font-style: italic;">F</span>={A→B, B→C, A→D, D→C} が指定されているとする．このとき，<b><span style="font-style: italic;">R</span></b> は 2NF ではあるが 3NF ではない．<b><span style="font-style: italic;">R</span></b> の 3NF への情報無損失分解が関数従属性保存であるかどうかを検証してみよ．なお，図 2 に本例題での所与の FD 集合の様子を示す．<br />
<strong>(解答)</strong><br />
&emsp;このとき，A<sup>+</sup>=ABCD, B<sup>+</sup>=BC, C<sup>+</sup>=C, D<sup>+</sup>=CD, AB<sup>+</sup>=AC<sup>+</sup>=AD<sup>+</sup>=ABCD, BC<sup>+</sup>=BC, BD<sup>+</sup>=BCD, CD<sup>+</sup>=CD, ABC<sup>+</sup>=ABD<sup>+</sup>=ACD<sup>+</sup>=ABCD, BCD<sup>+</sup>=BCD, ABCD<sup>+</sup>=ABCD なので，<span style="font-style: italic;">F</span><sup>+</sup>={A→A, A→B, A→C, A→D, B→B, B→C, C→C, D→C, D→D, AB→A, AB→B, AB→C, AB→D, AC→A, AC→B, AC→C, AC→D, AD→A, AD→B, AD→C, AD→D, BC→B, BC→C, BD→B, BD→C, BD→D, CD→C, CD→D, ABC→A, ABC→B, ABC→C, ABC→D, ABD→A, ABD→B, ABD→C, ABD→D, ACD→A, ACD→B, ACD→C, ACD→D, BCD→B, BCD→C, BCD→D, ABCD→A, ABCD→B, ABCD→C, ABCD→D}となる．<b><span style="font-style: italic;">R</span></b> の候補キーはAのみなので 2NF である．一方，<b><span style="font-style: italic;">R</span></b> にはA→B→C，A→D→Cという 2 つの推移的関数従属性が存在し 3NF ではないので <b><span style="font-style: italic;">R</span></b> を情報無損失分解する．</p>
<p><strong>(場合1) A→B→C の解消を図る．</strong><br />
&emsp;<b><span style="font-style: italic;">R</span></b> を A→B→C を構成する B→C を使って <b><span style="font-style: italic;">R</span></b>[B, C] と <b><span style="font-style: italic;">R</span></b>[A, B, D]に情報無損失分解すると，次が成立する．このときは <b><span style="font-style: italic;">R</span></b>[A, B, D] も 3NF となっている．<br />
&emsp;<span style="font-style: italic;">F</span><sup>+</sup>[B, C]= {B→B, B→C, C→C, BC→B, BC→C}<br />
&emsp;<span style="font-style: italic;">F</span><sup>+</sup>[A, B, D]= {A→A, A→B, A→D, B→B, D→D, AB→A, AB→B, AB→D, AD→A, AD→B, AD→D, BD→B, BD→D, ABD→A, ABD→B, ABD→D}<br />
&emsp;そこで，<span style="font-style: italic;">G</span>=<span style="font-style: italic;">F</span><sup>+</sup>[B, C]∪<span style="font-style: italic;">F</span><sup>+</sup>[A, B, D] と置き，<span style="font-style: italic;">G</span><sup>+</sup>=<span style="font-style: italic;">F</span><sup>+</sup> かどうかを検証する．<span style="font-style: italic;">F</span><sup>+</sup> と <span style="font-style: italic;">G</span> の元を見比べてみると， <span style="font-style: italic;">F</span><sup>+</sup> の元 A→C, D→C, AB→C, AC→A, AC→B, AC→C, AC→D, AD→C, BD→C, CD→C, CD→D, ABC→A, ABC→B, ABC→C, ABC→D, ABD→C, ACD→A, ACD→B, ACD→C, ACD→D, BCD→B, BCD→C, BCD→D, ABCD→A, ABCD→B, ABCD→C, ABCD→D が <span style="font-style: italic;">G</span> に入っていない．これらの中の自明でない FD である A→C, D→C, AB→C, AC→B, AC→D, AD→C, BD→C, ABC→D, ACD→B が <span style="font-style: italic;">G</span><sup>+</sup> の元か否かを検証すると，D→C が <span style="font-style: italic;">G</span> の下では導出されないことが分かる（￢(<span style="font-style: italic;">G</span> ⊨ D→C)，ここに￢は否定を表す）．したがって，<u>この情報無損失分解は関数従属性保存では<strong>ない</strong></u>．</p>
<p><strong>(場合2) A→D→C の解消を図る．</strong><br />
&emsp;<b><span style="font-style: italic;">R</span></b> を A→D→C を構成する D→C を使って <b><span style="font-style: italic;">R</span></b>[D, C] と <b><span style="font-style: italic;">R</span></b>[A, B, D] に情報無損失分解したときには，(場合1)と同様な展開で B→C が保存されず，<u>この情報無損失分解も関数従属性保存ではない<strong>ない</strong></u>．</p>
<p>&emsp;つまり，リレーションスキーマ <b><span style="font-style: italic;">R</span></b>(A, B, C, D) に所与の FD 集合 <span style="font-style: italic;">F</span>={A→B, B→C, A→D, D→C} が指定されているとき，<b><span style="font-style: italic;">R</span></b> を 3NF に正規化しようとする<u>何れの情報無損失分解も関数従属性保存ではない</u>ことが示されました．これが，前述の午前 Ⅱ 問題 問 4 とその正解を(ア)とする解答への端的な反証となります．</p>
<p><center><img decoding="async" src="https://www.sraoss.co.jp/tech-blog/wp-content/uploads/2022/05/drmasunaga-pic-02.png" alt="SQL code" style="margin-top: -22px; width: 300px" /></center><br />
<center>図2　リレーションスキーマ <b><span style="font-style: italic;">R</span></b>(A, B, C, D) に所与の FD 集合（例題5）</center></p>
<h4>6. 3NF 分解が関数従属性保存となるか否かが，場合による 3 例</h4>
<p style="margin-top: -10px;">
<strong>【例題6】</strong><br />
&emsp;リレーションスキーマ <b><span style="font-style: italic;">R</span></b>(A, B, C, D)に所与の FD 集合 <span style="font-style: italic;">F</span>={A→B, B→C, C→D} が指定されているとする．このとき，<b><span style="font-style: italic;">R</span></b> は 2NF ではあるが 3NF ではない．<b><span style="font-style: italic;">R</span></b> の 3NF への情報無損失分解が関数従属性保存であるかどうかを検証してみよ．なお，図 3 に本例題での所与の FD 集合の様子を示す．<br />
<strong>(解答)</strong><br />
&emsp;このとき，<span style="font-style: italic;">F</span><sup>+</sup>={A→A, A→B, A→C, A→D, B→B, B→C, B→D, C→C, C→D, D→D, AB→A, AB→B, AB→C, AB→D, AC→A, AC→B, AC→C, AC→D, AD→A, AD→B, AD→C, AD→D, BC→B, BC→C, BC→D, BD→B, BD→C, BD→D, CD→C, CD→D, ABC→A, ABC→B, ABC→C, ABC→D, ABD→A, ABD→B, ABD→C, ABD→D, ACD→A, ACD→B, ACD→C, ACD→D, BCD→B, BCD→C, BCD→D, ABCD→A, ABCD→B, ABCD→C, ABCD→D}<br />
&emsp;<b><span style="font-style: italic;">R</span></b> の候補キーは A のみなので 2NF である．一方，<b><span style="font-style: italic;">R</span></b> には A→B→C，A→B→D，B→C→D，A→C→D という 4 つの推移的関数従属性が存在し 3NF ではないので <b><span style="font-style: italic;">R</span></b> を情報無損失分解する．</p>
<p><strong>(場合1) A→B→C の解消を図る．</strong><br />
&emsp;<b><span style="font-style: italic;">R</span></b> を A→B→C を構成する B→C を使って <b><span style="font-style: italic;">R</span></b>[B, C] と <b><span style="font-style: italic;">R</span></b>[A, B, D] に情報無損失分解すると，A→B→D により，<b><span style="font-style: italic;">R</span></b>[A, B, D] も 3NF ではないので，それを B→D を使って <b><span style="font-style: italic;">R</span></b>[B, D] と <b><span style="font-style: italic;">R</span></b>[A, B]に情報無損失分解すると次が成立する．<br />
&emsp;<span style="font-style: italic;">F</span><sup>+</sup>[B, C]= {B→B, B→C, C→C, BC→B, BC→C}<br />
&emsp;<span style="font-style: italic;">F</span><sup>+</sup>[B, D]= {B→B, B→D, D→D, BD→B, BD→D}<br />
&emsp;<span style="font-style: italic;">F</span><sup>+</sup>[A, B]= {A→A, A→B, B→B, AB→A, AB→B}<br />
&emsp;そこで，<span style="font-style: italic;">G</span>=<span style="font-style: italic;">F</span><sup>+</sup>[B, C]∪<span style="font-style: italic;">F</span><sup>+</sup>[B, D]∪<span style="font-style: italic;">F</span><sup>+</sup>[A, B] と置き，<span style="font-style: italic;">G</span><sup>+</sup>=<span style="font-style: italic;">F</span><sup>+</sup> かどうかを検証する．そのために，<span style="font-style: italic;">F</span><sup>+</sup> の元であって <span style="font-style: italic;">G</span> の元でない FD について，それが <span style="font-style: italic;">G</span><sup>+</sup> の元であるか否かを検証する．そのような元は，<br />
A→C, A→D, C→D, AB→C, AB→D, AC→A, AC→B, AC→C, AC→D, AD→A,AD→B, AD→C, AD→D, BC→D, BD→C, CD→C, CD→D, ABC→A, ABC→B, ABC→C, ABC→D, ABD→A, ABD→B, ABD→C, ABD→D, ACD→A, ACD→B, ACD→C, ACD→D, BCD→B, BCD→C, BCD→D, ABCD→A, ABCD→B, ABCD→C, ABCD→Dである．これらのうち，自明でない FD である A→C, A→D, AB→C, AB→C, AB→D, AC→B, AC→D, AD→B, AD→C, BC→D, BD→C, ABC→D, ABD→C, ACD→B, BCD→A について，それらが <span style="font-style: italic;">G</span><sup>+</sup> の元か否かを検証すると，C→D が <span style="font-style: italic;">F</span><sup>+</sup> の元ではないことが分かる（￢(<span style="font-style: italic;">G</span> ⊨ C→D)）．したがって，<u>この情報無損失分解は関数従属性保存では<strong>ない</strong></u>．</p>
<p><strong>(場合2) A→B→D の解消を図る．</strong><br />
&emsp;<b><span style="font-style: italic;">R</span></b> を A→B→D を構成する B→D を使って <b><span style="font-style: italic;">R</span></b>[B, D] と <b><span style="font-style: italic;">R</span></b>[A, B, C] に情報無損失分解すると，A→B→C により，<b><span style="font-style: italic;">R</span></b>[A, B, C] も 3NF ではないので，それを B→C を使って <b><span style="font-style: italic;">R</span></b>[B, C] と <b><span style="font-style: italic;">R</span></b>[A, B] に情報無損失分解すると次が成立する．その結果，<b><span style="font-style: italic;">R</span></b> は <b><span style="font-style: italic;">R</span></b>[B, D] と <b><span style="font-style: italic;">R</span></b>[B, C] と <b><span style="font-style: italic;">R</span></b>[A, B] に情報無損失分解されるが，検証しないといけないことは (場合1)と同様となる．したがって，<u>この情報無損失分解は関数従属性保存では<strong>ない</strong></u>．</p>
<p><strong>(場合3) B→C→D の解消を図る．</strong><br />
&emsp;<b><span style="font-style: italic;">R</span></b> を B→C→D を構成する C→D を使って <b><span style="font-style: italic;">R</span></b>[C, D] と <b><span style="font-style: italic;">R</span></b>[A, B, C] に情報無損失分解すると，A→B→C により，<b><span style="font-style: italic;">R</span></b>[A, B, C] も 3NF ではないので，それを B→C を使って <b><span style="font-style: italic;">R</span></b>[B, C] と <b><span style="font-style: italic;">R</span></b>[A, B]に情報無損失分解すると次が成立する．<br />
&emsp;<span style="font-style: italic;">F</span><sup>+</sup>[C, D]= {C→C, C→D, D→D, CD→C, CD→D}<br />
&emsp;<span style="font-style: italic;">F</span><sup>+</sup>[B, C]= {B→B, B→C, C→C, BC→B, BC→C}<br />
&emsp;<span style="font-style: italic;">F</span><sup>+</sup>[A, B]= {A→A, A→B, B→B, AB→A, AB→B}<br />
&emsp;そこで，<span style="font-style: italic;">G</span>=<span style="font-style: italic;">F</span><sup>+</sup>[C, D]∪<span style="font-style: italic;">F</span><sup>+</sup>[B, C]∪<span style="font-style: italic;">F</span><sup>+</sup>[A, B] と置き，<span style="font-style: italic;">G</span><sup>+</sup>=<span style="font-style: italic;">F</span><sup>+</sup> かどうかを検証する．そのために，<span style="font-style: italic;">F</span><sup>+</sup> の元であって <span style="font-style: italic;">G</span> の元でない FD について，それが <span style="font-style: italic;">G</span><sup>+</sup> の元であるか否かを検証する．そのような元は，<br />
A→C, A→D, B→D, AB→C, AB→D, AC→A, AC→B, AC→C, AC→D, AD→A, AD→B, AD→C, AD→D, BC→D, BD→B, BD→C, BD→D, ABC→A, ABC→B, ABC→C, ABC→D, ABD→A, ABD→B, ABD→C, ABD→D, ACD→A, ACD→B, ACD→C, ACD→D, BCD→B, BCD→C, BCD→D, ABCD→A, ABCD→B, ABCD→C, ABCD→D である．これらのうち，自明でない FD である A→C, A→D, B→D, AB→C, AB→D, AC→B, AC→D, AD→B, AD→C, BC→D, BD→C, ABC→D, ABD→C, ACD→B について，それらが <span style="font-style: italic;">G</span><sup>+</sup> の元か否かを検証すると，すべてが <span style="font-style: italic;">G</span><sup>+</sup> の元であることが分かる．したがって，<u>この情報無損失分解は関数従属性保存で<strong>ある</strong></u>．</p>
<p><strong>(場合4) A→C→D の解消を図る．</strong><br />
&emsp;<b><span style="font-style: italic;">R</span></b> を A→C→D を構成する C→D を使って <b><span style="font-style: italic;">R</span></b>[C, D] と <b><span style="font-style: italic;">R</span></b>[A, B, C]に情報無損失分解する．このとき，行わなくてはならない検証は(場合3)と同じとなり，したがって，<u>この情報無損失分解は関数従属性保存で<strong>ある</strong></u>．</p>
<p>&emsp;以上，例題 6 では，関数従属性保存か否かは情報無損失分解の仕方による，ということが示されました．<br />
<center><img decoding="async" src="https://www.sraoss.co.jp/tech-blog/wp-content/uploads/2022/05/drmasunaga-pic-03.png" alt="SQL code" style="margin-top: -22px; width: 300px" /></center><br />
<center>図 3　リレーションスキーマ <b><span style="font-style: italic;">R</span></b>(A, B, C, D)に所与のFD集合（例題6）</center></p>
<p><strong>【例題7】</strong><br />
&emsp;リレーションスキーマ <b><span style="font-style: italic;">R</span></b>(A, B, C, D) に所与の FD 集合 <span style="font-style: italic;">F</span>={A→B, B→C, A→D, D→B} が指定されているとする．このとき，<b><span style="font-style: italic;">R</span></b> は 2NF ではあるが 3NF ではない．<b><span style="font-style: italic;">R</span></b> の 3NF への情報無損失分解が関数従属性保存であるかどうかを検証してみよ．なお，図 4 に本例題での所与の FD 集合の様子を示す．<br />
<strong>(解答)</strong><br />
&emsp;このとき，A<sup>+</sup>=ABCD, B<sup>+</sup>=BC, C<sup>+</sup>=C, D<sup>+</sup>=BCD, AB<sup>+</sup>=AC<sup>+</sup>=AD<sup>+</sup>=ABCD, BC<sup>+</sup>=BC, BD<sup>+</sup>=BCD, CD<sup>+</sup>=BCD, ABC<sup>+</sup>=ABD<sup>+</sup>=ACD<sup>+</sup>=ABCD, BCD<sup>+</sup>=BCD, ABCD<sup>+</sup>=ABCD なので，<span style="font-style: italic;">F</span><sup>+</sup> は次の通りとなる．<br />
&emsp;<span style="font-style: italic;">F</span><sup>+</sup>={A→A, A→B, A→C, A→D, B→B, B→C, C→C, D→B, D→C, D→D, AB→A, AB→B, AB→C, AB→D, AC→A, AC→B, AC→C, AC→D, AD→A, AD→B, AD→C, AD→D, BC→B, BC→C, BD→B, BD→C, BD→D, CD→B, CD→C, CD→D, ABC→A, ABC→B, ABC→C, ABC→D, ABD→A, ABD→B, ABD→C, ABD→D, ACD→A, ACD→B, ACD→C, ACD→D, BCD→B, BCD→C, BCD→D, ABCD→A, ABCD→B, ABCD→C, ABCD→D}<br />
&emsp;<b><span style="font-style: italic;">R</span></b> の候補キーは A のみで，2NF である．一方，<b><span style="font-style: italic;">R</span></b> には A→B→C, A→D→B, D→B→C, A→D→C という 4 つの推移的関数従属性が存在し 3NF ではない．そこで，<b><span style="font-style: italic;">R</span></b> を 3NF に情報無損失分解する．</p>
<p><strong>(場合1) A→B→C の解消を図る．</strong><br />
&emsp;<b><span style="font-style: italic;">R</span></b> を A→B→C を構成する B→C を使って <b><span style="font-style: italic;">R</span></b>[B, C] と <b><span style="font-style: italic;">R</span></b>[A, B, D] に情報無損失分解すると，A→D, D→B∈<span style="font-style: italic;">F</span><sup>+</sup> なので，<b><span style="font-style: italic;">R</span></b>[A, B, D] は 3NF ではなく，それを D→B で情報無損失分解して 3NF にするとき，次が成立する．<br />
&emsp;<span style="font-style: italic;">F</span><sup>+</sup>[B, C]= {B→B, B→C, C→C, BC→B, BC→C}<br />
&emsp;<span style="font-style: italic;">F</span><sup>+</sup>[A, D]= {A→A, A→D, D→D, AD→A, AD→D}<br />
&emsp;<span style="font-style: italic;">F</span><sup>+</sup>[B, D]= {B→B, D→B, D→D, BD→B, BD→D}<br />
&emsp;そこで，<span style="font-style: italic;">G</span>=<span style="font-style: italic;">F</span><sup>+</sup>[B, C]∪<span style="font-style: italic;">F</span><sup>+</sup>[A, D]∪<span style="font-style: italic;">F</span><sup>+</sup>[B, D] と置き，<span style="font-style: italic;">G</span><sup>+</sup>=<span style="font-style: italic;">F</span><sup>+</sup> かどうかを検証する．そのために，<span style="font-style: italic;">F</span><sup>+</sup> の元であって <span style="font-style: italic;">G</span> の元でない FD について，それが <span style="font-style: italic;">G</span><sup>+</sup> の元であるか否かを検証する．そのような元は，<br />
A→B, A→C, D→C, AB→A, AB→B, AB→C, AB→D, AC→A, AC→B, AC→C, AC→D, AD→B, AD→C, BD→C, CD→B, CD→C, CD→D, ABC→A, ABC→B, ABC→C, ABC→D, ABD→A, ABD→B, ABD→C, ABD→D, ACD→A, ACD→B, ACD→C, ACD→D, BCD→B, BCD→C, BCD→D, ABCD→A, ABCD→B, ABCD→C, ABCD→D である．これらのうち，自明でない FD である A→B, A→C, D→C, AB→C, AB→D, AC→B, AC→D, AD→B, AD→C, BD→C, CD→B, ABC→D, ABD→C, ACD→B について，それらが <span style="font-style: italic;">G</span><sup>+</sup> の元か否かを検証すると，すべてが <span style="font-style: italic;">G</span><sup>+</sup> の元であることが分かる．したがって，<u>この情報無損失分解は関数従属性保存で<strong>ある</strong></u>．</p>
<p><strong>(場合2) A→D→B の解消を図る．</strong><br />
&emsp;<b><span style="font-style: italic;">R</span></b> を A→D→B を構成する D→B を使って <b><span style="font-style: italic;">R</span></b>[D, B] と <b><span style="font-style: italic;">R</span></b>[A, C, D] に情報無損失分解すると，A→D, D→C∈<span style="font-style: italic;">F</span><sup>+</sup> なので，<b><span style="font-style: italic;">R</span></b>[A, C, D] は 3NF ではなく，それを D→C で情報無損失分解して 3NF にするとき，次が成立する．<br />
&emsp;<span style="font-style: italic;">F</span><sup>+</sup>[D, B]= {B→B, D→B, D→D, BD→B, BD→D}<br />
&emsp;<span style="font-style: italic;">F</span><sup>+</sup>[C, D]= {C→C, D→C, D→D, CD→C, CD→D}<br />
&emsp;<span style="font-style: italic;">F</span><sup>+</sup>[A, D]= {A→A, A→D, D→D, AD→A, AD→D}<br />
&emsp;そこで，<span style="font-style: italic;">G</span>=<span style="font-style: italic;">F</span><sup>+</sup>[D, B]∪<span style="font-style: italic;">F</span><sup>+</sup>[C, D]∪<span style="font-style: italic;">F</span><sup>+</sup>[A, D] と置き，<span style="font-style: italic;">G</span><sup>+</sup>=<span style="font-style: italic;">F</span><sup>+</sup> かどうかを検証する．そのために，<span style="font-style: italic;">F</span><sup>+</sup> の元であって <span style="font-style: italic;">G</span> の元でない FD について，それが <span style="font-style: italic;">G</span><sup>+</sup> の元であるか否かを検証する．そのような元は，<br />
A→B, A→C, B→C, AB→A, AB→B, AB→C, AB→D, AC→A, AC→B, AC→C, AC→D, AD→B, AD→C, BC→B, BC→C, BD→C, CD→B, ABC→A, ABC→B, ABC→C, ABC→D, ABD→A, ABD→B, ABD→C, ABD→D, ACD→A, ACD→B, ACD→C, ACD→D, BCD→B, BCD→C, BCD→D, ABCD→A, ABCD→B, ABCD→C, ABCD→D となる．これらのうち，自明でない FD である A→B, A→C, B→C, AB→C, AB→D, AC→B, AC→D, AD→B, AD→C, BD→C, CD→B, ABD→C, ACD→B について，<span style="font-style: italic;">G</span><sup>+</sup> の元であるか否かを検証すると，B→C が <span style="font-style: italic;">G</span><sup>+</sup> の元ではないことが分かる（￢(<span style="font-style: italic;">G</span> ⊨ B→C)）．したがって，<u>この情報無損失分解は関数従属性保存では<strong>ない</strong></u>．</p>
<p><strong>(場合3) D→B→C の解消を図る．</strong><br />
&emsp;<b><span style="font-style: italic;">R</span></b> を D→B→C を構成する B→C を使って情報無損失分解することとなるが，このとき，行わなくてはならない検証は(場合1)と同じとなり，したがって，<u>この情報無損失分解は関数従属性保存で<strong>ある</strong></u>．</p>
<p><strong>(場合4) A→D→C の解消を図る．</strong><br />
&emsp;<b><span style="font-style: italic;">R</span></b> を A→D→C を構成する D→C を使って <b><span style="font-style: italic;">R</span></b>[D, C] と <b><span style="font-style: italic;">R</span></b>[A, B, D] に情報無損失分解すると，A→D, D→B∈<span style="font-style: italic;">F</span><sup>+</sup> かつ ¬(D→A∈<span style="font-style: italic;">F</span><sup>+</sup>) なので，<b><span style="font-style: italic;">R</span></b>[A, B, D]は 3NF ではなく，それを D→B で情報無損失分解して 3NF にするとき，次が成立する．<br />
&emsp;<span style="font-style: italic;">F</span><sup>+</sup>[D, C]= {C→C, D→C, D→D, CD→C, CD→D}<br />
&emsp;<span style="font-style: italic;">F</span><sup>+</sup>[D, B]= {B→B, D→B, D→D, BD→B, BD→D}<br />
&emsp;<span style="font-style: italic;">F</span><sup>+</sup>[A, D]= {A→A, A→D, D→D, AD→A, AD→D}<br />
&emsp;そこで，<span style="font-style: italic;">G</span>=<span style="font-style: italic;">F</span><sup>+</sup>[D, C]∪<span style="font-style: italic;">F</span><sup>+</sup>[D, B]∪<span style="font-style: italic;">F</span><sup>+</sup>[A, D] と置き，<span style="font-style: italic;">G</span><sup>+</sup>=<span style="font-style: italic;">F</span><sup>+</sup> かどうかを検証する．そのために，<span style="font-style: italic;">F</span><sup>+</sup> の元であって <span style="font-style: italic;">G</span> の元でない FD について，それが <span style="font-style: italic;">G</span><sup>+</sup> の元であるか否かを検証する．そのような元は，<br />
A→B, A→C, B→C, AB→A, AB→B, AB→C, AB→D, AC→A, AC→B, AC→C, AC→D, AD→B, AD→C, BC→B, BC→C, BD→C, CD→B, ABC→A, ABC→B, ABC→C, ABC→D, ABD→A, ABD→B, ABD→C, ABD→D, ACD→A, ACD→B, ACD→C, ACD→D, BCD→B, BCD→C, BCD→D, ABCD→A, ABCD→B, ABCD→C, ABCD→D となる．<br />
&emsp;これらのうち，自明でない FD である A→B, A→C, B→C, AB→A, AB→B, AB→C, AB→D, AC→A, AC→B, AC→C, AC→D, AD→B, AD→C, BC→B, BC→C, BD→C, CD→B, ABC→A, ABC→B, ABC→C, ABC→D, ABD→A, ABD→B, ABD→C, ABD→D, ACD→A, ACD→B, ACD→C, ACD→D, BCD→B, BCD→C, BCD→D, ABCD→A, ABCD→B, ABCD→C, ABCD→D について，<span style="font-style: italic;">G</span><sup>+</sup> の元であるか否かを検証すると，B→C が <span style="font-style: italic;">G</span><sup>+</sup> の元ではないことが分かる（￢(<span style="font-style: italic;">G</span> ⊨ B→C)）．したがって，<u>この情報無損失分解は関数従属性保存では<strong>ない</strong></u>．</p>
<p>&emsp;以上，例題 7 では，関数従属性保存か否かは情報無損失分解の仕方による，ということが示されました．<br />
<center><img decoding="async" src="https://www.sraoss.co.jp/tech-blog/wp-content/uploads/2022/05/drmasunaga-pic-04.png" alt="SQL code" style="margin-top: -22px; width: 300px" /></center><br />
<center>図 4　リレーションスキーマ <b><span style="font-style: italic;">R</span></b>(A, B, C, D) に所与の FD 集合（例題7）</center></p>
<p><strong>【例題8】</strong><br />
&emsp;リレーションスキーマ <b><span style="font-style: italic;">R</span></b>(A, B, C, D) に所与の FD 集合 <span style="font-style: italic;">F</span>={A→B, B→C, B→D, D→C} が指定されているとする．このとき，<b><span style="font-style: italic;">R</span></b> は 2NF ではあるが 3NF ではない．<b><span style="font-style: italic;">R</span></b> の 3NF への情報無損失分解が関数従属性保存であるかどうかを検証してみよ．なお，図 5 に本例題での所与の FD 集合の様子を示す．<br />
<strong>(解答)</strong><br />
&emsp;このとき，A<sup>+</sup>=ABCD, B<sup>+</sup>=BCD, C<sup>+</sup>=C, D<sup>+</sup>=CD, AB<sup>+</sup>=AC<sup>+</sup>=AD<sup>+</sup>=ABCD, BC<sup>+</sup>=BCD, BD<sup>+</sup>=BCD, CD<sup>+</sup>=CD, ABC<sup>+</sup>=ABD<sup>+</sup>=ACD<sup>+</sup>=ABCD, BCD<sup>+</sup>=BCD, ABCD<sup>+</sup>=ABCD なので，<span style="font-style: italic;">F</span><sup>+</sup> は次の通りとなる．<br />
&emsp;<span style="font-style: italic;">F</span><sup>+</sup>={A→A, A→B, A→C, A→D, B→B, B→C, B→D, C→C, D→C, D→D, AB→A, AB→B, AB→C, AB→D, AC→A, AC→B, AC→C, AC→D, AD→A, AD→B, AD→C, AD→D, BC→B,BC→C, BC→D, BD→B, BD→C, BD→D, CD→C, CD→D, ABC→A, ABC→B, ABC→C, ABC→D, ABD→A, ABD→B, ABD→C, ABD→D, ACD→A, ACD→B, ACD→C, ACD→D, BCD→B, BCD→C, BCD→D, ABCD→A, ABCD→B, ABCD→C, ABCD→D}<br />
&emsp;<b><span style="font-style: italic;">R</span></b> の候補キーは A のみで，2NF である．一方，<b><span style="font-style: italic;">R</span></b> には A→B→C，A→B→D, B→D→C，A→D→C という 4 つの推移的関数従属性が存在し 3NF ではない．そこで，<b><span style="font-style: italic;">R</span></b> を情報無損失分解する．</p>
<p><strong>(場合1) A→B→C の解消を図る．</strong><br />
&emsp;この場合，B→C を使って <b><span style="font-style: italic;">R</span></b> を <b><span style="font-style: italic;">R</span></b>[B, C] と <b><span style="font-style: italic;">R</span></b>[A, B, D] に情報無損失分解する．<b><span style="font-style: italic;">R</span></b>[A, B, D] では A→B→D が成立していて 3NF ではないので，B→D でそれを <b><span style="font-style: italic;">R</span></b>[B, D] と <b><span style="font-style: italic;">R</span></b>[A, B] に情報無損失分解する．このとき，次が成立する．<br />
&emsp;<span style="font-style: italic;">F</span><sup>+</sup>[B, C]= {B→B, B→C, C→C, BC→B, BC→C }<br />
&emsp;<span style="font-style: italic;">F</span><sup>+</sup>[B, D]= {B→B, B→D, D→D, BD→B, BD→D}<br />
&emsp;<span style="font-style: italic;">F</span><sup>+</sup>[A, B]= {A→A, A→B, B→B, AB→A, AB→B}<br />
&emsp;そこで，<span style="font-style: italic;">G</span>=<span style="font-style: italic;">F</span><sup>+</sup>[B, C]∪<span style="font-style: italic;">F</span><sup>+</sup>[B, D]∪<span style="font-style: italic;">F</span><sup>+</sup>[A, B] と置いて，<span style="font-style: italic;">G</span><sup>+</sup>=<span style="font-style: italic;">F</span><sup>+</sup> かどうかを検証する．そのために，<span style="font-style: italic;">F</span><sup>+</sup> の元であって <span style="font-style: italic;">G</span> の元でない FD について，それが <span style="font-style: italic;">G</span><sup>+</sup> の元であるか否かを検証する．<br />
&emsp;そのような元は，A→C, A→D, D→C, AB→C, AB→D, AC→A, AC→B, AC→C, AC→D, AD→A, AD→B, AD→C, AD→D, BC→D, BD→C, CD→C, CD→D, ABC→A, ABC→B, ABC→C, ABC→D, ABD→A, ABD→B, ABD→C, ABD→D, ACD→A, ACD→B, ACD→C, ACD→D, BCD→B, BCD→C, BCD→D, ABCD→A, ABCD→B, ABCD→C, ABCD→D となる．これらのうち，自明でない FD である A→C, A→D, D→C, AB→C, AB→D, AC→B, AC→D, AD→B, AD→C, BC→D, BD→C, ABC→D, ABD→C, ACD→B について，<span style="font-style: italic;">G</span><sup>+</sup> の元であるか否かを検証すると，唯一，D→C が <span style="font-style: italic;">G</span> の下では導出されない,つまり，D→C は <span style="font-style: italic;">G</span><sup>+</sup> の元ではないことが分かる（￢(<span style="font-style: italic;">G</span> ⊨ D→C)）．したがって，<u>この情報無損失分解は関数従属性保存では<strong>ない</strong></u>．</p>
<p><strong>(場合2) A→B→D の解消を図る．</strong><br />
&emsp;この場合，B→D を使って <b><span style="font-style: italic;">R</span></b> を <b><span style="font-style: italic;">R</span></b>[B, D] と <b><span style="font-style: italic;">R</span></b>[A, B, C] に情報無損失分解する．<b><span style="font-style: italic;">R</span></b>[A, B, C] は 3NF ではないので，B→C でそれを <b><span style="font-style: italic;">R</span></b>[B, C] と <b><span style="font-style: italic;">R</span></b>[A, B] に情報無損失分解する．このとき，行わなくてはならない検証は(場合1)と同じとなり，したがって，<u>この情報無損失分解は関数従属性保存では<strong>ない</strong></u>．</p>
<p><strong>(場合3) B→D→C の解消を図る．</strong><br />
&emsp;この場合，D→C を使って <b><span style="font-style: italic;">R</span></b> を <b><span style="font-style: italic;">R</span></b>[D, C] と <b><span style="font-style: italic;">R</span></b>[A, B, D] に情報無損失分解する．<b><span style="font-style: italic;">R</span></b>[A, B, D] は A→B→D の存在により 3NF ではないので，B→D でそれを <b><span style="font-style: italic;">R</span></b>[B, D] と <b><span style="font-style: italic;">R</span></b>[A, B] に情報無損失分解する．このとき，次が成立する．<br />
&emsp;<span style="font-style: italic;">F</span><sup>+</sup>[C, D]= {C→C, D→C, D→D, CD→C, CD→D }<br />
&emsp;<span style="font-style: italic;">F</span><sup>+</sup>[B, D]= {B→B, B→D, D→D, BD→B, BD→D}<br />
&emsp;<span style="font-style: italic;">F</span><sup>+</sup>[A, B]= {A→A, A→B, B→B, AB→A, AB→B}</p>
<p>&emsp;そこで，<span style="font-style: italic;">G</span>=<span style="font-style: italic;">F</span><sup>+</sup>[C, D]∪<span style="font-style: italic;">F</span><sup>+</sup>[B, D]∪<span style="font-style: italic;">F</span><sup>+</sup>[A, B] と置いて，<span style="font-style: italic;">G</span><sup>+</sup>=<span style="font-style: italic;">F</span><sup>+</sup> かどうかを検証する．そのために，<span style="font-style: italic;">F</span><sup>+</sup> の元であって <span style="font-style: italic;">G</span> の元でない FD について，それが <span style="font-style: italic;">G</span><sup>+</sup> の元であるか否かを検証する．そのような元は，<br />
A→C, A→D, B→C, AB→C, AB→D, AC→A, AC→B, AC→C, AC→D, AD→A, AD→B, AD→C, AD→D, BC→B, BC→C, BC→D, BD→C, ABC→A, ABC→B, ABC→C, ABC→D, ABD→A, ABD→B, ABD→C, ABD→D, ACD→A, ACD→B, ACD→C, ACD→D, BCD→B, BCD→C, BCD→D, ABCD→A, ABCD→B, ABCD→C, ABCD→D となる．これらのうち，自明でない FD である A→C, A→D, B→C, AB→C, AB→D, AC→B, AC→D, AD→B, AD→C, BC→D, BD→C, ABC→D, ABD→C, ACD→B について，<span style="font-style: italic;">G</span><sup>+</sup> の元であるか否かを検証すると，すべてが <span style="font-style: italic;">G</span> の下で導出されることが分かる．したがって，<u>この情報無損失分解は関数従属性保存で<strong>ある</strong></u>．</p>
<p><strong>(場合4) A→D→C の解消を図る．</strong><br />
&emsp;この場合，D→C を使って <b><span style="font-style: italic;">R</span></b> を <b><span style="font-style: italic;">R</span></b>[D, C] と <b><span style="font-style: italic;">R</span></b>[A, B, D] に情報無損失分解する．このとき，行わなくてはならない検証は(場合3)と同じとなり，したがって，<u>この情報無損失分解は関数従属性保存で<strong>ある</strong></u>．<br />
&emsp;以上，例題 8 でも，関数従属性保存か否かは情報無損失分解の仕方による，ということが示されました．</p>
<p><center><img decoding="async" src="https://www.sraoss.co.jp/tech-blog/wp-content/uploads/2022/05/drmasunaga-pic-05.png" alt="SQL code" style="margin-top: -22px; width: 300px" /></center><br />
<center>図 5　リレーションスキーマ <b><span style="font-style: italic;">R</span></b>(A, B, C, D)に所与のFD集合（例題8）</center></p>
<p>&emsp;以上，例題 4～8 を通して確認できたように，「情報無損失分解ができ，かつ，関数従属性保存が成り立つ変換が必ず存在するものは，第 2 正規形から第3正規形への変換である」（午前 Ⅱ 問題 問 4 の出題意図）とは言い切れないことが分かりました．関数従属性保存が成り立つか否かは場合によるということです．</p>
<h4>7. おわりに</h4>
<p>&emsp;筆者は，平成 26 年度 春季 データベーススペシャリスト試験 午前 Ⅱ 問題 問 4 とその正解を「出題ミス」として簡単に片付けてしまう気にはなれず，この問題をもう少し重く受け止めています．その理由は，なぜこのような認識がなされてしまったのだろうかと考えるとき，どうもその背景には RDB 設計の現場に，RDB 設計のための「分解的手法」と「合成的手法」について，特に，その差異について十分な理解がなされていないのではないかと思うからです．<br />
&emsp;そもそも，分解的手法とはコッドのリレーショナルデータモデルとその正規化理論に基づく RDB の設計手法で，FD や多値従属性や結合従属性によるリレーションの情報無損失分解がすべてを取り仕切ります．<u>その時，FD が保存されるか否かは，情報無損失分解とは独立した概念であり</u>，本稿で示したように，FD が保存される場合もあれば，保存されない場合もあるわけです．<br />
&emsp;一方，バーンシュタイン（P.A. Bernstein）により提案された RDB 設計の「合成的手法」[5] は，データベース化の対象となった実世界で成り立つ FD をリストアップし，それを所与の FD 集合と指定することで，それから「関数従属性保存・3NF・情報無損失分解」と三拍子そろった RDB を設計することができます．<br />
&emsp;つまり，3NF のリレーションスキーマを設計するにあたり，<u>分解的手法では情報無損失分解と関数従属性保存はセットではありませんが，合成的手法では情報無損失分解と関数従属性保存はセットです</u>．ここで，セットという言葉は共に成り立つ，という意味で使っています．これはとても大きな違いなのですが，このことがひょっとして RDB 設計の現場で十分認識されないまま，いつしか分解的手法でも 3NF までならば「関数従属性保存・3NF・情報無損失分解」と三拍子そろった RDB を設計することができるやに誤認識されて今日に至っているのではないか，筆者はそれをとても危惧してこの記事を書いたということです．本稿をお読みいただいた方の中には RDB 設計の最前線に立たれている方も大勢いらっしゃるのではないかと思いますが，機会があれば現場の声を是非お聞かせ願いたく思います．</p>
<p>【文献】</p>
<p style="margin-top: -10px;" >[1]</p>
<table style="border:none; margin-top: -62px; margin-left: 20px; margin-bottom: -00px;" align="left" >
<tbody style="border:none;">
<td style="width: 800px; border:none;">
平成26年度春期データベーススペシャリスト試験午前Ⅱ問題<br />
https://www.jitec.ipa.go.jp/1_04hanni_sukiru/mondai_kaitou_2014h26_1/2014h26h_db_am2_qs.pdf
</td>
</tbody>
</table>
<p style="margin-top: -22px;" >[2]</p>
<table style="border:none; margin-top: -62px; margin-left: 20px; margin-bottom: -00px;" align="left" >
<tbody style="border:none;">
<td style="width: 800px; border:none;">
平成26年度春期データベーススペシャリスト試験解答例<br />
https://www.jitec.ipa.go.jp/1_04hanni_sukiru/mondai_kaitou_2014h26_1/2014h26h_db_am2_ans.pdf
</td>
</tbody>
</table>
<p style="margin-top: -22px;" >[3]</p>
<table style="border:none; margin-top: -62px; margin-left: 20px; margin-bottom: -00px;" align="left" >
<tbody style="border:none;">
<td style="width: 800px; border:none;">
E.F. Codd. A Relational Model of Data for Large Shared Data Banks. Communications of the ACM, Vol.13, No.6, pp.377-387, 1970.
</td>
</tbody>
</table>
<p style="margin-top: -22px;" >[4]</p>
<table style="border:none; margin-top: -62px; margin-left: 20px; margin-bottom: -00px;" align="left" >
<tbody style="border:none;">
<td style="width: 800px; border:none;">
E.F. Codd. Further Normalization of the Data Base Relational Model. R. Rustin (Ed.), Data Base Systems (Courant Computer Science Symposia 6), pp.33-64, Prentice-Hall, Englewood Cliffs, NJ, 1972.
</td>
</tbody>
</table>
<p style="margin-top: -22px;" >[5]</p>
<table style="border:none; margin-top: -62px; margin-left: 20px; margin-bottom: -00px;" align="left" >
<tbody style="border:none;">
<td style="width: 800px; border:none;">
P.A. Bernstein. Synthesizing Third Normal Form Relations from Functional Dependencies. ACM Transactions on Database Systems, Vol.1, No.4, pp.277-298, 1976.
</td>
</tbody>
</table>
<p style="margin-top: -22px;" >[6]</p>
<table style="border:none; margin-top: -62px; margin-left: 20px; margin-bottom: -00px;" align="left" >
<tbody style="border:none;">
<td style="width: 800px; border:none;">
増永良文．リレーショナルデータベース入門[第3版]．サイエンス社，2017．
</td>
</tbody>
</table>
]]></content:encoded>
					
		
		
			</item>
	</channel>
</rss>
