URLを入れておきたいカラムなのにRailsのマイグレーションでt.string :url
って書いてvarchar(255)にしちゃって、実際の運用で日本語URLがエンコードされて渡ってきて余裕でオーバーするっていうのはあるあるじゃないですか?それとも初心者あるある?
URLに文字数制限ってのは確か存在しなくて、IEかなんかでは2083文字までは大丈夫などアプリケーションによって異なるらしい。
Internet Explorer では URL に最大 2,083 文字が使用可能
で、僕はこのミスをRSSリーダーのときにやった。RSSフィードを解析すると各記事のタイトルやらURLが取れるんだけど、そのURLの保存先をvarchar(255)にしていてINSERTできないって問題に当たってしまった。
これを何も考えずに解決するだけであれば簡単で、Railsであれば、t.string :url
をt.text :url
などにしてしまえばOK。文字制限なくなるし。
あとはt.string :url, limit: 1024
みたいにlimit使うってのもありだけど、なんかうまくいかないこともあったような。
ついでに話しておくと、MySQLのデフォルトでは768バイト以上の文字列にインデックスを付けることができない。なのでvarchar(256)以上の文字列はインデックスを付けられないようだ。
MySQLのUNIQUEなINDEXには長さ767byteまでしか使えない件と対策 - tanamonの日記
このページの解決策には掲載されていないが、MySQL5.5系だとinnodb_large_prefix
というオプションを有効にした上で、ROW_FORMATをDynamicやCompressedに変更したテーブルでのみ3072バイトまで使えるようになる。これを使うとvarchar(1024)とかでもインデックスを付けられるようになってしまう!
ちなみにこれをRailsのマイグレーションにするにはSQLを直接実行するしかなさそう。こういう風にかいた。change
ではなく、従来型のup
、down
を用いてロールバックもできるように書いている。
class ChangeRowFormat < ActiveRecord::Migration
def up
execute 'ALTER TABLE feeds ROW_FORMAT=Dynamic'
end
def down
execute 'ALTER TABLE feeds ROW_FORMAT=Compact'
end
end