サロゲートキーの日常性と心得之条
「モノクロとカラーのどちらの表現を選ぶか」と訊かれて、映画監督はなんと答えるだろう。おそらく「どちらかを選べだって?愚問だね。必要に応じて使い分けるだけさ」と答えるだろう。同様に「サロゲートキーと複合主キーのどちらの技法を選ぶか」なんて訊かれても困る。どちらも必要に応じて使うだけの話で、どちらかが強制されるようなものではない。
実際のところ、複合主キーと同様、サロゲートキーも必要不可欠な技法だ。それは設計者本人さえ意識しないまま、日常的に利用されている。たとえば多くの場合、受注テーブルの主キー(一次識別子)である「受注№」は、サロゲートキーの一種だ。次のモデルで説明しよう。
(1)受注情報のモデル1
+
|
└―…[受注見出し] 受注№,顧客id,受注日,...
+
|
└―∈[受注明細] 受注№,明細行番,商品id,
受注数,納期,...
受注情報は、出荷情報や売上情報と連係する。それゆえ、出荷作業が進行している途中で、受注テーブル上の顧客idの値が変更されたら面倒なことになる。これを避けるために、受注テーブル上の顧客idは(少なくとも受注として確定した後では)変更不可項目として扱われるのがふつうだ。
(1)のモデルにおいて「受注見出し」の「顧客id」が変更不可項目だとすれば、(2)のモデルと性質が同じになる。主キーに含まれる項目は基本的に変更不可だからだ(注1)。もともとのデータ要件はこちらだったと考えても間違いではない。
(2)受注情報のモデル2
+
|
└―∈[受注見出し] 顧客id,受注行番,受注日,...
+
|
└―∈[受注明細] 顧客id,受注行番,明細行番,商品id,
受注数,納期,...
しかし実際には、(2)のように実装することはまずない。受注データの性格上、単一の手がかり(キー)でデータを特定できるようにしておきたいからだ。そこで、本来の「顧客id+受注行番」の複合主キーの代わりに、システム内でユニークな値をとる「受注№」をサロゲートキーとして導入する。その結果が(1)なのである。
このように、サロゲートキーはことさら珍しいものでも、忌避されるものでもなく、日常的に利用される。しかしそれは強制されるようなものではない。強制されることで、データ要件の精妙な色合いが捨象されかねないからだ。たとえばデータ要件において、F(id1, id2)=属性1 の関数従属性が存在するとしよう(id1もid2もナチュラルキーではないとする)。素直に設計すれば次のようになる。
(3)素直なモデル
[テーブルA] id1, id2, 属性1
サロゲートキーが強制される開発環境において、(3)のままでは実装できない。次の(4)のように、サロゲートキー(id3)とユニーク制約{id1,id2}とを組み込んだ形に変形しなければいけない。同時に、id1やid2の値が更新された場合に備える必要もある(注2)。これらの「正規化違反の報い」を引き受けなければ、遅かれ早かれデータベースは矛盾をかかえる。
(4)サロゲートキーを組み込んだモデル
[テーブルA] id3, 属性1, {id1, id2}
このように、あえてサロゲートキーを組み込むことで、設計者にはより慎重さが求められる。その慎重さは隠然としたコストになるので、このテクニックは必要と判断された場合以外に使わないほうがいい。つまり、サロゲートキーを利用するかどうかは、設計者の主体的な判断に委ねるべきだ。
とはいえ、海外製を中心にしてサロゲートキーを強制する開発環境がすでにいくつか出回っている。それらの利用が前提となっている開発プロジェクトもあるだろう。そういう事情から、サロゲートキーを組み込む際の注意事項があらためて喚起される必要がある。次のオキテを覚えて、サロゲートキーを安全確実に運用しよう。
「サロゲートキー心得之条」必要なユニーク制約が組み込まれているか注意すべし。また、ユニーク制約に含まれる項目値の更新に対処できているか注意すべし。なお、以って怠りし由(よし)にて死すとも、屍拾う者なし。死して屍拾う者なし
注1.一部のDBMSでは、主キーであっても値の変更が許される。これを柔軟だとか便利だとか思ってはいけない。本来ならば、アプリが主キーの値を変更しようとすれば、DBMSはそれを拒否する最終関門となるべきだ。もし主キーの値を変更したくなっているとすれば、ナチュラルキーを主キーにしているといったDB設計上のミスが疑われる。
注2.id1やid2を更新する処理を作らないのが手っ取り早いが、そういう処理が存在しなければいいだけの話ではない。交代してゆく保守担当者に対して「id1やid2は本来は主キーなので、値が更新されないようにしてください」という意向が申し送られる必要がある。
| 固定リンク
この記事へのコメントは終了しました。
コメント