はじめに
既存のデータベース内のテーブル、カラムの照合順序が統一されていないため、統一する作業について調べた内容を記録します。
方法①
各テーブルごとに変更する
mysql> ALTER TABLE テーブル名 CONVERT TO CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci;
===
下記のSQLを実行すると、データベース内の全テーブルへのSQL文の一覧が出力されるので、一行ずつコピペをして各テーブルごとのSQLを実行することができる
mysql> SELECT CONCAT('ALTER TABLE ', table_name, ' CONVERT TO CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci;') AS alter_sql FROM information_schema.tables WHERE table_schema = 'データベース名';
+---------------------------------------------------------------------------------------------------------+
| alter_sql |
+---------------------------------------------------------------------------------------------------------+
| ALTER TABLE active_storage_attachments CONVERT TO CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci; |
| ALTER TABLE active_storage_blobs CONVERT TO CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci; |
| ALTER TABLE active_storage_variant_records CONVERT TO CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci; |
| ALTER TABLE ar_internal_metadata CONVERT TO CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci;
|
(省略)
方法②
マイグレーションでまとめて実行する
- 下記のようなマイグレーションファイルを作成し、
rails db:migrate
を実行する
class ChangeCollation < ActiveRecord::Migration[6.1]
def up
ActiveRecord::Base.connection.tables.each do |table_name|
execute "ALTER TABLE #{table_name} CONVERT TO CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci;"
end
end
end
-
ActiveRecord::Base.connection.tables
- ActiveRecordを使って全テーブル名が入った配列を返す
irb(main):001:0> ActiveRecord::Base.connection.tables
=> ["active_storage_attachments", "active_storage_blobs", "active_storage_variant_records", "ar_internal_metadata", ...]
-
execute
メソッド- 任意のSQLを実行できる
- Railsガイドでは「データをマイグレーションでみだりに直接変更しないよう注意が必要です」とあるので実行に際しては十分に検討してください