RailsでMySQLにマイグレーションでテーブルを作成してみる

RailsでMySQLにスキーマファイルからテーブルを作成してみるの続き


migrateのディレクトリが無ければ作っておく。

$ mkdir db/migrate

また、前回のテーブルが残っているので、一旦まっさらな状態にしておく。

$ rake db:drop
$ rake db:create

空のcreate_table

何もカラムを書かずにテーブルを作成してみる。

$ vi db/migrate/1_create_table_first.rb
class CreateTableFirst < ActiveRecord::Migration
  def change
    create_table :sample1 do |t|
    end
  end
end

db:migrateを実施するとDBに反映される。

$ rake db:migrate

sample1のテーブルが作成され、テーブルにはidというカラムが自動で追加される。
また、バージョン番号1も追加される。

mysql> show tables;
+------------------------------------+
| Tables_in_sample_mysql_development |
+------------------------------------+
| sample1                            |
| schema_migrations                  |
+------------------------------------+

mysql> desc sample1;
+-------+---------+------+-----+---------+----------------+
| Field | Type    | Null | Key | Default | Extra          |
+-------+---------+------+-----+---------+----------------+
| id    | int(11) | NO   | PRI | NULL    | auto_increment |
+-------+---------+------+-----+---------+----------------+

mysql> select * from schema_migrations;
+---------+
| version |
+---------+
| 1       |
+---------+

schema.rbも自動で更新される。

$ cat db/schema.rb
ActiveRecord::Schema.define(version: 1) do

  create_table "sample1", force: true do |t|
  end

end

created_at/updated_at

t.timestampsを指定すると、created_atとupdated_atのカラムが追加される。

$ vi db/migrate/2_create_table_timestamps.rb
class CreateTableTimestamps < ActiveRecord::Migration
  def change
    create_table :sample2 do |t|
      t.timestamps
    end
  end
end
$ rake db:migrate
mysql> desc sample2;
+------------+----------+------+-----+---------+----------------+
| Field      | Type     | Null | Key | Default | Extra          |
+------------+----------+------+-----+---------+----------------+
| id         | int(11)  | NO   | PRI | NULL    | auto_increment |
| created_at | datetime | YES  |     | NULL    |                |
| updated_at | datetime | YES  |     | NULL    |                |
+------------+----------+------+-----+---------+----------------+

様々な型

様々な型のカラムを作成してみる。

$ vi db/migrate/3_create_table_types.rb
class CreateTableTypes < ActiveRecord::Migration
  def change
    create_table :sample3 do |t|
      t.string    :column01        # 文字列
      t.text      :column02        # 長い文字列
      t.integer   :column03        # 整数
      t.float     :column04        # 浮動小数
      t.decimal   :column05        # 精度の高い小数
      t.datetime  :column06        # 日時
      t.timestamp :column07        # より細かい日時
      t.time      :column08        # 時間
      t.date      :column09        # 日付
      t.binary    :column10        # バイナリデータ
      t.boolean   :column11        # Boolean型
    end
  end
end
$ rake db:migrate
mysql> desc sample3;
+----------+---------------+------+-----+---------+----------------+
| Field    | Type          | Null | Key | Default | Extra          |
+----------+---------------+------+-----+---------+----------------+
| id       | int(11)       | NO   | PRI | NULL    | auto_increment |
| column01 | varchar(255)  | YES  |     | NULL    |                |
| column02 | text          | YES  |     | NULL    |                |
| column03 | int(11)       | YES  |     | NULL    |                |
| column04 | float         | YES  |     | NULL    |                |
| column05 | decimal(10,0) | YES  |     | NULL    |                |
| column06 | datetime      | YES  |     | NULL    |                |
| column07 | datetime      | YES  |     | NULL    |                |
| column08 | time          | YES  |     | NULL    |                |
| column09 | date          | YES  |     | NULL    |                |
| column10 | blob          | YES  |     | NULL    |                |
| column11 | tinyint(1)    | YES  |     | NULL    |                |
+----------+---------------+------+-----+---------+----------------+

様々なオプション

様々なカラムのオプションを指定してみる。

$ vi db/migrate/4_create_table_options.rb
class CreateTableOptions < ActiveRecord::Migration
  def change
    create_table :sample4 do |t|
      t.string    :column01, :limit => 100      # カラムの桁数
      t.integer   :column02, :default => 200    # デフォルトの値
      t.float     :column03, :null => false     # nullを許可するか
    end
  end
