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

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

サロゲート単独主キー vs 複合主キーの話、予習編

6月28日開催の下記のイベントに参加させていただく予定です。
 
 
 
開催の経緯としては、まずは、渡辺幸三氏の以下の記事があって、
 
 
この記事を受けて「IT勉強宴会」さんは、次のようなイベントを大阪にて開催しました。
 
複合主キーの扱い方(※イベントに参加された阪井氏による記事)
 
今回は、「超高速開発コミュニティ」、「IT勉強宴会」共催で、同テーマでの嬉しい東京開催が実現しました。
 
 
以下この問題の予習復習です。
 
用語整理
 
o 主キー(primary key)
レコードを一意に特定または指定するキー(=候補キー)の内、代表として定めたもの
o 代替キー/代理キー(alternate key)
主キー以外の候補キー
o 単独主キー
主キーが、一つのスカラー値あるいは単純型から構成される場合
o 複合主キー
主キーが、二つ以上のスカラー値の組み合わせ、あるいは複合型である場合
o 自然キー(natural key)
業務要件に表出しているキー
例1)会員はメールアドレスで識別する
例2)卸単価は「取引先ID」+「商品ID」+「適用開始日」で特定される
o 代用キー(surrogate key)
業務要件に表出しない、システムの設計上(※通常は物理設計段階で)導入したキー
例)会員の主キーとして、システム採番のUUID値を用いた
o 人工キー
システムとしては外部となる人間系や他システムから提供されるキー値ではなく、システムが内部で自動採番するキー; 人工キーは、自然キーである(=業務に表出する)場合も、代用キーである(=業務に表出しない)場合もある
 
事前知識
 
(1) まず用語の確認だが、「代替キー/代理キー(alternate key)」は、候補キーの内、主キー(primary key)とならなかったものを表す。例えば、会員マスターで、メアドと携帯電話番号を入力させた時、メアド、携帯電話番号はいずれも候補キーで、メアドを主キーと定めたのならば、携帯電話番号が「代替/代理キー」。対して、別途システム自動採番値を主キーとして用いることとしたならば(、かつ、それが業務に表出しないならば)、それが「代用キー(surrogate key)」。代用キーは、ほぼ必ず主キーとすることが意図されている。(※「代替/代理キー(alternate key)」を意図して導入する「代用キー(surrogate key)」というものは考えにくい。)
 
(2) 「代用キー(surrogate key)」と「人工キー」の関係については、こちらの記事中の以下の定義を採用する。
 
-----(ここから)-----
今回の議論でサロゲートキーはObject-IDやSalesforce-IDのように、利用者の画面や帳票には出さないものとしています。社員番号は人工キーですがサロゲートキーではありません。
-----(ここまで)-----
 
即ち、システム自動採番する「人工キー」は、表に出さないなら「代用キー」だが、表に出したら、その時点で「自然キー」に“格上げ”となる。
 
(2-2) 逆から言うと、定義上、自然キーは、非人工キー(=人間系から発生)の場合も人工キー(=システム自動採番)の場合もあるが、代用キーは常に人工キーである。
 
論点理解
 
(3) 自然キーをそのまま主キーとすることは多くの場合避けるべきで、そのために「人工キー」を導入することは定石であり、今回の課題ではない。
 
(ケース1)
会員マスターで、メアドが自然キーだったとして、それを主キーにしてしまったらメアドの変更ができないという事態になる。システム自動採番値(人工キー)を導入するのが定石。ただし、当該人工キーは、利用者側には表出させないかもしれないが、管理者側には「会員管理番号」としておそらく表出させるだろうから、定義上「代用キー」ではなく「自然キー」扱いとなることも多い。
 
(ケース2)
単価マスターは、「取引先ID」+「商品ID」+「年度」が複合自然キーだとする。しかし実際には、年度内改定も発生するので「取引先ID」+「商品ID」+「適用開始日」が妥当。かと思うが、適用開始日は営業調整で初期登録から実際の適用までに訂正が入り得る(=更新され得る)。結局、「卸値契約番号」という人工キーを導入するべき。ただし、「卸値契約番号」は業務上表に出すだろうから、定義上「代用キー」ではなく「自然キー」扱い。
 
