一昨日の「主キー/外部キーなんてドーデモイイ」と昨日の「絵で分かる! 主キー/外部キーのアホらしさ」において、主キー/外部キーというのは、いわばメモリ番地とポインターのような、仕掛け・手段が露出しているだけのものだ、と説明しました。仕掛けが露出している結果、概念的には単純なもの(例えば単なる写像)の実現が複雑でしかも恣意的になっています。
今日は正規形、なかでも一番基本的な第1正規形の話です。控えめなデイヴィッド君に代わって、ジイサマ(檜山)が批判的に検討しましょう。
アトミックって何ですかぁ?
関係データベースである限り、かならず第1正規形になっていることが要求されます。で、第1正規形って何? カラムの値がアトミックであることだと定義されます。アトミック? それ何?
まーともかくも「アトミックな値」というものがあったとして、アトミックな値の集合はドメインと呼び、テーブルとは区別されます。「テーブル=構造を持つレコードの集合」「ドメイン=構造を持たない値の集合」というと、なんかツジツマがあっているように思えます。はて、ほんとうでしょうか?
例で考えましょう。人に関するレコードを蓄えたPersonテーブルを考えます。名前(name)と生年月日(birth)のカラムがあります。nameカラムの値はName型、birthカラムの値はDate型だとします。Dateは標準SQLの日付型(時・分・秒を含まない)、NameはVARCHARとかで適当に定義するとしましょう。この状況を絵で描くと次のようです。
Personは第1正規形になっているでしょうか? 別な言い方をすると、DateとNameはドメインでしょうか? 「SQL標準や実際のRDB製品でドメインなんだからドメインでしょ」というのは正しい答です。では、標準や製品が「これはドメイン」と決めた根拠は何でしょうか。それは「アトミックな値の集合であるから」という理由のはずです。
しかし現実的に、DateやNameがアトミック(分解不可能)だとはとうてい思えません。次の絵をみてください。
実は「アトミック」に文字通りの「分解不可能」なんて意味はないのです。「このデータ型はアトミックだ」と宣言したらそれがアトミックになります。つまり、言ったもの勝ちなのです。また一方、コンピュータや実装の都合で扱いにくいデータ型に対して「アトミックではない」と文句付けたり言い訳したりするためにも使います。標準委員会や大手ベンダーは声が大きいので、その言い分が世間的なアトミックとなっているのが実態です。
関係データモデルのいう第1正規形には、まともな定義はありません。
圏論を使えばどうなる
スピヴァックのデータベース理論では、テーブルとドメインは区別しません(便宜上、すべてテーブルと呼んでいる)。では、どうやってもドメインという概念は定義できないのかというと、そうではありません。
圏Sのなかで、リーフ対象(leaf object)という概念が厳密に定義できます。有向グラフにおけるリーフノードと同じ定義です。リーフ対象はドメインに相当すると考えていいでしょう。リーフ対象の定義は次のとおりです。
- X∈|S| がリーフ対象であるとは、f:X→A ならば A = X かつ f = idX であること。
つまり、その対象から出る射が恒等射しかないときリーフ対象なのです。カラム f:X→A の存在は、XがA成分への分解を持つことなので、自分自信しか成分を持たないなら、確かにアトミックです。
リーフ対象が定義できても、それはあくまで圏Sに対して相対的なものです。絶対的なアトミックなんてありません。実際のところ、圏Sをより大きな圏Tに埋め込むと、Sのリーフ対象はTではリーフでなくなることがあります。DateやNameが特定の圏(スキーマ)内でリーフでも、より大きな圏では分解されるのはこの事情です。
スピヴァックは型システムとデータベースシステムの統合を目指す
次のことが分かりました。
- 第1正規形であるかどうかは「ドメイン」概念に依存する。
- ドメインは「アトミック」な値の集合である。
- アトミックな値の定義なんてない。したがって、ドメインの定義も第1正規形の定義もない。
- 理論的な根拠なんてないので、「アトミックだ」と言ったもの勝ち。
- アトミックとドメインの概念は、圏論ではリーフ対象として定義できる。
- しかし、リーフ対象の概念は埋め込み(より一般に関手)に対して安定してない。
このような状況ですから、アトミックとかドメインなんて根拠薄弱な概念に拘るのは得策とは思えません。スピヴァックのアプローチは、型システムを選んで固定したときに、その上でデータベースの世界がどう構築できるかを定式化することです。結論だけ言うと、トポスと呼ばれるたいへんに扱いやすい圏ができます。基盤となる型システムの変更は、トポスの系統的な変更を誘導します。
型システムはプログラミング言語に付随することが多いので、この方法はプログラミング言語とデータベースシステムの統合と言ってもいいでしょう。先週の土曜日に、id:bonotakeさんが紹介したスライドでは、聴衆(Haskeller)を考慮して、型システムの圏(たくさんの関数も含まれる)をHaskとしていましたが、どんなプログラミング言語/型システムでも同じことです。