このブログの更新は Twitterアカウント @m_hiyama で通知されます。
Follow @m_hiyama

メールでのご連絡は hiyama{at}chimaira{dot}org まで。

はじめてのメールはスパムと判定されることがあります。最初は、信頼されているドメインから差し障りのない文面を送っていただけると、スパムと判定されにくいと思います。

参照用 記事

奥野幹也『理論から学ぶデータベース実践入門』はどこがダメなのか

言い訳から始めます。この記事を(途中まででも)読んだ人は、次のように言いたくなるでしょう。

  • 『理論から学ぶデータベース実践入門』は良い本なのか悪い本なのか、いったいどっちなんだよ?!

この本は間違いや説明不足があり、誤読されやすい表現も多く、その点では残念な本です。しかし、面白いアイディア、するどい観察も含まれていて、行間を補い深読みすれば、多くの示唆を得られる本でもあります。

よって、「良い/悪い」の二択では答えられません。良い点と悪い点の両方を、できるだけ客観的に記述するしかないのです。それをした結果、長い記事となりました。

内容:

ことの発端: zhanponさんの批判

先日、次のQiita記事をみつけました。

タイトルにある本の第2章がオカシイという話です。もとの本をまったく知らないので、“著者の説明が舌足らずな程度”なのか、“トンデモ本と呼べるひどさ”なのか分かりません。

そこで、渋谷のMARUZEN&ジュンク堂書店で立ち読みすることにしました。立ってるのが辛くなったし、(幾つかの意味で)面白い本なので購入しました。

奥野本擁護と奥野本批判

先のQuiita記事で、zhanponさんは5つの問題点を指摘しています。そのうちの1つはどうにも擁護できませんが、残る4つは(ある程度は)擁護できます。zhanponさんの批判は、著者・奥野さんの真意を理解してないように思います。(真意を汲み取るのが困難なので、zhanponさんを責める気はありません。)

僕の批判・批判=擁護の弱いところは、「奥野さんの真意」なるものが僕(檜山)の想像である点です。想像が妄想だったら、僕の言い分はデタラメになります。この点は奥野さんご本人しかジャッジできないことです。

では、奥野本には問題がないのかというと、大いに問題あります。zhanponさんが指摘した諸点より、もっと重大な問題があります。zhanponさんに誤解を与えたこと*1も、おそらくは多くの人を困惑・混乱させていることも、「重大な問題」に起因しています。

先にその問題点を言っておくと:

  1. 論理をほとんど使ってない。
  2. 外部世界を考慮してない。

「書きたかったはずのこと/書くべきだったこと」が書いてないと言えます。zhanponさんは注意深く断り書きを付けています:

著者の意図が本文に正しく反映されていない可能性もある。

まさに、著者の意図が本文に正しく反映されていない本だと思います。

僕の擁護・批判の方針

問題点はありますが、だからといってこの本が無価値だとは思いません(zhanponさんも同じ断り書きをしています)。ほんとにダメダメだったら、そもそも擁護・批判する価値さえないので無視するか、トンデモ本ネタとして茶化すかです。擁護・批判に値する程度に、示唆に富む内容だということです。激しく同意する点も、「なるほど」とうなずく所も多々あります。

この本の企画の意図と志は素晴らしいものです。その意図・志が実現できていない、むしろミスリーディングな記述が目立つ、という事が僕が批判的になる理由です。「企画に無理があったかも」と感じるし、一方で「こうすればウマクいくんじゃないか」という思いもあります。

今回、擁護・批判の対象にするのは、『理論から学ぶデータベース実践入門』の第8章までです(すぐ下に目次)。第9章以降は、各論と応用なので、実務に疎い僕がどうこう言える内容ではありません(よって、対象外)。

  • 第1章 SQLとリレーショナルモデル
  • 第2章 述語論理とリレーショナルモデル
  • 第3章 正規化理論(その1)―― 関数従属性 ――
  • 第4章 正規化理論(その2)―― 結合従属性 ――
  • 第5章 リレーションの直交性
  • 第6章 ドメインの設計戦略
  • 第7章 NULLとの戦い
  • 第8章 SELECTを攻略する
  • 第9章 履歴データとうまく付き合う
  • 第10章 グラフに立ち向かう
  • 第11章 インデックスの設計戦略
  • 第12章 Webアプリケーションのためのデータ構造
  • 第13章 リファクタリングの最適解
  • 第14章 トランザクションの本質