単独主キーである「メアド」であれ、複合主キーである「取引先ID」+「商品ID」+「適用開始日」であれ、既存の自然キーでは更新禁止にできない場合に、人工キーの導入は容認される。そのようなケースではほとんど業務的にも当該人工キーを運用したいはずで、であるので定義上当該人工キーは(代用キーではなく)新たに自然キー扱いとなる。
 
(4) 「論理データ設計上、いずれにせよ複合キーをしっかり捉えなければならない。」今回のテーマにおいて、この主張に異論を持っている者はおそらくいない。それを実装としてRDB等を前提として物理設計する時、「代用キーによる単独主キー化(強制)」という選択肢の是非が問われている。
 
この論点はこちらのエントリーでは次のように言及されている。
 
-----(ここから)-----
サロゲートキーを使おうが使うまいが、複合主キーは必要なのですね。その上で、サロゲートキーを使うメリットが、二元的キーモデルの煩雑さ甘受するというデメリットを超えるのか、という話だと思います。
-----(ここまで)-----
 
(5) 最後に全く別の論点がある。「代用キーによる単独主キー化(強制)」プラットフォームに最初に馴染んだ者の中に、複合主キーの概念を学んでない者が現れている、という事実がある。また、そのようなプラットフォームは多く複合主キーがクリティカルな場面に出現しない程度の規模のシステムで用いられていることから、複合キーの概念を学んだにも関わらず無用の物と捉える者すら現れている。
 
意見まとめ
 
当初迷ったのは、「代用キー」と「人工キー」という用語の定義のぶれです。論点理解(3)で示したように、定義に基づくと「導入の必要性が定石として既に広く認知されている人工キーは、多く代用キーではなく自然キーとして扱われ得る。このような人工キーは、導入が是であることは既に明らかなので、今回の代用キー導入是非問題の議論対象外である。」と若干循環論法になってしまうように思います。それでも言わんとする点は、次のように対偶(?)逆(?)を云うといくらか明らかになります。「導入の必要性がDOA従来的には広く認知されていない人工キーは、多く自然キーに格上げされ得ない点で代用キーとなる。今回の議論対象は、このような代用人工キーを(例えばORMとの親和性のために)あえて導入する事の是非」となります。
 
そもそもこのようなお題となっているということの理解に至るまでに時間がかかりました。
 
 
そして論点理解(4)に引き継がれますが、つまり端的に、機械的に“レコードID”を導入して、ジョインや外部参照には常にこの代用単独キーを用いる。その一方、それ自体の存在制約は別途代替キーで担う、こういうやり方にメリットがあるのか?という問いだと思います。
 
多くのORMおよび支援ツールでは“レコードID”の設置は自動〜半自動で行います。“二元的キーモデル”は煩雑だとしても、それはORMツールの支援の元で維持管理することが前提なので、煩雑さは半減しているはずです。
 
自分としては次の観点が鍵になるかと思っています。こちらの記事にも一言言及されていた次の観点です。
 
-----(ここから)-----
複合キーはデータを特定するというよりもデータ間の関係(制約)を表している
-----(ここまで)-----
 
“二元的キーモデル”は、まさにデータを特定する役割のキーと、関係制約・存在制約を表す役割のキーとを分離しているのだ、と捉えられる気がします。
 
かつて次のような事例がありました。ある金融商品のシステムにおいて「証券番号」という自然キー(※システム採番の人工キーだが、業務に表出しているので自然キー扱い)があって、これをそのまま主キーにしていました。ある日、「同一の証券番号だが、通貨建ての異なる証券」を導入するような改定が発生しました。改定後は「証券番号」+「通貨」が主キーになりました。結局そこらじゅうのテーブルにカラムを追加して、そこらじゅうのジョイン条件を書き換えたように記憶しています。このような関係制約に対する仕様変更は、どういう頻度で発生し得るでしょうか。この様な問題に対する柔軟さをどの程度備えたら良いでしょうか。この辺に鍵があるように思います。
 
 
論点理解(5)は技術的な良し悪しとは全く別の問題です。道具の特性の問題と、それを利用する者の態度や指向の問題は本来切り分けるべきでしょう。ただ、ある道具の普及がある種の効果をもたらしたという“疫学的”な認識もまた無視できるものではないでしょう。
 
 
<6/30更新>
・タイトルを変更しました。
・本イベントは、「超高速開発コミュニティ」と「IT勉強宴会」との共催でした。その旨明記しました。
 
◆以上