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

# 環境
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](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/94029/7ad49cde-857a-bf27-12a6-ad772acce1c9.png)

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

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/94029/6fb3cecc-7f74-bc6c-7cc2-47ca5393d17f.png)

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

Railsのマイグレーションで指定できる数値型が、intetgerの１種類しか用意されていないからこそ、データベースに然程詳しくなくても、簡単にデータベースアプリが作成できるというのが、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](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/94029/02f349dd-b967-b45a-2be8-54db13504c7c.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](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/94029/c7c735e9-fe80-6f53-3640-b5d47dedea5f.png)

# まとめ
| Rails       |    PostgreSQL  |                説明    |
|:------------|---------------:|:----------------------:|
| float       |           real |    4バイト / 精度不正確 |
| decimal     |        numeric |   可変長   / 精度正確   |

- real型は、精度不正確とあるので、金額を扱う場合は、float型ではなく、decimal型を使った方が無難という判断になろう。
 
- Railsで用意されているdecimal型は、PostgreSQL側のdecimal型ではなく、numeric型に変換されるのはなぞではある。しかし、PostgreSQL側では、numeric型も、decimal型も同じらしい。