とりあえずID
すっかり暗黙の了解として認識してしまっていたのですが
DBでテーブルを作る際、id列は必ずできるものだと勘違いをしていました。
そのテーブルに、idは必要ですか?〜idの必要性とデータの一意性についてもう一度考えてみる
私はRailsを主に使って開発をしています。
こちらの記事に書いてある通り、Railsでマイグレーションファイルを扱うと、何も考えなくてもid列は存在しています。
しかし、id列というものは必須ではないです。
id列は行の一意性を保つために存在していることが多いです。
つまり、行の一意性が保たれているのならばid列は存在しなくても良いのです。
行の一意性が保たれているケースってどのようなものがあるでしょうか。
例えば全国民に発行されているマイナンバーは各個人に一意に存在しています。
仮にマイナンバーと個人情報を扱うようなテーブルがあった際には
普段使うようなid列は必要ないということになります。
id列は必要か?
下記のようなテーブルを扱う際、mynumber列を利用してテーブルを結合することもできます。
外部キーとして参照することもできます。よく使われるid列は存在していなくても成り立ちます。
個人情報テーブル
mynumber | 名前 | 年齢 |
---|---|---|
123456 | 太郎 | 21 |
123457 | 花子 | 22 |
123458 | 二郎 | 23 |
所属保険団体テーブル
mynumber | 所属保険団体 | 登録番号 |
---|---|---|
123456 | 東京都保険会社 | 123 |
123457 | 大阪府保険会社 | 124 |
123458 | 愛知県保険会社 | 125 |
このテーブルの場合、id列はそもそもそれ自体に意味は持ちません。あくまで行を一意に保つためだけに存在しています。
そういったキーを擬似キー(pseudo key)、または代理キー(surrogate key)と表します。
クエリを交えて確かめてみる
Userモデル
Carモデル
というようなモデルがあったとします。
ユーザーは何らかの車を所有しているという前提があるものとします。
Userモデル
id | name | year | car_id |
---|---|---|---|
1 | 太郎 | 21 | 1 |
2 | 花子 | 22 | 2 |
3 | 二郎 | 23 | 3 |
Carモデル
id | car_id | name | year |
---|---|---|---|
1 | 1 | トヨタ | 2000 |
2 | 2 | ホンダ | 2010 |
3 | 3 | スバル | 2015 |
上記の例で、新たにCarモデルを追加する場合、
INSERT TO Cars (car_id, name, year) VALUES ('4','スズキ','2019');
というように、id列を使わなくても挿入しても、Carモデルの行の一意性は保たれます。
これらがもし、id列のみで表されていたらどうなるか、確認してみましょう。
Userモデル
id | name | year | car_id |
---|---|---|---|
1 | 太郎 | 21 | 1 |
2 | 花子 | 22 | 2 |
3 | 二郎 | 23 | 3 |
Carモデル
id | name | year |
---|---|---|
1 | トヨタ | 2000 |
2 | ホンダ | 2010 |
3 | スバル | 2015 |
SELECT u.id.c.id from Users as u INNER JOIN Cars as c ON u.car_id = c.id;
この時に帰ってくるテーブルはこうなります。
id(u.id) | id(c.id) |
---|---|
1 | 1 |
2 | 2 |
3 | 3 |
列の名前で値を参照する場合、本来u.idとc.idはどちらも「id」という列名なので
どちらがどちらのモデルのidを表しているのかわからなくなります。
これらを、idではなく、「user_id」「car_id」を扱うことで、主キー・外部キーの性質を保ち、かつテーブル結合をした時などでもその列名が判別しやすくなります。
結論
主キーには分かりやすい列名をつけよう!
擬似キーは必須ではないよ!