Hot Heart, Cool Mind.

会計×IT の深層へ

主キーの設計④-数学をちょっとだけ(その1)

主キー論争の分析その④である。
といっても、前のエントリーですでに、主キーの存在を抹殺したので、論争の焦点そのものが雲散霧消してしまった。今回は付け足しとして、数学の話をする。
この「主キーの設計」シリーズ、僕は近年稀に見る気合をいれて書いているのに、悲しいことに回を追うごとに読者は減っているようだ(:_;)。今回でさらに減ること請け合いだ。
読みたくない人は読まなくてよろしい(でもヒマだったら読んでね)。


さて取り掛かる前に、やるべき作業の全体像を鳥瞰しておこう。
僕らの目標は、リレーショナルモデルに「エンティティ参照」の概念を組み込むことだ。
リレーショナルモデルは、大雑把に言えば、リレーションの数学的定義を土台として、その上に関係代数正規化理論が乗っかる構造になっている。
ここで明らかなのは、僕らの目標を達成するには、「リレーション」をそのまま使うわけにはいかない、ということだ。前々回しつこく説明したように、「リレーション」は「エンティティ」とは無縁の概念だからだ。
だから、まずは、「リレーション」に代えて何か別のものを土台に据えなければならない。ところが、下部構造が入れ替われば、上部構造もとうぜん修正を迫られる。すなわち、関係代数と正規化理論を再構築しなくてはならなくなる。
実は、結構大変な作業なのだ。

イデアを記述するだけでも、この一回のエントリでは到底無理だということに、今気付いた。

ともあれ、まず、土台から着手しよう。

リレーションの定義

リレーショナルモデルで、リレーションはどのように定義されるか。ここに、従業員Cとか、従業員名、職務等級といったデータ項目があるとする。これらのデータ項目それぞれについて許される値の集合はそれぞれ決まっている。これらを属性値集合とかドメインと呼ぶ。
いくつかの集合を持ち寄り、それぞれから要素をひとつずつ取り出してタプル(値の組)を作ることができる。たとえば、従業員C、従業員名、職務等級の値をそれぞれひとつずつ取り出して、

("1234","杉本啓","見習社員")
というタプルを作るといった具合に。

さらに、いくつかの集合をもとに作り得るタプルすべての集合という概念を考えることができる。これを、もとのいくつかの集合の直積と呼ぶ。上に示したタプルは、従業員C、従業員名、職務等級(これらそれぞれが集合である)の直積に属する。直積には、もとになった集合の要素のすべての組合せが属する。たとえば3個の要素を含む集合Aと5個の要素を含む集合Bの直積(これをA×Bで表す)には15個のタプルが属する。

さて、リレーションの定義は、「n個の属性値集合から構成される直積の部分集合」となる。
先の、AとBがそれぞれ属性値集合であって、

A={a1, a2, a3}, B={b1, b2, b3, b4, b5}
とすると、
X={(a1, b2), (a3, b1)} や、
Y={(a2, b3), (a1, b2), (a3, b2)}
は、リレーションである。

属性値集合D1,D2,D3...の直積の部分集合であるリレーションRを、

R(D1×D2×D3×...)
と書くことにしておこう。具体例で書けば、
従業員(従業員C×従業員名×職務等級)
といった具合である。

「リレーション関数」の導入

「知っている」ことと「理解している」ことは別である。僕らは今、リレーションがどう定義されるかを知った。ではリレーションを理解しよう。それには、タプルの同一性について考えてみることが近道だ。

リレーションにおいて各タプルを区別するものは、それを構成する要素(属性値)しかない。たとえば、

("1234","杉本啓","見習社員")
というタプルが「2つある」としよう。この2つを区別する手段は何もない。したがって、これらが2つあるという、最初の仮定は誤りである。ひとつしかない。属性の値がすべて等しい複数のタプルが存在するという状況は、リレーショナルモデルでは、あり得ない。

さらにいえば、上に示したタプルと、