「述語論理に関して幾つか誤りが見られる」とか「論理に詳しい人なら「なにを今更」「間違いだらけ」だ」とかほのめかして、その根拠を明らかにしない事は、僕が最も忌み嫌う卑怯なクズ野郎のやり口なので、僕はしません。しかし、擁護・批判の詳細な根拠は、短時間では書けないし、ひとつの記事が長大になるのも好ましくありません(って、いいかげん長大なんだが)。そこで、概略しか書いてない所では、「(詳細は別途記述予定。)」という断り書きを入れます。後日記事にしたら、リンクを張ります。

文句を言うだけでは建設的でないので、消極的提案と積極的提案をします。消極的提案とは、間違いと不適切な記述の削除・修正の案です。積極的提案とは、企画意図を実現するための加筆・敷衍の案です。

zhanponさんの指摘の再検討

zhanponさんの5点の指摘を引用します。「…」の後は僕のコメントです。

  1. 論理的な矛盾とデータの不整合を混同している … これは重要な論点
  2. 命題論理の限界についての説明がおかしい … それほどおかしくない
  3. 古典論理の定義を間違えている … 完全に間違えている、アウト
  4. 集合と集合論、述語と述語論理を混同して使っている … 言葉遣いが杜撰とは言えるが
  5. 二階論理の説明がおかしい … それほどおかしくない

この節は、著者・奥野さんを擁護する論調です。論理学の予備知識を仮定するので分からない所は飛ばしてください。

1. 論理的な矛盾とデータの不整合を混同している

これは、奥野さんの真意を想定(想像)しないと擁護できないので、次節以降(結論はココ)に回します。

2. 命題論理の限界についての説明がおかしい

zhanponさんは奥野本p.42の説明をまるまる引用しています。

命題論理は、突き詰めて言えば命題同士の関係性について、あれこれと考える学問です。ある事実を単に真偽値を持った命題として表現できる限りは、それで十分ですが、そうではない場合、つまり事実をシンプルな命題を用いて表現できないケースには対応できません。

たとえば、「この村のすべての村人が正直者だというわけではない」という文章は、どのような論理式で表現すれば良いでしょうか?

この文章をたとえば、P という命題だと仮定すると、「この村には正直でない者がいる」という命題の真偽は、どうやって証明すれば良いでしょうか? ほかにも「この村の村人は全員誰かと友だちである」という文章は、どのような論理式で表現すれば良いでしょうか? この文章と、「この村には村人全員と友だちの村人がいる」という文章との違いを、どのように確認すれば良いのでしょうか。

この部分、僕はあんまり違和感なかったです。

奥野さんの言いたいことは、次のようなことでしょう; 「この村のすべての村人が正直者だというわけではない」という内部構造を持つ文、述語論理を使えば「¬∀x∈この村の村人.(正直者だ(x))」と書ける文を、命題論理の命題Pと見なしてしまうと(つまり、量化子による内部構造を隠してしまうと)、内容的には同値である「この村には正直でない者がいる」をPから導出するすべがない。

順番に書くと:

  1. 命題Pを ¬∀x∈この村の村人.(正直者だ(x)) と置こう。(述語論理の書き方先取りしちゃってるけどさ。)
  2. 命題Qを ∃x∈この村の村人.(¬正直者だ(x)) と置こう。
  3. 内容的に P⊃Q かつ Q⊃P だよね。
  4. 命題論理の範囲内で、P⊃Q や Q⊃P を証明できますか?
  5. できないよね。
  6. 命題論理だけでは不十分だね。

これは、“著者の説明が舌足らずな程度”だと思います。

3. 古典論理の定義を間違えている

これはアウト。古典論理の定義(奥野本p.49)「一階述語論理は、古典論理とも呼ばれます」は間違ってます。でも、定義の一文を削除すればすむ話です。古典論理という概念を後で使いません(デフォルトが古典論理なので)。しかし、正しい定義をしておけば、後の説明を少し面白くできるでしょう。

p.145から3値論理の話があります。T(真), F(偽), U(未知)が真偽値です。論理演算の仕方はp.146にあります。それに従って真理値表を書いてみると、排中律(A∨¬A)は恒真式にならず、矛盾を表す式(A∧¬A)は恒偽式になりません。背理法も使えません。

