8.1. 数値データ型

数値データ型には2、4、8バイト整数と、4、8バイト浮動小数点および精度設定が可能な数があります。 表8-2に使用可能な型を列挙します。

表 8-2. 数値データ型

型名格納サイズ説明範囲
smallint2バイト狭範囲の整数-32768から+32767
integer4バイト通常使用する整数-2147483648から+2147483647
bigint8バイト広範囲整数-9223372036854775808から9223372036854775807
decimal可変長ユーザ指定精度、正確最大1000桁[訳注:原文ではno limit]
numeric可変長ユーザ指定精度、正確最大1000桁[訳注:原文ではno limit]
real4バイト可変精度、不正確6桁精度
double precision8バイト可変精度、不正確15桁精度
serial4バイト自動増分整数1から2147483647
bigserial8バイト広範囲自動増分整数1から9223372036854775807

数値データ型に対する定数の構文は項4.1.2で説明しています。 数値データ型には対応する算術演算子と関数の一式が揃っています。 詳細は第9章を参照してください。 次節でデータ型について詳しく説明します。

8.1.1. 整数データ型

smallintintegerbigintは各種範囲の整数、つまり小数点以下の端数がない数を保持します。 許容範囲から外れた値を保存しようとするとエラーになります。

integer型は数値の範囲、格納サイズおよび性能において最も釣合いが取れていますので、通常使用されます。 smallint型は一般的にディスク容量に制限が付いている場合にのみ使用します。 bigint型はintegerの許容範囲では十分ではない場合にのみ使用すべきです。 integerデータ型の方がずっと速いからです。

8バイト整数をコンパイラがサポートしているかどうかに依存しますので、bigint型は全てのプラットフォームで正常に機能するとは限りません。 サポートしていないマシン上ではbigintintegerと同じように振舞います(しかし、領域は8バイトまで必要です)。 しかしながら、このようなことが現実の問題を起こすようなプラットフォームがあるかどうかわかりません。

SQLでは整数の型としてinteger(またはint)とsmallintのみを規定しています。 bigintint2int4、およびint8は拡張ですが、他の様々なSQLデータベースシステムでも使われています。

8.1.2. 任意の精度を持つ数

numeric型は、最大1000桁の精度で数値を格納でき、正確な計算を行えます。 通貨金額やその他正確性が求められる数量を保存する時は特に、この型を推奨します。 とは言っても、numericの値に対する算術演算の動作は整数や、次節で説明する浮動小数点データ型に比較し非常に遅くなります。

この後の説明では、次の用語を使用します。 numeric位取りとは、小数点の右側の小数点以下の桁数をいいます。 numeric精度とは数字全体の有効桁数です。 すなわち、小数点をはさんでいる両側の桁数の合計です。 そのため、23.5141という数値の精度は6で位取りは4となります。 整数の位取りは、ゼロであるとみなすことができます。

numeric列の数値の最大精度と最大位取りはともに設定することができます。 列のデータ型をnumericと宣言するには次の構文を使います。

NUMERIC(precision, scale)

精度は正数、位取りは0もしくは正数でなければなりません。 他に

NUMERIC(precision)

は位取りが0であることを選択します。

NUMERIC

精度または位取りの指定がない場合、実装されている限界の精度まで、いかなる精度あるいは位取りの値も格納できる列が作られます。 この類の列はいかなる特定の位取りに対しても入力値を強要しませんが、宣言された位取りを持つnumeric列は入力値にその位取りを強要します (標準SQLはデフォルトとして位取り0を要求していて、整数に対する厳密性を強制しています。 しかし、この方法はあまり役に立たないと思われます。 もし移植性を心配するなら、常に精度と位取りを明示的に設定してください)。

格納される値の位取りが宣言された列の位取りより大きかった場合、システムは指定された小数部の桁まで値を丸めます。 そして、小数点の左側の桁数が、宣言された精度から宣言された位取りを差し引いた数を超える場合にエラーとなります。

数値は物理的に先頭や末尾に0を付与されることなく格納されます。 したがって、列の宣言された精度と位取りは最大であり、固定的に割り当てられていません (この意味ではnumericchar(n)よりもvarchar(n)に似ています)。実際の格納に必要は容量は、10進数4桁のそれぞれのグループに対して2バイトと、8バイトのオーバヘッドです。

通常の数値に加え、numeric型は、"非数値"を意味するNaNという特別な値を取ることができます。 NaNに対する操作は全て、別のNaNを生成します。 この値をSQLコマンドの定数として記述する場合は、例えばUPDATE table SET x = 'NaN'のように、引用符で括らなければなりません。 入力の際は、NaNという文字列は大文字小文字の区別なく認識されます。

decimalnumeric型は等価です。 2つのデータ型はともに標準SQLに従っています。

