RubyONRails/データベース設計における制約について

f:id:AK474747:20190813143311p:plain

 

簡単なブログアプリを作ってるんすが、データベース設計の際に必要になりそうなものがあったので、 手早くまとめます。

意外と検索してもヒットしなかったんだこれが。

制約とは

制約とは特定のデータの保存を許さないためのバリデーションです。例えば同じメールアドレスのユーザーを登録できないようにする、名前のデータが空のユーザーを保存できないようにするといったことができるようになります。 RubyOnRailsの場合だと、rails g model [テーブル名(単数形)]をターミナルで打ち込むと、マイグレーションファイルが出来上がります。 このファイルにカラムの指定をした後、rake db:migrateすることでデータベースにカラムが反映されます。 制約はこのカラム一つ一つに対して使います。

NOT NULL制約

NOT NULL制約を設定すると、そのカラムの値にはNULL(空の値)を入れることができなくなります。 ブログアプリの場合でしたらユーザー登録が必要になるので、ユーザー登録の際のEmailやパスワード、nameなんかが対象になります。下記のnull: falseが入っている箇所のことです。

マイグレーションファイル

class CreateUsers < ActiveRecord::Migration
  def change
    create_table :users do |t|
      t.string :name, null: false
      t.timestamps null: false
    end
  end
end

一意性制約

一意性制約はテーブル内で重複するデータを禁止する制約です。 ユーザー登録をする際に、もう登録したことあるサイトなのに、自分のEメールアドレスを登録しようとしたことってありませんか?すでに使われてるアドレスです、なんて怒られたと思います。

その制約をカラムに対して行うことですね。

ブログアプリの場合はやはりEmailカラムが対象になります。unique :trueが制約している文になります

マイグレーションファイル

class CreateUsers < ActiveRecord::Migration
  def change
    create_table :users do |t|
      t.string :name  , null: false
      t.string :email , null: false , unique: true
      t.timestamps null: false
    end
  end
end

外部キー制約

外部キー制約は、外部キーの対応するレコードが必ず存在しなくてはいけないという制約です。

これはミニアプリの場合、UserテーブルではなくArticle(記事)テーブルになるかと思います。 記事を投稿するのに、投稿したユーザーが不明瞭ではだれが書いたがわかりませんよね?

この制約は、t.referenceを使います。これによりuserではなくuser_idというカラムを作成してくれるため、テーブル間のリレーションを意識しやすくなります。また、後述しますがインデックスを自動で貼ってくれます。

foreign_key: trueというのが制約文に当たります。

マイグレーションファイル

class CreateArticles < ActiveRecord::Migration
  def change
    create_table :articles do |t|
      t.string     :text
      t.references :user , foreign_key: true
    end
  end
end

インデックスとは

インデックスはデータベースの機能の一つで、テーブル内のデータ検索を高速化することができます。インデックスはカラムに対して設定することができ、設定したカラムでの検索が高速になります。

ただし、インデックスには以下の2つのデメリットがあります。

・データを保存・更新する速度が遅くなる ・データベースの容量を使う

ミニアプリであれば、Userテーブルのnameなんかが該当するでしょうか。Articleテーブルのnameも該当しそうですね。投稿者名で検索、記事名で検索みたいな。

ただし記事名にインデックスを貼るのは考えた方がいいかもしれません。データの保存・更新に関してはスピードを要すルものではないかもしれませんが、データベース容量はユーザーが増えてくればサーバーサイドとの相談になりそうですね。

add_index :usersがインデックスを貼り付ける文になります。 補足的にですが、同時に二つのカラムにインデックスを貼る場合も書いています。

class CreateUsers < ActiveRecord::Migration
  (省略)
  add_index :users  # インデックスを一つに貼る 
  add_index :users,  [:name, :email] # インデックスを2つにまとめて貼る
  end
end

主キー制約

主キー制約は、主キーである属性値が必ず存在してかつ重複していないことを保証する制約です。主キーに対してNOT NULL制約と一意性制約を両方設定するのと同義になります。

railsの場合はもともと機能が備わっていて、データベースを見たときに、それぞれのテーブルでIDというカラムがあるかと思います。

それが主キーに当たります。

制約文といいうよりは概念として非常に重要ですので記載しました。

ってまた30分くらいかかっちゃったよおおお。

手早くって言ったのにいいい・・・