Nwht0xn1

ActiveRecordで途中からcollationをutf8mb4_binに変更するCreated on 2016-06-25 by r7kamura

「テスト」で「デストロイヤー」が一致してしまったりするのを防ぐために、もうテーブルなどを作っちゃったあとでcollationを変更する。

database.yml

まずdatabase.ymlを変える。

charset: utf8mb4
collation: utf8mb4_bin
encoding: utf8mb4

my.cnf を変更する

utf8mb4を使うとキーの容量が増えてしまうので、これに対応できるようにするために、MySQL側のinnodb_large_prefixオプションでキープレフィックスを3072バイトまで拡張する。my.cnfで指定できる。自分の環境ではMacのHomebrewでMySQLを導入していたので、~/.my.cnf を作成して追記した。

[mysqld]
innodb_file_format = Barracuda
innodb_file_per_table = 1
innodb_large_prefix = on

ALTER TABLEする

上記のオプションは ROW_FORMAT=DYNAMIC に設定されたテーブルにしか有効ではないので、ALTER TABLE your_table_name ROW_FORMAT=DYNAMIC を実行する。

テーブル作成時にROW_FORMATを付ける

create_tableのときに自動的にROW_FORMAT=DYNAMICが付くようにする。

# config/initializers/active_record_innodb_raw_format.rb
ActiveSupport.on_load :active_record do
  module ActiveRecord
    module ConnectionAdapters
      class AbstractMysqlAdapter
        def create_table_with_innodb_row_format(table_name, options = {})
          table_options = options.merge(options: "ENGINE=InnoDB ROW_FORMAT=DYNAMIC")
          create_table_without_innodb_row_format(table_name, table_options) do |td|
            yield td if block_given?
          end
        end
        alias_method_chain :create_table, :innodb_row_format
      end
    end
  end
end

migrationする

activerecord-mysql-awesomeを入れながら、既存のテーブルのカラムのcollationを変更するようなmigrationを用意する。

# Gemfile
gem "activerecord-mysql-awesome"
change_column :your_table_name, :your_column_name, :string, collation: "utf8mb4_bin"
rake db:migrate

おしまい

以上の処理が上手くいくとcollationが変更されるはず。