読者です 読者をやめる 読者になる 読者になる

よかろうもん!

アプリからインフラまで幅広くこなすいまどきのクラウドエンジニアが記す技術ブログ

migrateでストレージエンジンを指定

rails MySQL

railsアプリケーションを動作させるためには、DBのmigrateをしてコマンド一発でテーブルの作成および変更ができます。そのため、利用者は安易に構築ができるようになるのですが、裏ではどのような処理が走っているのでしょうか?
今回はMySQLのドライバについて少しだけ調査してみましたので、そこで学んだことを書き留めておきます。

railsでマイグレートをすると、InnoDBに対応していればストレージエンジンはデフォルトでInnoDBになります。
これは、以下のコードを読むことで理解できます。
activerecord/lib/active_record/connection_adapters/mysql_adapter.rb
一部抜粋

def create_table(name, options = {}) #:nodoc:
  super(name, {:options => "ENGINE=InnoDB"}.merge(options))
end

mysql_adapterでストレージエンジンがべた書きされています。
※まさかべた書きとは思ってもいませんでしたが・・・

そのため、このENGINEをMyISAM等に書き換えてやればエンジンの変更は可能です。
しかしアダプターに変更を加えるのは微妙ですね・・・。
理由は、CREATE TABLEをすると必ず指定したエンジンになってしまうため。
#指定したエンジンをMySQLをmakeしたときに有効にしていればですが。

テーブル全てを特定のエンジンにする&ActiveRecordをfreeze(vendor/rails以下に凍結)するという制限付きで利用する分には妥協すればOKかもしれませんが、これじゃあカッコ悪いですよね。

というわけで何かよい方法はないかと調べていると、
マイグレートファイルでストレージエンジンを指定できることが判明。
なので、特定のテーブルのみエンジンを変更することができます。

指定方法は、マイグレートファイルに以下のように記述します。

class AddStatusTable < ActiveRecord:migration
 def self.up
  create_table(:statuses, :options => "ENGINE=MyISAM DEFAULT CHARACTER SET=UTF8") do |t|
   t.column(:status, :string, :null => false)
  end
 end
 def self.down
  drop_table(:statuses)
 end
end

CRAETE TABLEのオプションで上記のようにENGINEと文字コードを指定可能です。

これで、参照しかしないテーブルについてはエンジンをInnoDBからMyISAMに変更してレスポンスの高速化を図ることもできるはずです。
#試したことがないので控えめにしときます・・・