Tech Racho エンジニアの「?」を「!」に。
  • 開発

代理キーとナチュラルキー

こんにちは、未だ勉強中のhachi8833です。

最近読んだ「楽々ERDレッスン (CodeZine BOOKS) 」という本は、Railsとは特に関係ない一般的なテーブル設計の解説ですが、データベースの教科書と現実の設計の間を埋めてくれる実践的な記述で、今の自分にとっては有用な本でした。Railsから入門して間もない人にはきっと有用だと思います。なおこの本が出版された2006年にはRailsはまだ1.0でしたが、現在も版を重ねているようです。さりげなく文章の質がよく非常に読みやすいのがありがたい点です。

楽々ERDレッスン

同書で繰り返し言及されていたのが、「顧客番号のようなコード番号をテーブルの主キーにしないこと」「主キーには、それ自体は意味を持たないアイデンティファイア(識別子)を使い、外部キーとして参照すること」というものでした。ほんの一瞬COBOLerだった頃の遠い記憶がほんのりと蘇ってまいりました。確かその現場ではコード番号体系を明示的に定め、それを主キーにするのが当たり前に行われていました。ついでながら、当時の業務システムのインターフェイスは、分厚いコード番号表を横に置いて番号を探して入力しないと先に進めないという何とも垢抜けないものでした。

このように意味を持つコードを主キーにする方法をナチュラルキーと呼ぶようです。典型的なのは銀行番号みたいなものでしょう。それにしてもいつの頃からか冗談みたいな銀行名が増えましたね。
銀行コード

他にも、郵便番号や電話番号などはそれ自体がキーとしての性格を持つので、ナチュラルキーとして使用されることが多くあります。

なおナチュラルキーだけでは重複が発生するような案件では、他のカラムと複合させることでユニークなキーにします。これは文字どおり複合キーです。

その一方、Ruby on Rails (ActiveRecord)では普通にデータベースを構築していくと、意味のあるコード番号を主キーにすることはなく、意味を持たない専用のキーが主キーとして使用されます。これを代理キー(サロゲートキー)と呼ぶようです。この場合、データベースではなくモデルでリレーションが構築されることになります。

代理キー

Railsで次なるアプリケーションを作ろうとして、テーブル設計の部分で最初の一歩をなかなか踏み出せず迷っていたのですが、同書を読んだことでやっと問題意識がはっきりしました。Railsでは当たり前のように代理キーを使用してモデルでリレーションを構築している一方、自分は知らず知らずのうちにCOBOLerだった頃のナチュラルキーの概念に囚われていたのでした。同書のおかげでこの点に気付くことができたのは収穫でした。

それでネットでこの辺りのことを調べてみると、どうやらデータベースの世界では「ナチュラルキーか代理キーか」というテーマは長年にわたって論争の種になっていることを今になって知りました。

検索で見つかった主なものをピックアップしてみました。議論を蒸し返すつもりは毛頭ありませんのでご了承ください。

どちらかというとキャリアの長い人はどちらかというとRailsのような代理キー強制フレームワークに否定的で、下の世代は肯定的という感じでしょうか。当然ながらどちらの主張にも理があり、どちらかに決めて楽できるようなものではなさそうです。簡単に断定できれば苦労はありません。

自分の印象としては、ナチュラルキー(複合キー)は、そのコード体系が長期的に変化しないことが前提とされているように思います。代理キーはこれと比べて、コード体系が企業合併などで変化する可能性をある程度見越している面があると思います。しかし合併などによるコード体系の変化が、代理キーによって吸収される場合はいいのですが、リレーションそのものが根本的に変化するような場合には、結局どちらの方法を取っていても大幅な変更を余儀なくされるのかなと思います。

Railsでscaffoldを使用してアプリをさくさく作っている段階ではこうしたことを意識することはないと思いますが、RailsというかActiveRecordの実装が代理キーベースであることは意識しておいて損はないかと思います。あちこちで指摘されているように、モデリングとしては原則に沿ったナチュラルキーで、実装ではフレキシブルな代理キーでという役割分担と考えてやっと落ち着きました。

参考: 代理キーを使用しない場合の方法:


CONTACT

TechRachoでは、パートナーシップをご検討いただける方からの
ご連絡をお待ちしております。ぜひお気軽にご意見・ご相談ください。