A ¬A A∨¬A A∧¬A
T F T F
F T T F
U U U U

排中律背理法は、古典論理における法則/推論手法です。そして、我々が使い慣れているのは古典論理なので、古典論理ではない3値論理は辛いよね、という説明ができます。

{T, F, U}の3値論理は、次の記事の4値論理からボトム(⊥)を除いたものと同じです。

2値以外の真偽値にもし興味があるなら:

奥野本p.147のコラム「量子コンピュータとNULL」は悪い意味でヨタ話になっているので、削除したほうがいいでしょう。「量子」とかリスキーなワードを持ち出さなくても、単なるベキ集合でも(ある意味)重ね合わせです。計量的な重ね合わせをしたいなら、凸結合(重心結合)や劣凸結合の空間で出来ます。この枠組内でNULLの意味も(ヨタ話じゃなくて)分析できます。(詳細は別途記述予定。)[追記]データベースへの論理的アプローチ: NULLについてチャンと考えよう」参照[/追記]

4. 集合と集合論、述語と述語論理を混同して使っている

不注意と説明不足な点があるけど、まー、許容範囲かな。

  • 奥野本p. 50「集合は一階述語論理と1:1対応する」

「集合」は「集合論」の書き間違いとすれば、次の文と同じです。

  • 奥野本p.64 「述語論理と集合論は1:1で対応しています」

これは、述語論理のある特定の体系に対して、ある種の集合論(ZFCってことではない)の宇宙が健全な(ひょっとすると完全な)モデルになっている、ってことを言いたいのだと思います。(詳細は別途記述予定。)[追記]現場の集合論としての有界素朴集合論」参照[/追記]

5. 二階論理の説明がおかしい

他の部分(例えばp.136)も読むと、奥野さんは、二階論理に関してだいぶ誤解をしているようです。単なる二階論理で自己言及ができないのもzhanponさんのおっしゃる通り -- 「自己言及は二階論理では不可能である。」

ですが、ちょっと細工すれば自己言及はできます。アトム(とみなすモノ)の集合をDとして、Dの要素を引数とする単項述語の集合をPred(D)とします。Pred(D)をD内に埋め込むゲーデルエンコーディング g:Pred(D)→D があれば、p∈Pred(D)に対して p[p] := p(g(p)) と自己言及できます。(「「わたしはウソをつきません」と言い張る命題やプログラムを書けるのか?」も参考になるかも。)

つまり、gというレイフィケーション機能を付けた一階述語論理内で自己言及が可能です。しかしgは、構文領域の存在物Pred(D)と意味領域の存在物Dをまたぐ写像なので、当該の一階述語論理体系内で表現されていません。ニ階述語論理体系を使えば、体系内でgを記述できるでしょうか? たぶんできます。そのうちやってみます。(詳細は別途記述予定。)

とはいえ、奥野本の趣旨と構成からいえば、自己言及への“言及”はそもそもアラズモガナなので、一段落(p.49からp.50)削除すべきです。

消極的提案: 第2章を削除する

僕が感じたこの本の問題点のひとつは「論理をほとんど使ってない」ことです。どうせ使わないのなら、第2章「述語論理とリレーショナルモデル」は不要です。奥野さんは、

  • 論理学に触れない正規化の解説は、でたらめだと言っても過言ではありません。

と思いっきり強調太字で書いてますが、過言です。実際に、第3章以降で、述語論理を実質的・本質的に使っている所はないです。読む側としては、第2章を飛ばして、他で論理学の用語が出てきたら、そこも飛ばすようにしても差し支えないです。

「自己言及」「閉世界仮説」「フレーム問題」「量子力学的重ね合わせ」とかの言葉の使用も、間違いとは言いませんが、衒学的臭いがします。第2章は、まるまる衒学趣味の産物に見えます。

第3章以降でしばしば登場する論理的概念は「矛盾」です。論理的矛盾を引き合いに出して「データ不整合は怖いぞ、ダメだぞ」と訴えています。しかし、データ不整合がマズイことは、論理学で説明するまでもないことです。原稿修正作業としては、「矛盾」を文字列検索して、データ不整合と論理的矛盾を絡めている記述は全部削除するだけです。

今述べた削除修正によって、この本の価値は下がりません。むしろ、読みやすくなって歓迎されるでしょう。

