0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

自分用メモ(マイグレーション,index,foreign_key,reference)

Posted at

referenceあたりまとめ

外部キーのuser_idカラムを作るときに、二通りの手段がある。

一つはrefference型を使いuser_idを作成する方法。もう片方は自分でuser_idを作成する方法

データベース上で親テーブルuserと子テーブルを結びつける時は
・子テーブルにuser_id(外部キー)を作る
・user_idにindexをつける(付けた方がデータ読み込み時に便利)
・外部制約キーをつける(親テーブルの値しか入らないように・親テーブルのデータが変わると反映)
の3つが必要。

マイグレーション時にreferencesを使うと、(t.references:user)
user_idの作成と、indexの作成を行ってくれる。
しかし、外部制約キー(foreign_key)は作成してくれない。
なので、自分で外部制約キーは自分でつける必要がある。

(初めは外部キーと外部制約キーを混同してごっちゃになった)

マイグレーションについて

index,foreign_key,referenceの理解が曖昧なので、整理する。

まず、マイグレーションファイルはこんな感じ

class CreatePosts < ActiveRecord::Migration[5.2]
  def change
    create_table :posts do |t|
      t.text :body
      t.references :user, foreign_key: true

      t.timestamps
    end
  end
end
class AddIndexToテーブル名 < ActiveRecord::Migration
  def change
    add_index :テーブル名, カラム名
  end
end

referencesはデータ型の指示
foreign_keyは列の制約
indexは

そもそものところのマイグレーション

・テーブルが多数(tasks,posts,userとか)
・その中に、カラムが多数(id,title,nameとか)
・そのカラムは属性を持っている

def change
 create_table :books do |t|#テーブル作成
  t.string :title, limit: 100, null: false#カラム作成
  #(まずフィールド定義t.string)(その後フィールド名定義 :title)(その後列制約)

 end
end

t.stringとかはデータ型の指定(フィールドの定義)
(利用できるデータ型は他にtext, date, boolean, integer, textなど多数)

特殊なフィールド定義をするためのメソッドとしてtimestampsや、referencesなどがある。

t.timestamps メソッド
→日付時刻型のcreated_atとupdated_at列を生成する

t.references
→外部キー列を生成する
ex) t.references:bookとした場合は booksテーブルの外部キーとして、book_idを生成する

今回はcreate_tableメソッドを用いているが、他にも色々メソッドがある
add_column,add_index,add_foreign_key,change_table,executeなど

foreign_key,index,referenceの意味

indexとは?つけるとどんなメリットがあるのか?

「この列だけ検索したい」「この列を基準に並べ替えしたい」というときに使える
メリット:データベースの読み込み速度が改善可能(貼り方やデータ数にもよる)

テーブルの中の特定のカラムのデータを複製し検索が行いやすいようにしたもの。

データベースにインデックスをつけることができる。
インデックスがあれば全部のデータを調べずに、高速に検索を行える。

ex)膨大なデータの中から、aaa@mail.comというデータを調べたいとする。
この場合、インデックスがなければ、全てのデータからこのデータを探らなければいけないため、非効率。
インデックスがあれば、emailのインデックス部分から探すだけで良い。

indexの貼り方

class AddIndexToテーブル名 < ActiveRecord::Migration
  def change
    add_index :テーブル名, カラム名
  end
end

「ある程度多くのデータを格納するテーブルの、格納される値がそれぞれ異なるようなカラムの中で、検索がよく行われるカラム」にindexを貼ると良いらしい

参考:データベースにindexを張る方法https://qiita.com/seiya1121/items/fb074d727c6f40a55f22

foreign_keyとは?外部制約キーをつけるとどんなメリットがあるの?

親テーブルと子テーブルの間で、整合性をとるためのキー
 
データを参照する側(子テーブル側)に外部制約キーを設置する。
 
子テーブルに設置した外部制約キーには何でも入れられるわけではなく、
親テーブルに入っている値しか入れられなくなる。(user_idに何にでも入れれる訳ではなく、実際にあるuser_idしか入れれなくなる)

親テーブルのuser_idを変更、削除すると、子テーブルにあるforeign_keyも変更、削除される。

外部キーの作成

create_tableで
t.references :bookを使うと、book_idとが作成される

add_foreign_keyメソッド
add_foreign_key :作成先のテーブル名, :参照先のテーブル名
add_foreign_key :reviews, :books
→reviewsテーブルに、booksテーブルを参照する外部キーを設置する

待て待て、外部キー列と外部キー制約があるんか
テーブルを作るときに、t.reference、カラムを追加するときにadd_referenceすれば、外部キーのカラムを作成することができる。

参考:https://teratail.com/questions/63406
https://www.dbonline.jp/

referenceとは?使うとどんないいことがあるの?

references型を使うことで、自動で、〇〇_idという外部キーを設定してくれるのが良いところ
外部キーを作成するときの一つの手法(普通にuser_idカラムを設定することもできる)

t.references :bookとかで、外部キーを作成する

外部キーをreferences型カラムで保存する
https://qiita.com/sinagaki58/items/7edea51ef00e393834ca
Railsの外部キー制約とreference型について
https://qiita.com/ryouzi/items/2682e7e8a86fd2b1ae47

外部キーuser_idをつくるだけじゃダメなの?

なぜ外部キー制約と、インデックスを付けなければいけないのか

→外部キー制約(foreign_key: true)があると、子テーブルにあるuser_idが親テーブルの値しか入らなくなるから。しかも親テーブルの値が変わると、子テーブルの値も変わるので使う。

どこにindex付けてんの
→user_idに作られる

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?