3
2

More than 3 years have passed since last update.

マイグレーションで指定する、数値型カラムのlimitの値と、PostgreSQLで作成される型の対比

Last updated at Posted at 2020-04-08

環境

Vagrant + Ubuntu 16.04.5 LTS
Rails 5.2.4.2

はじめに

Railsのマイグレーションでintegerカラムを作る時、limitで指定する値で、実際に作られるデータベースの型が違ってくる。

参考URLでは、MySQLで試したテスト結果だが、PostgreSQLで同じようなテストを行ってみた。

参考URL
https://qiita.com/Yinaura/items/cede8324d08993d2065c

テスト結果(integer)

テストで用意した項目は下記。因みに、limit:で指定する数値の範囲は、1~8の範囲のみ有効になります。

db/migrate/xxxxx_create_task_test01s.rb
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が生成されます。

db/schema.rb
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側で参照したテーブルの型です。

image.png

PostgreSQLにはこんなに沢山の数値のデータ型が用意されているにも関わらず、Railsから作成する場合は、smallint ,integer, bigintの3種類しか作成できないという事になります。他のデータ型を使用したい場合は、PostgreSQL側で変更するしかないでしょう。

image.png

参考URL
https://www.postgresql.jp/document/9.4/html/datatype-numeric.html

Railsのマイグレーションで指定できる数値型が、intetgerの1種類しか用意されていないからこそ、データベースに然程詳しくなくても、簡単にデータベースアプリが作成できるというのが、Railsを使う意義があるという事なのでしょう。

テスト結果(float)

floatの場合はどうなるかテストをしてみる。

db/migrate/xxxxx_create_task_test01s.rb
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型で作成されます。

db/schema.rb
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を指定する事自体無意味でした。(お後がよろしいようで)

image.png

テスト結果(decimal)

decimalの場合はどうなるかテストをしてみる。

db/migrate/xxxxx_create_task_test02s.rb
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型で作成されます。

db/schema.rb
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を指定する事自体無意味でした。

image.png

まとめ

Rails PostgreSQL 説明
float real 4バイト / 精度不正確
decimal numeric 可変長 / 精度正確
  • real型は、精度不正確とあるので、金額を扱う場合は、float型ではなく、decimal型を使った方が無難という判断になろう。

  • Railsで用意されているdecimal型は、PostgreSQL側のdecimal型ではなく、numeric型に変換されるのはなぞではある。しかし、PostgreSQL側では、numeric型も、decimal型も同じらしい。

3
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
2