2010年12月26日

商品コードを主キーにするべきではない理由

リレーショナルデータベースのテーブルの主キーの設計については「ユニークになる項目だから必ず主キーにしないと行けない」というわけではなく、多くのDB設計者の間でも

- ID派(あえて別に自動採番のIDを付ける)
- コード派(ユニークになるものは出来るだけ主キーとする)

の2つに分かれる様だ。特に近年はRuby on Railsに代表される様に数値型の単一キーの存在を前提として作られているFrameworkが増えて来た事もあって、ID派の存在感が増しているらしい。

それぞれメリット・デメリットがあってどちらがいいのかはケースバイケースになるのかも知れないが、自分の場合はこれまでの業務システム開発の経験から、どちらかと言うと自動採番のIDを使う方がメリットが多いのではないかと思っている。やっぱりなんだかんだ言っても、「どうしてもこのマスターのコードを変えたいんだけど」と言われるケースが何度かあって、コードを主キーにしている場合に結構面倒な作業になってしまった事があるからだ。

ただ今回はあるプロジェクトにおいて「コード派」の技術者の方をやんわりと説得する必要があったので、「ID派」の根拠になりそうな情報を少し調べて見た。せっかくなので今回参考にさせてもらったサイトの引用とURLなどをまとめておこうと思う。

まずその前にひとつ思った事は、「主キーにする為にあえて付与したID」の事は「サロゲートキー(代理キー)」と言うよりも、「人工キー(Artificial Key)」と呼ぶ方がしっくり来る気がするという事だ。もちろん引用は原文のままにしておいた。


「サウスポーなSEの独り言 - テーブル設計」
テーブル設計上、どっちが良いか(…)ですが、私はお客様の要望が無ければサロゲートキーを採用します。
ナチュラルキーの代表的なものである顧客IDや社員番号、商品番号等は先程も書いたようにお客様(直接でなく間接的な意味も含め)が決めたものです。そしてその決め方、不変である保証はいつ(お客様の都合により)変わるともしれないのです。...

「ぼそっと - 人は何故PKに人工キーを用いるのか」
メリット
- 変更に強い
- 自然キーの場合、複合キーがめんどくさい
- 最近のデータベースアクセスソリューションもの(平たく言うと、広義の意味でのORM)と相性が良い
デメリット
- 関連が分かりづらい
- ベテランの技術者は自然キーに慣れている人が多く、なかなかコミットしてくれない
- 既存システムはまだまだ自然キーのものが多いので、他システム連携的なところとは相性が悪いことが多いくらいにしか思っておらず、ようするにビジネス的な変更がシステムに与える影響を小さくする、一種の粗結合的なものだと思うのですが、...

「@IT - システムの寿命はコードで決まる!」
業務で利用するコードをテーブルの主キーとして利用することは、コード体系とデータベース設計を独立させるという観点からできるだけ避けるべきです。...

「Life goes on - 楽々ERDレッスンを読んでいます」
アプリ側の視点からすれば、業務コードを主キーに使うような下のような設計はもうありえないと思います。(...)主キーには業務上で一意に識別されているコードではなく、意味もないIDを使いましょうというのが今の主流だと思います。...

「Hot Heart, Cool Mind. - 主キーの設計①」
これはかなり以前からある論争で、大雑把にいうとコード派とID派という二つの立場の間で戦われている。
コード派 ... ユーザの目に触れるデータ項目(典型的にはコード)を主キーとする。複合主キーを許す。
ID派 ... ユーザの目に触れないデータ項目(自動生成したID)を主キーとする。複合主キーを許さない。...

「A.R.N [日記] - ID or not ID」
たしかにDB直接見て何かするような運用だと、複合主キーの方がわかりやすかったりするのはたしか。でも複雑なシステムで他のテーブルへの関連が沢山あるような場合、いったいいくつ項目持てばいいのかわからないくらい項目が増える場合がある(まぁ大半は設計が悪いだけだったりするのだけど、ID派の立場を取ればそもそもそのような状況はおこらないことを考えれば欠点には違いない)。
個人的には、複合主キーだとマスタに履歴を持つようなケースで変な主キーを選択しなければならなかったり、主キーを更新せざるを得ない場合があって気持ち悪いので、ID派ではあるけど、絶対にIDじゃなければダメだということを説得できるだけの論点が見出せないのが実情。...

「DBFlute - サロゲートキーと複合主キー」
ナチュラルキーをPKにするということは、業務に直結していて実装上でも直感的でありながら、 直結しているがために業務の変更の影響をもろに食らうということにつながります。確かに変更が発生するのは仕方のないことではありますが、 その影響は最小限にしたいものです。そのためには、テーブル間の依存関係を薄くすることが重要です。
サロゲートキーを導入することで、テーブル間の依存度合いは減り、業務変更のインパクトも(何もしない状態よりは)少ないものになります。 複合主キーの場合の方が効果は顕著ですが、単一キーでも同じ話です。例えば、ExampleDB の商品テーブルは、単一のナチュラルキーである商品ハンドルコードでユニークですが、商品IDというサロゲートキーを利用しています。 商品ハンドルコードは、業務で利用する値であり、業務変更でコード値の構成変更が発生する可能性があると想定したものです。


他に以下のサイトも非常に参考にさせて頂いた。

http://watanabek.cocolog-nifty.com/blog/2006/09/post_d032.html
http://www.oracle.co.jp/forum/thread.jspa?threadID=35007076&start=0&tstart=120
http://d.hatena.ne.jp/kanonji/20100224/1266972329
http://blogs.wankuma.com/ognac/archive/2006/11/27/47250.aspx
http://blogs.wankuma.com/ognac/archive/2007/06/19/81258.aspx
http://gihyo.jp/dev/serial/01/sql_academy2/000304?skip
http://d.hatena.ne.jp/suusuke/20081205/1228480992
http://d.hatena.ne.jp/samehada3/20070320
http://www.atmarkit.co.jp/bbs/phpBB/viewtopic.php?topic=42102&forum=26




.