はじめに
バージョン情報は以下の通りです。
$ bundle exec rails -v
Rails 4.2.3
$ mysql --version
mysql Ver 14.14 Distrib 5.6.25, for osx10.10 (x86_64) using EditLine wrapper
概要
最近 Rails を 4.2 系にバージョンアップして気づいたこと。
class CreateWeapons < ActiveRecord::Migration
def change
create_table :weapons do |t|
t.references :girl
t.string :name
t.timestamps null: false
end
end
end
このマイグレーションを作成して schema.rb
を確認すると、
create_table "weapons", force: :cascade do |t|
t.integer "girl_id", limit: 4
t.string "name", limit: 255
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
のように自動的に limit: 4
が付与されています。
あれ、以前のバージョンでは limit なんて付かなかったのに…。
そして僕はこう思いました。
「あれ? 外部キーが 4 桁の整数だと 1 万件以上のレコードを保持できなくね?」
でも、むろんそんなことはなく、それは非常に初歩的な勘違いでした。
Rails のドキュメント を見ると、
:limit - Requests a maximum column length. This is number of characters for :string and :text columns and number of bytes for :binary and :integer columns.
と書かれていました。つまり数値型の場合の limit の単位はバイトなんですね。
4 バイトというのは一般的な整数型の範囲 (-2,147,483,648 ~ 2,147,483,647) と一致しますし、なぜ気付かなかったし…orz
ちなみに MySQL 上は int(11)
という型になっており、僕はこう思いました。
「あれ? この (11) ってなんぞ? 整数値の範囲である 4 バイトとも関係なさそうだし…」
これも MySQL のドキュメント を確認すると、以下の言及がありました。
When used in conjunction with the optional (nonstandard) attribute ZEROFILL, the default padding of spaces is replaced with zeros. For example, for a column declared as INT(4) ZEROFILL, a value of 5 is retrieved as 0005.
つまり、整数を 0 埋め (ZEROFILL) する際の桁数のようですね。
ZEROFILL については StackOverflow の What is the benefit of zerofill in MySQL?
というページも参考になりました。