("1234","オダギリジョー","見習社員")
というタプルは別物である。「従業員Cが同じなのでこの二人は同一人物かもしれない」という主張は相当の妥当性を持つと僕は思うが、リレーショナルモデルでは、その主張は根拠づけされない。すなわち、リレーショナルモデルにはそういった主張を支える「同一性」の概念がない。そういった同一性を持ち込むなら、あくまでデータ内容を解釈する側の責任で行え、モデル側では関知しないよ、ということなのだ。

さて、ここでやっと、なぜ「エンティティ参照」なのか、「タプル参照」ではだめなのか、という問いに、ちゃんと答えることができる。
対象の状態がどう変わろうともその対象を指し続ける、というのが「参照」の意味だ。したがって、「参照」をモデルに導入するには、「属性値の異同に依らない同一性」「属性値の変更を越えて生き延びる同一性」という概念を、なんとかしてモデルに組み込まなければならない。「参照」可能なのは、こういった「同一性」を定義できる対象だけなのだ。「タプル」はその資格要件を欠いている。
「同一性」をリレーショナルモデルに組み込むには、タプルの背後に実在する実体(エンティティ)という概念に、モデル上の要素としての居場所を与えてやればよい。なぜなら、僕たちが同一性を云々するとき、その対象は、表面に見える「タプル」ではなくそれが表す実体だからである。

これをする一番すっきりとした(と僕が思う)方法は、エンティティにタプルを対応づける関数

r : E ---> R(D1×D2×D3×...)
を考え、リレーションのかわりに、これをもとにモデルを構成することだ。この関数 rリレーション関数と呼ぼう。
いままでは「リレーション」を基礎としていたのに、それをやめて「関数」を基礎とするなんて、突拍子もないとお感じになるかもしれない。しかし、リレーションと同様、リレーション関数もまた「表」として表せることをご理解頂ければ、その違和感は解消されると思う。表形式で表したリレーション関数の一例を挙げよう:
主キーサンプル③-リレーション関数の例①
左の表は現実のエンティティを納めている。1行目のマス目の(僕)は、現実の存在である僕自身だ。リレーション関数によって、左の表の各エンティティが、右の表(リレーション)のタプルに対応づけられている。2行目と3行目の右の表部分には、同一の(すなわち同じ値をもつ)タプルが表示されている。すなわち、この2つの行の属性値はすべて一致しているが、異なる行と認識されている。異なるエンティティに結び付けられているからだ。「属性値の異同に依らない同一性」の存在を示す例である。 さて、表の1行目のタプルを変更してみよう:
主キーサンプル④-リレーション関数の例②
タプルは以前と異なるが、依然として1行目は僕を表している。「属性値の変更を越えて生き延びる同一性」だ。名前を変えても僕は僕。オダギリジョーにはなれない。悲しい現実ではある。

これで、同一性の概念を適切に表現できるようになった。次には、「エンティティ参照」を使えるようにしょう。これは簡単だ。リレーションを定義する際に、任意の属性値集合Dkは(E自身や別の)エンティティ集合であってもよいことにすればよい。
上の例の従業員リレーション関数は、以下のように定義される:

r1 : 従業員 ---> 従業員(従業員名×職務等級)
これを次のように変更しよう。
r1 : 従業員 ---> 従業員(従業員名×職務等級×[従業員] as 上司)
[従業員]は従業員エンティティ集合、"as 上司"はそれへの参照に「上司」という呼び名を与えることを表す(前回エントリへのコメント欄で渡辺さんが示された記法を使わせて頂いた。なお "as…" がない場合、エンティティ集合の名前がそのまま、参照の呼び名になる)。 このリレーション関数の例は以下のようになる:
主キーサンプル⑤-リレーション関数の例③
「上司」欄がエンティティ参照となっていることは一目瞭然だろう。

さて次のハードルは、リレーションの上に構築された関係代数と正規化理論という二つの建物を、リレーション関数の上に移築することだ。
しかし予想通り今日はここで力尽きた。

残りは次回(とたぶん次々回)のお楽しみ。...えっ? 全然楽しくないって?