積極的提案: 述語論理を活用した解説

「第2章は、まるまる衒学趣味の産物に見えます」と失礼なことを書きました。読む側からはそう見える(かも知れない)ということです。著者・奥野さんがそんなつもりではないことは承知です。曖昧な物言いや事例を出すだけでごまかさないで、述語論理を使ってキチンとした説明をしたい、というのが奥野さんの意図・志でしょう。

もちろん、その意図・志は支持します。しかしながら、一階述語論理の述語(が定義する命題関数)とリレーショナルモデルのリレーションとの対応だけでは、いうほど役に立つものでもなく、ありていに言って「別になくてもいい」ものです。

リレーショナルモデルについて語る人は、数学や論理を基盤としていることを強調することが多いのですが、その割に数学的/論理的記述はスベっているきらいがあります。奥野さんの記述も現象としてはスベっています。衒学趣味とみなされかねないのです。

しかし、奥野さんには(皮肉ではなく)高邁な志があるように思えます。リレーショナルモデルだけでなく、奥野流データベース理論を語ろうとしているのではないか、と。その理論が断片的に、ときに間違いを含んだ形で発露されているように僕には見えます。

僕が想像する(想像し過ぎか?)奥野流データベース理論を説明するには、一階述語論理では不十分です。二階で済むのか、それ以上の階数が必要なのかちょっと分からないのですが、高階(ニ階以上)の述語論理が必要です。

もし、意図・志を実現したいなら、高階述語論理まで積極的に使うべきです。それと同時に、論理のモデル*2としての外部世界(現実世界でも仮想世界でも抽象世界でもいい)を考慮すべきです。つまりは、次の2つの問題点を解決すべきです。

  1. 論理をほとんど使ってない。
  2. 外部世界を考慮してない。

奥野さんの発想の源泉(ただし想像)

僕が想像するには(あくまで想像ですが)、奥野さんの心のなかには(仮称)奥野流データベース理論がおぼろげに芽生えているようです。その理論の基盤となる概念は次の3つでしょう。

  1. (仮称)リレーショナル集合論
  2. (仮称)リレーショナル述語論理
  3. 演繹データベース

(仮称)リレーショナル集合論とは、リレーショナルモデルを説明するのに適した集合論です。ZFC公理的集合論のようなものではなく、アトムと型(または階数)を持ち帰納的に構成できるものです。

(仮称)リレーショナル述語論理は、基本リレーションを基本述語記号とみなして構成される、古典論理のひとつの体系です。

奥野さんが「集合論と述語論理は1:1対応する」と再三述べているのは、「(仮称)リレーショナル集合論と(仮称)リレーショナル述語論理は1:1対応する」ということです。あくまでリレーショナルモデル界隈を説明・分析する道具・枠組みのことであって、一般的集合論と一般的述語論理の話ではありません。(詳細は別途記述予定。)[追記]現場の集合論としての有界素朴集合論」参照[/追記]

推論や証明のことを演繹〈えんえき〉といいます。演繹能力を備えたデータベースが演繹データベースです。ここで言う演繹データベースは、特に(仮称)リレーショナル述語論理の演繹能力を備えたものです。そのような演繹データベースが、奥野さんにとっての理想のデータベースなのではないでしょうか。

(仮称)奥野流データベース理論の問題点は:

  1. アイディアはある(ように見える)が、明確な定式化には至っていない。
  2. アイディアの(断片的)記述においても、勘違いや過ちがある。

この残念さが『理論から学ぶデータベース実践入門』の各所に影を落としていると言えるでしょう。

「矛盾」て何なんだろう?

奥野本p.68の表データ(リレーション)の一部を例にします。背後に、IT系の学校のデータベースがある、という設定です。あくまで説明用の事例なので、現実性はありません。

氏名 授業 学年
桂小五郎 リレーショナルモデル 2
坂本龍馬 リレーショナルモデル 1
坂本龍馬 コンピュータアーキテクチャ 2

奥野さんは、同一人物(学生)'坂本龍馬'の学年が1と2になっているから、「矛盾が生じた」(p.69)と述べています。一方zhanponさんは、この状況は「論理的な矛盾ではなく、「1人の人間が異なる2つの学年をもつことはない」という大学のルールに対する不整合である。」と指摘しています。

