PostgreSQLのデータ型とその挙動のまとめ(数値型)

  • 4
    いいね
  • 2
    コメント

Postgresにテーブルを作成する際に、Postgresのデータ型を見てみると、数値型だけで10個もある。。どうやって使い分けたら良いのかわからなかったので、調べてみた。

この表は、PostgreSQL公式ページに記載されている内容。
image

数値型の大まかな区分け

Postgresの数値型には、①整数型、②小数点型、③自動採番型の3つがある。

  1. 整数型
    • smallint
    • integer
    • bigint
  2. 浮動小数点データ型
    • decimal
    • numeric
    • real
    • double precision
  3. 自動採番型
    • smallserial
    • serial
    • bigserial

整数型

整数型の特徴は、整数しか格納できないこと。小数を含んだ値を入れようとするとエラーになる。この3つの型の違いは、格納できる数値の最大桁数。

型名 最小桁
smallint -32768 to +32767
integer -2147483648 to +2147483647
bigint -9223372036854775808 to +9223372036854775807

最大桁数が多くなれば、それだけハードディスクの容量を消費することになる。公式ページによると、整数型の中ではintegerが一番バランスの取れた型となっているため、整数を扱う場合、特に理由のない場合はinteger型を利用する事との記述があった。

具体的にはHDDのコストが高く、容量を出来る限り節約したい場合のみsmallintを利用し、integerの桁数で足りない値を格納する可能性がある場合はbigintを利用すると言った具合。

浮動小数点データ型

浮動小数点データ型の特徴は、小数を格納できること。型によって桁数に制限があるものとないものがある。桁数に制限がある型を利用しているフィールドにそれ以上の桁数を持つ値が入れられた場合、自動的に計算し、値を切り詰めて格納する。
例えば、real型のフィールドに12.34567という値が入った場合、格納後の値は12.3457となる。(最後の桁を四捨五入)

型名 最小桁
real 6桁までの整数及び小数
double precision 15桁までの整数及び小数
numeric 最大 131072桁の整数部と16383桁の小数部
decimal 最大 131072桁の整数部と16383桁の小数部

numericとdecimalの違い

Postgresでは、これらの値の違いはない。pgadminでは、decimal型のフィールドが選択できないようになっている(リストに表示されない)。 sqlではdecimal型を指定することはできるが、作成後に型を確認するとnumericに変換される。
image

自動採番型

この型は、値を入力しなくても自動的にシーケンステーブルから取得した値が登録される型となる。
serial型を指定すると、テーブル名シーケンスの値名seqという名前のシーケンスオブジェクトが作成され、関連付けられる。種類によって、最大値が異なる。

型名 最小桁
real 6桁までの整数及び小数
double precision 15桁までの整数及び小数
numeric 最大 131072桁の整数部と16383桁の小数部
decimal 最大 131072桁の整数部と16383桁の小数部

シーケンスが最大値に達した場合の挙動について

最大値に達した場合の挙動は、DB作成時に選択ができるようになっている。シーケンスオブジェクトの定義をプロパティから開くと、限界リセットというチェックボックスがある。ここがONになっていると限界値に達したときに一旦リセットされる。選択した型よりも限界値が大きくなっていたりすると、値がリセットされずにエラーが出続けてしまうので注意。
image
※キー項目などで限界値リセットすると、当然古い値との重複が避けられない。古いものを順に削除しているログなどの情報以外は、この選択は取れない可能性が高い。

まとめ

数値を格納する型の数だけを見てもこれだけの数の型があると、どれを使うか迷ってしまいますが、HDDの価格や記録できる領域が劇的に大きくなった昨今では、real型やsmallint型などの精度を犠牲にしてでも利用領域を小さくするような型を利用するシーンは少なくなってきている様に思います。整数を扱うフィールドならinteger型を、小数を扱うフィールドならnumeric型を選択するようにしておけば、間違いがないように思います。

参考ページ

https://www.postgresql.org/docs/current/static/datatype-numeric.html