6月28日に「「単独主キー主義」の是非を問う<超高速開発コミュニティ& 第57回IT勉強宴会in東京>」というイベントに参加しました。大変刺激的なイベントでした。システム開発の本質が浮き上がってきたように感じましたので、そこで考えたことを中心に書きたいと思います。
イベントの趣旨は以下の通りです。
https://benkyoenkai.connpass.com/event/58333/
元々は渡辺幸三氏が以下の記事をアップした所から始まります。
「単独主キーでもDB設計は楽にならない」
http://watanabek.cocolog-nifty.com/blog/2017/05/db-ae3e.html
また、当イベントの前提となる情報は田中浩一氏が以下に纏めてくださっています。
http://tanakakoichi9230.hatenablog.com/entry/2491274126
イベント当日の内容と懇親会での内容も同氏が以下に纏めてくださっています。
http://tanakakoichi9230.hatenablog.com/entry/2491274126
イベントで起こった内容については上記でほぼ全て記されていますので、ここではその後に考えたことを記します。
これまで私自身はエンタープライズ系(所謂基幹)システムの開発を長年行ってきました。そのため以降の話は基幹系の業務システムを前提としています。
話を始める前に複合主キーと単一主キーの考え方について簡単に振り返ります。
上記の渡辺氏の記事にある素朴な例として示されているのは契約仕入単価の例です。
ものすごく単純に要約すると、この例では、
・仕入先ID
・商品ID
・契約開始年月
という3要素で仕入単価を決める形になっています。
(これは当然企業によって条件は違いますがここで例示されている企業の場合はこの3要素で単価決定するということです)
仕入先の情報群をまとめた「仕入先マスター」があり、商品の情報群をまとめた「商品マスター」があり、 その組み合わせに、さらに時間軸を持たせることで仕入れ単価が決まります。
この条件に間違いが無いと確信した場合、ERモデリングとしては上記3要素を複合キーとした「契約仕入単価マスター」が出来上がります。
ここで、さまざまな理由により複合主キーを許容しない場合は所謂サロゲートキーを主キーにして、3要素は属性項目となります。
複合キーのモデル=主キー[仕入先ID、商品ID、契約開始年月]、契約単価
単一キーのモデル=主キー[ID]、仕入先ID、商品ID、契約開始年月、契約単価
のような違いが生まれます。
単一キーにした場合の問題は渡辺氏の上述した記事に詳細に記されているのでそちらをご覧ください。
単一キーにする理由はいくつかあって、代表的には以下の2つだと思います。
1.開発する環境(フレームワーク、ツールなど)が複合主キーを許可していない
2.サロゲート単一キーにしておいた方が変化に強い
1についてはそもそもの制約なのでここでは議題にしません。
余談ですが、当社が開発した超高速開発ツール「TALON」はこのような制約を開発者に強いる事が無いようにするためにどのようなデータモデルでも制約なくシステム開発出来る事をそもそものコンセプトとしています。確かに開発ツールを開発する立場(ややこしい言い回しですが^^;)からすると単一主キーだけで構築する仕組みの方が簡単だと非常によくわかります。ここの話も凄く面白いのですが横道にそれるのでまた別の機会に。
2についての話が今回の主題となります。
上述した田中氏の記事にこんな一説があります。
「かつて次のような事例がありました。ある金融商品のシステムにおいて「証券番号」という自然キー(※システム採番の人工キーだが、業務に表出しているので自然キー扱い)があって、これをそのまま主キーにしていました。ある日、「同一の証券番号だが、通貨建ての異なる証券」を導入するような改定が発生しました。改定後は「証券番号」+「通貨」が主キーになりました。結局そこらじゅうのテーブルにカラムを追加して、そこらじゅうのジョイン条件を書き換えたように記憶しています。このような関係制約に対する仕様変更は、どういう頻度で発生し得るでしょうか。この様な問題に対する柔軟さをどの程度備えたら良いでしょうか。この辺に鍵があるように思います。」
これを読んで私はしばらく考え込んでしまいました。
確かに意味を持たないサロゲートキーで設計していればそこらじゅうのテーブルにカラムを追加するという作業は発生しないので柔軟であるといえる気がしました。
そして、これが非常に重要なのですが、設計者が設計する業務システムは不変なものではなく、将来に渡り変化する宿命を帯びています。(実態である業務は常に変化する可能性を持っているため)その時に主キーが意味を持っていなければ、本来のテーブル構造が持つ意味上のキー(上記例では仕入先ID、商品ID、契約開始年月)に変化が起きたとしても、主キーを変える必要なく、属性項目を追加すればテーブル構造の変更は完了です。他のテーブルに外部キーとしてつながりを持っていてもテーブル構造的には影響はありません。
これは一見説得力を持ちますが、良く考えてみると、テーブルを構成する意味上の主キーが変化するのでアプリケーションへの改修は当然必要となります。
さらに、影響度がテーブル構造には全く現れないので、各アプリケーションを精査してどこに手を入れるか慎重に決めて改修していく必要があります。
結局改修のコストは発生するがそのコストに違いがあるだけです。
むしろ、データベース構造を修正する必要がある複合主キーにキーを追加するような場合、影響度が可視化されています。
ERモデル上で影響する物を一瞬で特定できます(もちろんすべてではありませんが)。それにより影響するテーブルを利用しているアプリケーションに対して修正が必要とすぐにわかります。
これはコンパイラがあらかじめチェックしてくれる役割に近いのではないかと考えました。
私としては、そこで可視化されるメリットの方がデメリット(工数が多くかかる。ただしその工数差も調査やテストの時間を考えるとそれほど大きく違わないような気がしています)を上回ると感じました。
ここまでの話を懇親会でした所、上述の田中氏の記事でうまくまとめて頂きました。
「単独サローゲートキーが、仕様変更への柔軟さをもたらす、というのは全くその通りだろう。だとして、それでいて複合主キーを用いるメリットとは、仕様変更発生時に、静的にチェックができるということではないか。」
ここまでがイベントで考えた内容です。
そのイベント後に色々と考えていたらシステム開発の本質が現れてきた気がしました。
それは、システム開発の肝がどこにあるのかという事です。
私自身はエンタープライズ業務システムをずっと設計してきた経験から、業務システム開発に最重要なのはデータモデル設計であると強く考えています。 この主張はこちらのコラムに書いています。
入力の画面や出力の帳票からデータモデルは作られるのではなく、その企業の業務そのものから作られるデータ、流れ、データ間の関係を元に抽象化プロセスを経て作られる物だと考えています。
そして、そのデータモデルがその企業の業務とフィットしていて、抽象化プロセスにより変化に強いものになっていればシステム開発は高い確率で成功します。
重要だと感じたのは、全てを単一のサロゲートキーにした場合、開発の肝であるデータモデリング設計が徹底的に考え抜かれた物にならないのではないか?という点です。仕様変更への柔軟さとは裏を返すと後工程へ問題先送りをしているという一面もあると思います。
画面・帳票からのピックアップや現行業務の流れを聞いてそのままモデル化するのは非常に危険です。
これこそが後工程の開発(特にユーザテスト)や将来の変化にかなり弱いものになります。なぜこの業務のデータ構造がこのようになるのか、一般的な形と違う場合はなぜ違うのか、またこの先も不変であると考えられるかという点を徹底的に考え抜いて形を決定すべきです。(これが抽象化プロセス)
その結果として、複合主キーで現在は定義されるテーブルが、この先変化する可能性がありそうだと考えたらキー構造を今の現実と違う設計にする行う事はあります。
先ほどの仕入単価の例であれば同一仕入先でも単価条件が複数あり(良くあるのはロットサイズ)、現状では仕入先ID、商品ID、契約年月で決まっているとユーザから説明を受けてそのままモデル化してしまうと顧客の業種などによっては危険かもしれません。 ロットサイズをキーに含めて置き、初期値として最大値を自動セットしておくなどしておけば将来ロットサイズ単位の単価に変化した時にほどんど変更なしで運用出来ます。(どこまでやるかがまさに設計者の力量を問われる職人的な領域だと感じています。やりすぎると不要な機能が単純に増えますので。)
このように企業の現状だけでなく広い視野で検討を行った末に設計していくのが設計者の責任だと私は考えていますが、これが最終的に全て単一サロゲートキーを前提に設計するとなるとそこまで考えるだろうかと思います。後工程の開発で仕様変更しちゃえば良いか、データモデルは今のままで出来るから責任を追及されることもないし、なんて思考プロセスになりそうな気もします。(邪推ですが^^;)
将来に業務上の変化が起きて、キー構造の変更が必要になった時に設計者の力量が問われます。この程度の変化も予期していなかったのか、となるのか、この変化は予期できる物ではないという納得があるのかジャッジされます。(本稼働後の変化については責任を問われることはありませんが、設計者にとっては非常に良い学びの瞬間になります。)
まだ考えが煮詰まりきっていない時点の結論ですが、複合主キーを許容しない場合は設計者が熟考したデータモデル作りをする責任感が薄くなってしまうのではないでしょうか。そしてその弊害は極めて大きいです。データモデルが脆弱だとどれだけ次フェーズ以降の開発・テストプロセスで苦労するかは業務系システム開発を経験している人の多くは実感があるのではないでしょうか。(ツールの制約上単一主キーしか扱えない場合は設計を厳密にして実装での変換を行い、実態としての主キーをキッチリ定義する事でここでいう責任感を持つことは可能だと思いますが)
ここからは余談ですが、イベントの中でデータモデリング自体を重要視しない(極端なケースではモデル設計すらしない)ような開発が結構あるという話が出ました。それでは求められているシステムになっているのかどうかをどうジャッジするのかというとテストフェーズで徹底的に業務視点のテストをすることでクリアするそうです。これは基幹系システムを作り続けていた人間からすると結構衝撃でした。データモデルで品質を確保するという考えとは真逆の考えです。これは適用する領域の違いだと思います。会計業務とつながるようなシステム(受発注や在庫管理、原価管理などの所謂基幹系)には全くマッチしないやり方で、SoE(System of Engagement)と呼ばれるデータの精度よりもあいまいなデータを色々と集めて利活用していく(ちょっと乱暴な書き方ですが)システムにはマッチするのかもしれません。私には未知の世界ですので、今後この領域についても色々と勉強していこうと考えています。
また、イベント中にデータモデルなどの設計情報は顧客に理解してもらうのが難しいという話があり、そこで超高速開発ツールを作りましたと発言しましたが、その辺の思いはこちらのコラムに書いています。
それでは今回はこの辺で。
文=古関 雄介