たなかこういちの開発ノート

システム開発に携わる筆者が、あれこれアウトプットするブログ

サロゲート単独主キー vs 複合主キー問題、復習編

こちらの会に参加いたしました。
 
“予習編”の記事もご覧ください。
 
 
懇親会含め活発に意見交換がなされ、いわゆる“学びしかなかった”会となりました。
 
このテーマ立ては非常に多くの文脈を含んでいて、それを紐解くこと自体、複合主キーを的確に見出すのと同じような困難さがあるように思えました。
 
DDDでもそうなのですが、「ユビキタス言語を捉え、定義せよ」といいつつ、DDD自体を語る言葉にブレが内包されたままです。(※DDDの自己言及的な性質)複合主キー問題もまた、この問題の構造モデル自体にバリエーションがあるようです。まーそれも当然で、DDDのいう境界付けられたコンテキストが多様に異なるところの立場から語られているからです。
 
改めて論点まとめ
 
それでも、論点は、つまりは文脈は、次の三つに集約されそうです。
 
イ.単独主キー主義者への疑問

単独主キーが強制されないプラットフォームでも、機械的に「レコードID」を設けてしまう設計者がいるがそれはなんなのか?

 
ロ.実装、物理設計への取り組みにおいて
論理モデルで複合主キーを捉えるべきことに異論を持っている者はいなくて、それを実装あるいは物理設計するときにどうするかにおいて、考え方や立場の違いがある。
a) モデリング派
・キーの問題はモデルの問題
・実装詳細を如何に正しく(=モデルからずれずに)実施できるかは別の問題(≒関心外)
b) モデルと実装の乖離の少ない方式を選択すべき派
・論理モデル上複合主キーを認識できているなら、それを最も素直に実装できるRDBで、素直にそのまま複合主キーを定義するのが良いに決まっている(※ややERモデル原理主義)
c) まさに“保守系”実務派(※業務仕様をERモデルで受け止める系)
・サロゲートキーを導入することで制約(ビジネスルール)に関わる仕様決定を(良い意味でも悪い意味でも)遅延させることができる
・肯定的に言い換えると、サロゲートキーを導入することで、関係制約に関わる仕様変更に対する柔軟性を確保できる
d) “革新系”実務派(※業務仕様をロジック層で賄う系)
・論理モデルで捉えられた更新制約はAPI層を設けてそこに担わせ、そのG/W経由を必須とすればよい
∴常に複合主キーで実現しなければならない、とは必ずしも思わない
・昨今はRDB以外の永続化装置を用いるケースも多い; そのとき複合主キーが使えないものもある
e) プラットフォーム自体の構築論派
・Salesforce、各種ERP、実はOracle RDBMSだって、プラットフォームは多様な定義を受け入れ可能とするために、内部的にはサロゲートキー(に相当するものを)を用いている訳である(※プラットフォーム自体はスキーマ自体を操るので、プラットフォームの内部目線では、いずれも“ソフトスキーマ”的にキーを扱えるような仕組みを内包しているものである)
f) 複合主キーってよく知らない派
・そんな複雑なデータモデルに出会った事がないので、モデルから実装への転換で悩んだことが無い、さらには悩む可能性があること自体知らない
 
ハ.モデルとしての関係制約を、システム実装のどこで表現するか
「ロ.」の実装や物理設計をどうするかという考え方は、構築されたシステムのどのレイヤーにモデルの関係制約の実装を担わせると、実装の上で仕様が安定するだろうか、という観点からの評価と表裏になっている。この観点からは、次のように整理できると考える。
(i) 現在でも、最も安定して仕様をエンコードできる方式は、ERを表すところのDDLである派
b), c)
(ii) 業務のソースコードにエンコードできる派
d), 立場違うがe), ややa)
(iii) 無関心派
f), ややa)
 
「単独サロゲートキー主義」 vs 「複合キー重視派」問題に対する一つの解答
 
懇親会の席で、古関氏だったかと思いますが(※違っていたらすみません。)一つ意見をいただきました。
 
まず、“予習編”の記事に書いたことを長いですが要点を引用します。
 
-----(ここから)-----
この論点はこちらのエントリーでは次のように言及されている。
 
-----(ここから)-----
サロゲートキーを使おうが使うまいが、複合主キーは必要なのですね。その上で、サロゲートキーを使うメリットが、二元的キーモデルの煩雑さ甘受するというデメリットを超えるのか、という話だと思います。
-----(ここまで)-----
 
・・・
 
つまり端的に、機械的に“レコードID”を導入して、ジョインや外部参照には常にこの代用単独キーを用いる。その一方、それ自体の存在制約は別途代替キーで担う、こういうやり方にメリットがあるのか?という問いだと思います。
 
・・・
 
自分としては次の観点が鍵になるかと思っています。こちらの記事にも一言言及されていた次の観点です。
 
-----(ここから)-----
複合キーはデータを特定するというよりもデータ間の関係(制約)を表している
-----(ここまで)-----
 
“二元的キーモデル”は、まさにデータを特定する役割のキーと、関係制約・存在制約を表す役割のキーとを分離しているのだ、と捉えられる気がします。
 
・・・
 
関係制約に対する仕様変更は、どういう頻度で発生し得るでしょうか。この様な問題に対する柔軟さをどの程度備えたら良いでしょうか。この辺に鍵があるように思います。
-----(ここまで)-----
 
古関氏は、この問いに対して以下のように考えるといわれました。(※私の意訳、解釈がはいっていますので、若干本意からずれているかもしれません。)
 
単独サローゲートキーが、仕様変更への柔軟さをもたらす、というのは全くその通りだろう。だとして、それでいて複合主キーを用いるメリットとは、仕様変更発生時に、静的にチェックができるということではないか。
 
すばらしい着眼点でした!主キーに関するすべての主張をこれで統一的に説明できると気づきました。すなわち、サロゲート単独キー vs 複合キー問題は、動的型付き言語と静的型付き言語、どちらを選ぶか、という問題と全く相似だったのです!
 
動的型付け言語 vs 静的型付け言語もまた常に盛り上がるねたです。
 
・仕様変更への柔軟さか
・静的チェックを重視するか
・事前に設計するか、後からテストするか
・仕様を実装にエンコードすることの意味は?
・仕様を実装にエンコードすることのオーバーヘッドは?
・仕様は決められるのか?
 
単独サローゲートキー主義とは、動的型付け言語を指向することに対応し、複合キー重視とは静的型付け言語を指向することに対応するのです。
 
・単独サローゲートキー & 動的型付け言語 ← 変更の静的チェックはできないが、最大限の柔軟さを確保
・複合キー重視 & 静的型付け言語 ← 仕様がコードに固定される代わりに、変更を静的チェックできる
 
本記事前半に様々な文脈や立場を挙げてみましたが、全てこの対立軸からの派生事項として説明できるでしょう。
 
◆以上