内的・外的ということと外部キー


内的・外的という考え方がある。

野矢茂樹ウィトゲンシュタイン『論理哲学論考』を読む (ちくま学芸文庫)」 P-50
それが変化したとしてもあなたがなお同一人物であり続ける場合、その性質や関係はあなたという対象にとって
「外的」であるといわれる。それに対して、その性質や関係が失われたならば、もはやあなたはいままでと同一
人物のあなたとはみなされえなくなる場合、その性質や関係は「内的」ということになる。

「変わったらそいつじゃなくなる」ものだけが「内的」なのだから、モノについてはほとんどの性質は「外的」ということになる。
私の属性は、名前・性別・年齢など、思いつきそうなものは全て外的だ(名前を変えようと性転換しようと私が別人になるわけではない)。
このことは、モノをデータベースに写し取った resource についても当てはまる。そのへんのデータベースを眺めてみると、resource にはめったに内的属性がない。

resourceにIDを振らないとデータ構造が安定しない理由

例えば社員マスタ上の社員番号は、社員名なんかと同じく、内的属性ではない。
現実世界では、私の社員番号を変更しても私が別人に変わるわけではない。
ここから、resource にIDを振らないとデータ構造が安定しない理由がわかる。
自然キーを主キーに選定する条件は

  • not null
  • unique
  • 変更されない

の3点では足りない。

  • 内的属性であること(=それが変わったら、違うものとして記録しなくてはならない)

を満たさない自然キーを主キー/外部キーにすると、潜在的な危険を抱えることになる。


「コロコロ変わらないコード体系を作ればよい」と言ってみたところで、そのコードが内的属性ではない以上=その属性が仮に変わったとしても、レコードが現実世界の同じ対象を指し続けることができる以上、コード体系に依存したデータベースは安定しない。
例えばスーパーSEが、導入した会社の中では絶対重複も枯渇もしない部品コード体系を発明して*1、いろんな会社でそれを使うように指導したとする。
この場合も、クライアントの2社が合併したら部品コードが大量に重複するかもしれない。ほんとにそんなことがあったらコントだ。

内的属性である自然キーがあればIDは要らない

resourceに記録された「内的属性である自然キー」とは何か。
例えば姓名判断の事例データベースに、こんな姓名マスタがあるとする:

姓名マスタ

姓名(PK) 天格 人格 地格 総格 外格
佐藤聡 25 32 15 39 8
鈴木茂 17 12 9 25 14

姓名というものにとって、その漢字表記は内的属性だ。それが変わったら別の個体になってしまうから。
だからこのマスタの場合、姓名フィールドを主キー/外部キーにすることにデータ構造上の問題はない。
このresourceに「姓名ID」というIDを導入して、別のテーブルから外部キー参照させてみたところで、データ構造の安定度を増すことにはならない。
この意味ではIDは要らない*2

eventではどうか

resourceと違い、eventでは、自然キーが内的属性で構成されていることが普通にある。
こないだ描いた「はてなブックマークのデータモデル」では、「ブックマーク」テーブルを event(エントリーとはてな会員の対照表)にしてある。
ブックマークにとって { 会員ID, エントリーID } は内的属性だ。会員ID・エントリーIDのどちらか一つでも変更されたら、そのブックマークは「別のブックマーク」に変わってしまう。


ほんとに書きたかったのはこっから先の話で、それは「内的属性のあるeventにIDを導入すると微妙な問題を呼び込むことがある」という話なのだが、力尽きた。
先走ってアウトラインだけ書いてしまうと

  • 外部キーというのはポインタ
  • 楽々ERDレッスン (CodeZine BOOKS)に書かれている通り、外部キーを使って参照したいのはポインタの値じゃなくてポインタが指している先のもの
  • 内的属性&自然キーなフィールドを外部キーにしないで、IDを外部キーにすると、IDの指す先が「別のもの」に変わっている可能性がある
  • 上記問題を回避する役目はアプリケーションが負うことになる

みたいな話。

*1:例えばコードをただの連番にするとか

*2:物理設計上の意味はある。ストレージが節約できるとか