end
$ rake db:migrate
mysql> desc sample4;
+----------+--------------+------+-----+---------+----------------+
| Field    | Type         | Null | Key | Default | Extra          |
+----------+--------------+------+-----+---------+----------------+
| id       | int(11)      | NO   | PRI | NULL    | auto_increment |
| column01 | varchar(100) | YES  |     | NULL    |                |
| column02 | int(11)      | YES  |     | 200     |                |
| column03 | float        | NO   |     | NULL    |                |
+----------+--------------+------+-----+---------+----------------+

カラムの変更

カラムを色々変更してみる。

$ vi db/migrate/5_change_table_columns.rb
class ChangeTableColumns < ActiveRecord::Migration
  def change

    # カラムを追加
    add_column :sample3, :column99, :string

    # カラムを変更
    change_column :sample3, :column01, :integer

    # カラムを変更(各種オプション指定)
    change_column :sample3, :column02, :string, :limit => 200, :default => 'hello', :null => false

    # カラムの初期値を変更
    change_column_default :sample3, :column03, 300

    # カラムの名前を変更
    rename_column  :sample3, :column04, :column44

    # カラムを削除
    remove_column  :sample3, :column05

    # カラムをまとめて削除
    remove_columns :sample3, :column06, :column07, :column08, :column09, :column10

  end
end
$ rake db:migrate
mysql> desc sample3;
+----------+--------------+------+-----+---------+----------------+
| Field    | Type         | Null | Key | Default | Extra          |
+----------+--------------+------+-----+---------+----------------+
| id       | int(11)      | NO   | PRI | NULL    | auto_increment |
| column01 | int(11)      | YES  |     | NULL    |                |
| column02 | varchar(200) | NO   |     | hello   |                |
| column03 | int(11)      | YES  |     | 300     |                |
| column44 | float        | YES  |     | NULL    |                |
| column11 | tinyint(1)   | YES  |     | NULL    |                |
| column99 | varchar(255) | YES  |     | NULL    |                |
+----------+--------------+------+-----+---------+----------------+

インデックスの追加

インデックスを追加してみる。

$ vi db/migrate/6_add_index.rb
class AddIndex < ActiveRecord::Migration
  def change

    # インデックスを追加
    add_index :sample4, :column01

    # ユニークインデックスの追加
    add_index :sample4, :column02, :unique => true

    # インデックス名を指定
    add_index :sample4, :column03, :name => 'column03_index'

    # 複数カラムのインデックスを追加
    add_index :sample4, [:column02, :column03]

  end
end
$ rake db:migrate
mysql> show index from sample4;
+---------+------------+----------------------------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
| Table   | Non_unique | Key_name                               | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment |
+---------+------------+----------------------------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
| sample4 |          0 | PRIMARY                                |            1 | id          | A         |           0 |     NULL | NULL   |      | BTREE      |         |
| sample4 |          0 | index_sample4_on_column02              |            1 | column02    | A         |           0 |     NULL | NULL   | YES  | BTREE      |         |
| sample4 |          1 | index_sample4_on_column01              |            1 | column01    | A         |           0 |     NULL | NULL   | YES  | BTREE      |         |
| sample4 |          1 | column03_index                         |            1 | column03    | A         |           0 |     NULL | NULL   |      | BTREE      |         |
| sample4 |          1 | index_sample4_on_column02_and_column03 |            1 | column02    | A         |           0 |     NULL | NULL   | YES  | BTREE      |         |
| sample4 |          1 | index_sample4_on_column02_and_column03 |            2 | column03    | A         |           0 |     NULL | NULL   |      | BTREE      |         |
+---------+------------+----------------------------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+

最後に

schema.rbの中身がどうなってるか確認すると、下記のように更新されている。

$ cat db/schema.rb
ActiveRecord::Schema.define(version: 6) do

  create_table "sample1", force: true do |t|
  end

  create_table "sample2", force: true do |t|
    t.datetime "created_at"
    t.datetime "updated_at"
  end

  create_table "sample3", force: true do |t|
    t.integer "column01"
    t.string  "column02", limit: 200, default: "hello", null: false
    t.integer "column03",             default: 300
    t.float   "column44"
    t.boolean "column11"
    t.string  "column99"
  end

  create_table "sample4", force: true do |t|
    t.string  "column01", limit: 100
    t.integer "column02",             default: 200
    t.float   "column03",                           null: false
  end

  add_index "sample4", ["column01"], name: "index_sample4_on_column01", using: :btree
  add_index "sample4", ["column02", "column03"], name: "index_sample4_on_column02_and_column03", using: :btree
  add_index "sample4", ["column02"], name: "index_sample4_on_column02", unique: true, using: :btree
  add_index "sample4", ["column03"], name: "column03_index", using: :btree

end