初めに
今回は外部キーとリファレンスについてまとめます。
こちらは②マイグレーションファイルのすすめ②ですので、よければ①もご覧ください。
マイグレーションファイルのすすめ
以下の記事を参考にさせていただきました!
外部キーの概要と制約を使うことのメリット・デメリット
外部キー 概要
create_table(:users) do |t|
t.string :name, null: false
end
create_table(:user_tweet) do |t|
t.references :user, null: false, foreign_key: true
end
外部キーとは
テーブル同士を紐付ける際に用意されるカラムのこと。
例えば以下の二つのテーブルは、1ユーザーが複数のツイートを持っており、ツイートテーブルのuser_idがuser.idの値を格納することで二つのテーブルを紐付けている。
この時ユーザーテーブルのidカラムは主キー、ツイートテーブルのuser_idが外部キーである。
ユーザーテーブル
| id | user |
|---|---|
| 1 | KEN |
| 2 | MIKE |
ツイートテーブル
| id | user_id | content |
|---|---|---|
| 1 | 1 | Hello |
| 2 | 1 | How are you? |
| 3 | 2 | こんにちは |
外部キー制約とは
主キーと外部キーを使った制約で利用した場合、以下の制限がある。
- 存在しない値を外部キーとして登録することはできない
- 子テーブルの外部キーに値が登録されている親テーブルのレコードは削除できない
1. 存在しない値を外部キーとして登録することはできない
ツイートテーブルにデータを登録する際に、user_idがuserテーブルのidカラムに存在しない値(例えば nullや3など)を指定するとエラーが生じる。
2. 子テーブルの外部キーに値が登録されている親テーブルのレコードは削除できない
ユーザーKENを削除する際に、user_idの値が1のツイートが存在する場合は、ユーザーKENを削除することができない。
※ KENを削除する場合は、Userモデルでdependent: :destroy を使用する必要がある。
外部キーのメリットとデメリット
存在しない値が、登録されることを防ぐことがきる為、データの整合性が保たれる。
親テーブルの存在しない子テーブルが発生することを防げる。
外部キーの作成方法
外部キーの作成には以下の2パターンがある。
create_table(:users) do |t|
t.string :name, null: false
end
create_table(:tweet) do |t|
t.references :user, null: false, foreign_key: true
end
OR
create_table(:users) do |t|
t.string :name, null: false
end
create_table(:tweet) do |t|
t.references :user
end
# add_foreign_keyは後から外部キー制約を貼りたい場合にも使える
add_foreign_key(:tweet, :users)
t.reference :userによりuser_idカラムを作成している。
*foreign_key: trueがなければ外部キー制約がつかないので注意!
まとめ
外部キーは、テーブル設計に欠かせない知識なのでぜひ覚えましょう!
人のことは言えないので僕も覚えます!笑