ここでは、奥野さんの表現を採用して「矛盾」を使います。ただし、注意を喚起するために《矛盾》と書きます。

さて、この《矛盾》は何に由来するのでしょうか? これが《矛盾》だと判断する根拠は何でしょうか? ここでちょっとした実験をしてみます。先の表データは《矛盾》しているとして、次の表データならどうでしょうか?

氏名 授業 成績
桂小五郎 リレーショナルモデル 2
坂本龍馬 リレーショナルモデル 1
坂本龍馬 コンピュータアーキテクチャ 2

《矛盾》していると感じますか? 「'坂本龍馬'君の'リレーショナルモデル'の成績が1」「「'坂本龍馬'君の'コンピュータアーキテクチャ'の成績が2」と解釈すれば、《矛盾》はありません。次の表データならどうでしょう。

評者 書籍 評価
桂小五郎 リレーショナルモデル 2
坂本龍馬 リレーショナルモデル 1
坂本龍馬 コンピュータアーキテクチャ 2

「'坂本龍馬'氏による書籍'リレーショナルモデル'の評価は星1つ」、「'坂本龍馬'氏による書籍'コンピュータアーキテクチャ'の評価は星2つ」と解釈すれば、《矛盾》はありません。

僕がやったことは、表の属性名(見出しの名前)を変えただけです。属性名の変更に関して、奥野本p.62から引用すると:

既存の属性名を変更するだけであれば、特に、論理式としての構造に変化はありませんので、リレーションが表す意味にも変化はありません。どのような名称で呼ぼうが、論理的な意味は同じです。

論理的な意味が同じなのに、どうして《矛盾》したり《矛盾》しなかったりするのでしょうか? これこそ矛盾(オカシナこと)じゃないでしょうか。

演繹データベースと矛盾: 奥野さんは(まーまー)正しかった

前節の種明かしをしましょう。我々は、「'氏名'、'授業'、'学年'、'成績'、'評者'、'書籍'、'評価'」といった言葉から、無意識に意味を連想します。連想した意味に基づき常識を働かせます。

  • 同一学生が異なる2つの学年をもつのはオカシイ。
  • 同一学生が異なる2つの授業で異なる成績なのはオカシクない。
  • 同一人物が異なる2つの書籍に対して異なる評価をするのはオカシクない。

オカシイかオカシクないか(《矛盾》があるかないか)の判断は、解釈と常識によるのです。zhanponさんの指摘どおり、大学(学校)のルール/世間のルールとの整合・不整合の問題です。

となると、学校なり世間なりを考慮しないと《矛盾》の判定はできないことになります。無意味・無味・無臭な表データ(リレーション)だけ見ても、《矛盾》の検出なんて出来っこありません。先入観なしに次の表データを見てください。《矛盾》のあるなしは、サッパリ分からないはずです。

属性-1 属性-2 属性-3
桂小五郎 リレーショナルモデル 2
坂本龍馬 リレーショナルモデル 1
坂本龍馬 コンピュータアーキテクチャ 2

《矛盾》の判定基準は、外部世界のルールに由来するのです。演繹データベースのメリットのひとつは、外部世界のルールも、データベース内に格納できることです。「同一学生は同一の学年をもつべし」は次の論理式で書けます。

  • ∀x∈D_氏名.∀i, j∈D_学年.( 学生学年(x, i)∧学生学年(x, j) ⊃ i = j )

これだけだと分からないかな、説明を補足:

  • D_氏名 は氏名の値(たぶん文字列)全体の集合です。RDB用語では、基本的値の集合をドメインと呼ぶので接頭辞'D_'を付けました。
  • D_学年 も同様に、学年の値(たぶん整数)全体の集合です。
  • 学生学年(x, i) は、氏名xの学生が学年iであることです。

さて、上の表データから、学生学年(x, i) の形の述語を抽出します。

外部世界(学校)のルールと、表データの一部から、3つの論理式が得られました。これらに対して、述語論理の推論を施してみます。

 ∀x∈D_氏名.∀i, j∈D_学年.( 学生学年(x, i)∧学生学年(x, j) ⊃ i = j )
-------------------------------------------------------------------------
    ↓ x = 坂本龍馬 と具体化する。
 ∀i, j∈D_学年.( 学生学年(坂本龍馬, i)∧学生学年(坂本龍馬, j) ⊃ i = j )
