主キーには人工キーを使うか自然キーを使うか

主キーに人工キーを使うか、それとも自然キーを使うか、主キーの扱いがデータモデリングの方針として分かれているみたいです。

結論

現在の特にwebアプリケーションでの主流は、人工キーを使う方針みたいです。
他の言語のことは良く知りませんが、phpで主流のフレームワークや、そこで使われているORM*1が、人工キーを使うことを前提としています。
pythonDjangoでも同様の様です。

これは RDBでテーブルの作り方が良くわからなくなってきたので、いったんまとめてみた - kanonjiの日記 で作ったER図です。
[post] と [tag]エンティティは many-to-many の関係で、[tagged] という関係テーブルを使って one-to-meny に置き換えています。
この [tagged] の主キーを例として考えてみます。


[tagged] の主キーは id で、これは人工キーです。
このER図を書いたとき、id 無しで id_post と id_tag の2つで複合キーで主キーにも出来るなと思ったけど、そういう主キーが自然キーということでした。
この時は、どっちが良いのか悩んだけど、どちらも間違ってはないっぽい。
webアプリケーションを作るなら、id を主キーに使う人工キーを使った作り方の方が良いみたい。

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

ここで挙がっているメリット/デメリットを見ると、昔は自然キーを使った作り方が多く、最近は人工キーが主流って感じです。

依存関係について

[tagged] の主キーを自然キーにしたら id_post と id_tag が主キーになるので、依存エンティティという事になりそう。
でも 人工キーなら id が主キーになって id_post と id_tag は単なる外部キーになり、独立エンティティです。
明確な解説はなかったですが、どうやら依存関係は、あまり厳密に考えなくても良いみたいです。

人工キーと自然キー

連番(順序・シーケンスとも呼ばれる)のように、一意性を確保するためだけにシステム内部で生成され、利用者が関知しない情報を格納する属性からなる主キーを人工キー、人為キー(artificial key)ないし別名キー(alias key)、代替キー(surrogate key)などといい、逆に、システム外部から格納すべきものとして与えられる情報を格納する属性からなる主キーを自然キー(natural key)ということがある。

主キー - Wikipedia

堅い解説であまり分かりやすくは無いWikipedaiの解説。
人工キーはサロゲートキーとも呼ばれたりするようです。

*1:O/Rマッパー