8.1.3. 浮動小数点データ型

realdouble precisionは不正確な可変精度の数値データ型です。 実際にはこれらのデータ型は、使用しているプロセッサ、オペレーティングシステムおよびコンパイラがサポートしていれば、通常は(それぞれ単精度および倍精度の)バイナリ浮動小数点演算用のIEEE規格754の実装です。

不正確というのは、ある値はそのままで内部形式に変換されずに近似値として保存されるということです。 ですから、保存しようとする値と保存された値を戻して表示した場合に多少の差異が認められます。 これらのエラーを管理し計算によって補正をどうするかは、数学の系統全部とコンピュータ科学に関わることで、以下の点を除きこれ以上のことは触れません。

ほとんどのプラットフォームではrealは最低6桁の精度を持った少なくとも-1E+37と+1E+37の範囲です。 double precisionは通常最低15桁の精度でおよそ-1E+308と+1E+308の範囲です。 大き過ぎたり小さ過ぎる値はエラーの原因となります。 入力値の精度が高過ぎる場合は丸められることがあります。 ゼロに限りなく近い値で、しかもゼロとは区別されているようにみなされない数値はアンダーフローエラーを引き起こします。

通常の数値に加え、浮動小数点型では以下の特殊な値を取ります。

Infinity
-Infinity
NaN

これらはそれぞれ、IEEE 754の特殊な値、"無限大", "負の無限大""非数値"を表します (浮動小数点計算がIEEE 754に従わないマシンでは、これらの値はおそらく正しく動作しません)。 これらの値をSQLコマンドの定数として記述する場合、例えばUPDATE table SET x = 'Infinity'のように引用符で括る必要があります。 入力の際、これらの文字列は大文字小文字の区別なく認識されます。

また、PostgreSQLでは不正確な数値型を規定する標準SQLのfloatfloat(p)をサポートしています。 ここで、pは2進数の桁数で最低受け付ける精度を指定します。 PostgreSQLfloat(1)からfloat(24)realを選択するものとして受け付け、float(25)からfloat(53)double precisionを選択するものとして受け付けます。 許容範囲外のpの値はエラーになります。 精度指定のないfloatdouble precisionとして解釈されます。

注意: 7.4より前のPostgreSQLでは、float(p)の精度は10進数桁数として解釈されました。 これは、2進数桁数の精度を規定する標準SQLに一致するように変更されたものです。 realdouble precisionの仮数がそれぞれ24ビットと53ビットであるという前提は、IEEE標準浮動小数点の実装では正しいものです。 非IEEEのプラットフォームでは、一部無効になる可能性がありますが、単純化のために全てのプラットフォームでpの範囲は同一です。

8.1.4. 連番型

serialおよびbigserialデータ型は正確にはデータ型ではなく、テーブルの列に一意の識別子を設定する簡便な表記法です (他のデータベースでサポートされるAUTO_INCREMENTプロパティに似ています)。 現在の実装では、

CREATE TABLE tablename (
    colname SERIAL
);

は以下を指定することと同じです。

CREATE SEQUENCE tablename_colname_seq;
CREATE TABLE tablename (
    colname integer NOT NULL DEFAULT nextval('tablename_colname_seq')
);
ALTER SEQUENCE tablename_colname_seq OWNED BY tablename.colname;

このように整数列を作成し、その列のデフォルト値が連番ジェネレータから割り当てられるようにしました。 また、NOT NULL制約を適用することによって、NULL値が明示的に挿入されないようにします。 (たいていの場合は、重複する値を間違って挿入しないように、UNIQUE制約またはPRIMARY KEY制約も追加することが推奨されますが、これは自動的には行われません。) 最後に、シーケンスは列に"より所有"されるものと印が付きます。 したがって、テーブルの列が削除された場合にシーケンスは削除されます。

注意: PostgreSQL 7.3より前では、serialUNIQUEを意味していました。 現在では自動的には行われません。 連番の列に一意性制約もしくはプライマリキーを付与したい場合は、他のデータ型同様指定しなければなりません。

serial列にシーケンスの次の値を挿入するには、serial列にそのデフォルト値を割り当てるよう指定してください。 これは、INSERT文の列リストからその列を除外する、もしくはDEFAULTキーワードを使用することで行うことができます。

serialserial4という型の名称は等価です。 ともにinteger列を作成します。 bigserialserial8という型の名称もbigint列を作成することを除いて同じ振舞いをします。 もしテーブルを使用する期間で231以上の識別子を使用すると予測される場合、bigserialを使用しなければいけません。

serial列用に作成されたシーケンスは、それを所有する列が削除された時に自動的に削除されます。 列を削除せずにシーケンスを削除することができますが、これにより強制的に列のデフォルト式が削除されます。