--------------------------------------------------------------------------
    ↓ i = 1, j = 2 と具体化する。
 学生学年(坂本龍馬, 1)∧学生学年(坂本龍馬, 2) ⊃ 1 = 2

学生学年(坂本龍馬, 1)、学生学年(坂本龍馬, 2) を仮定として使えるので、

 学生学年(坂本龍馬, 1)∧学生学年(坂本龍馬, 2)
 学生学年(坂本龍馬, 1)∧学生学年(坂本龍馬, 2) ⊃ 1 = 2
-------------------------------------------------------
    ↓ モダスポネンス
   1 = 2

一方で、「1 = 2 じゃない」ことは真だと認められるので、

 1 = 2    ¬(1 = 2)
--------------------
    ↓ ∧の導入
 (1 = 2)∧¬(1 = 2)
--------------------
    ↓ 矛盾の導入
    ⊥

最後の⊥は論理的矛盾を表す記号です。ほんまもんの矛盾です。

外部世界のルールと、表データ(リレーション)の情報を、述語論理の論理式の形に書いて、述語論理の推論をすれば、論理的矛盾が導けます。つまり、この演繹データベース=述語論理系は矛盾を含むのです。

結果的に、奥野さんの《矛盾》は確かに論理的矛盾であり、「矛盾」の使用法に(少なくともこのケースでは)間違いはありません*3

しかしこれは、演繹データベースを想定した場合のことです。そういう想定が読み取れる書き方はされてません。それ相応の深読み、忖度が必要です。また、矛盾が生じるのは演繹データベース=述語論理系全体の性質であって、「リレーションに矛盾が生じる」という言い方は不用意に過ぎます。そもそも、「矛盾」を滅多矢鱈と使い過ぎなんですよね*4

演繹データベースで出来ること

せっかくなので、演繹データベースでもう少し遊んでみましょう。次のように仮定します。

  • 履修(x, m, y) とは、氏名xの学生が名前mの授業をy年度に履修すること。
  • yが今年度なら、現在履修中。
  • yが過去なら、履修済み(落第してない)。

授業'SQL入門'を履修するには、'リレーショナルモデル'を履修している必要があるとします。同様に、'SQL応用'を履修するには、'SQL入門'を履修している必要があるとします。これらの条件は次のように書けます。

  • ∀x∈D_氏名.∀y, z∈D_年度.( 履修(x, SQL入門, y) ⊃ 履修(x, リレーショナルモデル, z)∧(z < y) )
  • ∀x∈D_氏名.∀y, z∈D_年度.( 履修(x, SQL応用, y) ⊃ 履修(x, SQL入門, z)∧(z < y) )

こんな学校のルールが演繹データベースに入っていれば、履修(勝海舟, SQL応用, 2017) から、履修(勝海舟, SQL入門, y)∧(y < 2017) や 履修(勝海舟, リレーショナルモデル, z)∧(z < 2016) が、論理的な推論で導出できます。

また、'リレーショナルモデル'を受けてない学生が'SQL入門'を履修登録していれば、矛盾が生じます。矛盾検出機構や矛盾防止機構が付いていれば、学校のルールが破られる事態に対処できます。

次に否定(論理記号¬)を含む例を考えてみましょう。

  • ∀x∈D_氏名.∀y∈D_年度.( 学生学年(x, 1) ⊃ ¬履修(x, Javaプログラミング, y) )

これは、「1年生は'javaプログラミング'を受けられない」という意味です。x = '坂本龍馬', y = 2017 として、このルールが守られているかチェック(真偽判定)するにはどうするのでしょう。まず、学年学生(坂本龍馬, 1) という情報が見つかり、含意(論理記号⊃)の左が真だと分かったとしましょう。あとは、¬履修(坂本龍馬, Javaプログラミング, 2017) の真偽判定です。

奥野本p.51で説明(?)されている閉世界仮説の眼目は、¬履修(坂本龍馬, Javaプログラミング, 2017) のような否定命題の証明を、履修(坂本龍馬, Javaプログラミング, 2017) の検索(一種の証明と考える)失敗で代用していいよ、ってことです。「Pである証拠が見つからなかったら、Pでない」と考えるのです。閉世界仮説のもとで、否定命題も扱えるようになります。

