環境
Vagrant + Ubuntu 16.04.5 LTS
Rails 5.2.4.2
はじめに
Railsのマイグレーションでintegerカラムを作る時、limitで指定する値で、実際に作られるデータベースの型が違ってくる。
参考URLでは、MySQLで試したテスト結果だが、PostgreSQLで同じようなテストを行ってみた。
テスト結果(integer)
テストで用意した項目は下記。因みに、limit:で指定する数値の範囲は、1~8の範囲のみ有効になります。
class CreateTaskTest01s < ActiveRecord::Migration[5.2]
def change
create_table :task_test01s do |t|
# t.integer :integer0, limit: 0
t.integer :integer1, limit: 1
t.integer :integer2, limit: 2
t.integer :integer3, limit: 3
t.integer :integer4, limit: 4
t.integer :integer5, limit: 5
t.integer :integer6, limit: 6
t.integer :integer7, limit: 7
t.integer :integer8, limit: 8
# t.integer :integer9, limit: 9
end
end
end
schema.rbは下記のように作られます。マイグレーションファイルで、limit:1を指定しても、schema.rbには、limit:2で作成されるようです。
limit:1~4までは、integer型が生成され、limit:5~8は、bigintが生成されます。
create_table "task_test01s", force: :cascade do |t|
t.integer "integer1", limit: 2
t.integer "integer2", limit: 2
t.integer "integer3"
t.integer "integer4"
t.bigint "integer5"
t.bigint "integer6"
t.bigint "integer7"
t.bigint "integer8"
end
そして、PostgreSQL側で参照したテーブルの型です。
PostgreSQLにはこんなに沢山の数値のデータ型が用意されているにも関わらず、Railsから作成する場合は、smallint ,integer, bigintの3種類しか作成できないという事になります。他のデータ型を使用したい場合は、PostgreSQL側で変更するしかないでしょう。
参考URL
https://www.postgresql.jp/document/9.4/html/datatype-numeric.html
Railsのマイグレーションで指定できる数値型が、intetgerの1種類しか用意されていないからこそ、データベースに然程詳しくなくても、簡単にデータベースアプリが作成できるというのが、Railsを使う意義があるという事なのでしょう。
テスト結果(float)
floatの場合はどうなるかテストをしてみる。
class CreateTaskTest01s < ActiveRecord::Migration[5.2]
def change
create_table :task_test01s do |t|
#t.float :float0, limit:0
t.float :float1, limit:1
t.float :float2, limit:2
t.float :float3, limit:3
t.float :float4, limit:4
t.float :float5, limit:5
t.float :float6, limit:6
t.float :float7, limit:7
t.float :float8, limit:8
#t.float :float9, limit:9
end
end
end
limitをどのように指定しても、schema.rbは、全てfloat型で作成されます。
create_table "task_test01s", force: :cascade do |t|
t.float "float1"
t.float "float2"
t.float "float3"
t.float "float4"
t.float "float5"
t.float "float6"
t.float "float7"
t.float "float8"
end
PostgreSQL側では、全てreal型で作成されます。
float型に関しては、limitを指定する事自体無意味でした。(お後がよろしいようで)
テスト結果(decimal)
decimalの場合はどうなるかテストをしてみる。
class CreateTaskTest02s < ActiveRecord::Migration[5.2]
def change
create_table :task_test02s do |t|
t.decimal :decimal1, limit: 1
t.decimal :decimal2, limit: 2
t.decimal :decimal3, limit: 3
t.decimal :decimal4, limit: 4
t.decimal :decimal5, limit: 5
t.decimal :decimal6, limit: 6
t.decimal :decimal7, limit: 7
t.decimal :decimal8, limit: 8
end
end
end
limitをどのように指定しても、schema.rbは、全てdecimal型で作成されます。
create_table "task_test02s", force: :cascade do |t|
t.decimal "decimal1"
t.decimal "decimal2"
t.decimal "decimal3"
t.decimal "decimal4"
t.decimal "decimal5"
t.decimal "decimal6"
t.decimal "decimal7"
t.decimal "decimal8"
end
PostgreSQL側では、全てnumeric型で作成されます。
decimal型に関しても、limitを指定する事自体無意味でした。
まとめ
Rails | PostgreSQL | 説明 |
---|---|---|
float | real | 4バイト / 精度不正確 |
decimal | numeric | 可変長 / 精度正確 |
-
real型は、精度不正確とあるので、金額を扱う場合は、float型ではなく、decimal型を使った方が無難という判断になろう。
-
Railsで用意されているdecimal型は、PostgreSQL側のdecimal型ではなく、numeric型に変換されるのはなぞではある。しかし、PostgreSQL側では、numeric型も、decimal型も同じらしい。