と、こんな感じで、現状、CHECK制約/表明/トリガーなどの手段で実現していることが、演繹データベースにおいては一様かつクリアに表現できるのです。カッコイイですよね。奥野さんはたぶん、次のように考えているのでしょう。

  • 理想のデータベースは、演繹データベースである。
  • リレーショナルデータベースは、不完全な演繹データベースである。
  • リレーショナルデータベースを、演繹データベースに(その部分系として)埋め込める。

述語論理をチャンと使おう

奥野本『理論から学ぶデータベース実践入門』において、次の2点を改善すべきだと述べました。

  1. 論理をほとんど使ってない。 → 述語論理をチャンと使う。
  2. 外部世界を考慮してない。 → 外部世界をチャンと考慮する。

「本の第2章を削除する」修正案だと、「論理をほとんど使ってない」のは問題になりませんが、現状だと「何のための第2章か?」なんですよ。

p.61で射影を論理的に説明するとき、なぜか存在量化子(限量子)に触れてないんです。ここで存在量化子使わなかったら、どこで使うんじゃい?! p.57の結合(ジョイン)の論理的説明でも、肝心の存在量化子付けてないし、p.51のリレーション=述語の説明では、不要な全称量化子を付けちゃっているし、p.136では事例と論理を絡めたけど、論理側の説明がスッカリ間違っているので、これはないほうがいいし。使うべきところで使ってないか、使わないほうがマシかです。

奥野さんは、リレーショナルモデルは一階述語論理に基づくので、二階述語論理は要らないと書いてますが、それは違います。そういうことじゃない。キー制約関数従属性制約結合従属性制約などの制約を、チャンと定義・説明するなら、二階述語論理を使わざるを得ないです。「いつでもチャンと説明しろ」とは言いませんが、論理を使って説明するなら、そうなります。以下に例を挙げましょう。

Aを属性集合として、タプルtのAによる射影を t[A] と書くことにします。例えば、A = {氏名, 生年月日} のとき、t[{氏名, 生年月日}] が射影したタプルです。二重の括弧が煩雑なので、t[氏名, 生年月日] と略記します。

{氏名, 生年月日}がRのキー(候補キー)になっていることは、次のように書けます。

  • ∀s, t∈R.(s[氏名, 生年月日] = t[氏名, 生年月日] ⊃ s = t)

この論理式自体はスーパーキーの条件ですが、現実には候補キーの条件しか書きません。

さて、上記の論理式は、固定したRに関しては一階述語論理の論理式です。しかし、Rを動かしたらどうでしょうか。現実のデータベーステーブルを考えれば、そこに格納されるリレーションは変化します。Rが変化してもキー制約を満たすことを言いたいなら次の論理式でしょう。

  • ∀R∈R.∀s, t∈R.(s[氏名, 生年月日] = t[氏名, 生年月日] ⊃ s = t)

ここで太字斜体のRは、テーブルに許容されるリレーションの集合です。リレーション(タプルの集合)の集合であるRや、リレーションの束縛変数Rなどが登場しているので、上記論理式は高階(二階以上)の述語論理式です*5

属性集合AとBのあいだに関数従属性があることは次のように書けます。

  • ∀R∈R.∀s, t∈R.(s[A] = t[A] ⊃ s[B] = t[B])

これももちろん、高階の述語論理式です。A = {氏名}、B = {学年} とすると、

  • ∀R∈R.∀s, t∈R.(s[氏名] = t[氏名] ⊃ s[学年] = t[学年])

そうです、最初の例に挙げた「1人の人間が異なる2つの学年をもつことはない」です。詳しく言えば、「sとtが同じ氏名を持つ(同一人物)ならば、sの学年とtの学年は同じ」です。この制約条件は、特定のリレーションでたまたま成立することではなくて、時間がたとうが別な学校であろうが成立する普遍的法則です。その普遍性の表現のためには、高階の述語論理式が必要なのです。

露骨に高階述語論理を出すのは憚〈はばか〉られるにしろ、制約や正規化の背景に高階の構造があることは意識して説明すべきだと僕は思います。

外部世界をチャンと考慮しよう

前節で、「1人の人間が異なる2つの学年をもつことはない」のようなルール/制約が登場しました。これらのルール/制約は、どこからやって来るのでしょうか? リレーションをいくら眺めても、ルール/制約は書き込まれていません。ルール/制約は、リレーションの世界で発生したものではなくて、外部世界に由来します。

つまり、外部世界に対する認識がなければ、データベースのルール/制約を書き下すことは出来ません。外部世界の構造は、例えばER図で表現されるでしょう。そのER図にルール/制約は写し取られているはずです。(詳細は別途記述予定。)

奥野さんはp.4で、「実は、ER図とリレーショナルモデルは何の関係もありません。」と書いています。外部世界のモデリングと、リレーショナルモデルを混同するな! という趣旨でしょうが、「何の関係もありません」は言い過ぎです。もし、外部世界とリレーショナルモデルが無関係なら、ルールや制約は、その動機も根拠も失います*6

別な思考実験をしてみます。今、矛盾検出が出来る演繹データベースがあるとしましょう。学生の履修登録をしたら矛盾が生じたとします。履修テーブルのデータが悪かったのでしょうか? それとも学校の履修ルールに間違いがあったのでしょうか? どちらが悪いのかはシステム内で判断できません。

そんなとき我々は、外部世界、つまり現実を見ます。現実と較べて、履修登録を取り消すか、または履修ルールを修正します。最終的な拠り所は、リレーションでもルール/制約でもなく、現実=外部世界です。

論理には構文論(証明論)と意味論(モデル論)があります。リレーション/ルール/制約を記述する論理式は構文論に属します。矛盾が生じることは構文論的(証明論的)現象です。「で、どっちが実際に正しいの?」は意味論的(モデル論的)判断です。構文論/意味論的のどちらも必要なのです。

おわりに

冒頭で、「良い点と悪い点の両方を、できるだけ客観的に記述する」と言いましたが、悪い点の指摘のほうが多かったようです。まー、タイトルが「どこがダメなのか」なんでお許しを。

『理論から学ぶデータベース実践入門』の良い点は、純正リレーショナル主義が徹底しているところです。「リレーションは値である」と強調し、リレーショナルなモノと非リレーショナルなモノを区別して話を進めています。

“値であるリレーション”と“器であるテーブル”を区別するために、リレーション変数(p.26)*7という概念も紹介しています。データベースの各種操作を、値と変数というプログラミングの概念で説明できるでしょう。(詳細は別途記述予定。)

僕が目を通してない第9章以降では、一流のデータベース技術者である著者の経験と知見が活かされていることが期待できます。

と、そろそろこの記事はおしまいにします。それにしても、「(詳細は別途記述予定。)」をイッパイ入れちゃったな。いつになるか分からないし、全部書けるかも不安ですが、出来る限り宿題は果たしたいと思います。

*1:奥野さんの書きっぷりは、論理をやった人間を苛立たせるものがあるように僕は感じます。想像ですが、zhanponさんも、幾分か感情的に反応したのではないでしょうか。感情的だったので勇み足をしたんだろう、と -- そう思うのは、僕が若干感情的だからです。つまり、「ムッとなってやった 反省はしていない」。なので、僕も勇み足や言い過ぎがあるかも知れません。
[追記]zhanponさんに確認をとったところ、Qiita記事は「完全に怒り駆動で」書いた、とのことでした。https://twitter.com/zhanpon/status/917759680360751104 ; 文面は怒ってないし、「論理学を誤解して欲しくないので」という名目もちゃんと付いているけど、判断力に影響が出てたと思います。[/追記]

*2:このモデルは、モデル論における“モデル”で、構文としての論理に意味や妥当性を与える実在としての構造物のことです。

*3:要するに、「オカシイことが起きた」とき、オカシイかどうかを判断する論理式を体系内に放り込んでおけば、「矛盾が生じた」と言い直せるのです。

*4:執筆当時のマイブームだったのでしょう。

*5:実際的には、KeyConstraint氏名,生年月日(R) := ∀s, t∈R.(s[氏名, 生年月日] = t[氏名, 生年月日] ⊃ s = t) と高階述語KeyConstraint氏名,生年月日を定義して、それを使ってリレーション型(外延としてはリレーションの集合)を定義することになるでしょう。

*6:リレーショナルモデルをリレーションの算術(代数的演算体系)とだけ捉えて、「ER図とは無関係」と言ったのかも知れません。そうだとしても、その演算体系によりモデル化する世界を無視するのはいかがなものでしょう。

*7:「リレーション」という言葉をずっと使っているのに、なぜかここだけは「関係変数」となってます。