データ型

PostgreSQL 8.0.0 文書
前のページ | 巻戻し |  | 早送り | 次のページ

# 第 8章データ型

PostgreSQLにはユーザが使用可能な豊富なデータ型が始めから備わっています。 `CREATE TYPE`コマンドでPostgreSQLに対し新しいデータ型を追加できます。

表8-1に組み込みの汎用データ型を全て示します。 "別名"欄に列挙された代替名称のほとんどは、歴史的な理由によりPostgreSQL の内部で使用されている名前です。 他にも、ここに記載していない、内部で使用されるデータ型、削除予定のデータ型もあります。

表 8-1. データ型

名称 | 別名 | 説明
--- | --- | ---
`bigint` | `int8` | 8バイト符号付整数
`bigserial` | `serial8` | 自動増分8バイト整数
`bit [ (`n`) ]` |  | 固定長ビット列
`bit varying [ (`n`) ]` | `varbit` | 可変長ビット列
`boolean` | `bool` | 論理（ブール）値（真/偽）
`box` |  | 平面上の矩形
`bytea` |  | バイナリデータ("バイトの配列(byte array)")
`character varying [ (`n`) ]` | `varchar [ (`n`) ]` | 可変長文字列
`character [ (`n`) ]` | `char [ (`n`) ]` | 固定長文字列
`cidr` |  | IPv4もしくはIPv6ネットワークアドレス
`circle` |  | 平面上の円
`date` |  | 暦の日付（年月日）
`double precision` | `float8` | 倍精度浮動小数点
`inet` |  | IPv4もしくはIPv6ホストアドレス
`integer` | `int`, `int4` | 4バイト符号付整数
`interval [ (`p`) ]` |  | 時間間隔
`line` |  | 平面上の無限直線
`lseg` |  | 平面上の線分
`macaddr` |  | MAC アドレス
`money` |  | 貨幣金額
`numeric [ (`p`, `s`) ]` | `decimal [ (`p`, `s`) ]` | 精度の選択可能な高精度数値
`path` |  | 平面上の幾何学的経路
`point` |  | 平面上の幾何学的点
`polygon` |  | 平面上の閉じた幾何学的経路
`real` | `float4` | 単精度浮動小数点
`smallint` | `int2` | 2 バイト符号付整数
`serial` | `serial4` | 自動増分 4 バイト整数
`text` |  | 可変長文字列
`time [ (`p`) ] [ without time zone ]` |  | 時刻
`time [ (`p`) ] with time zone` | `timetz` | 時間帯付き時刻
`timestamp [ (`p`) ] [ without time zone ]` |  | 日付と時刻
`timestamp [ (`p`) ] with time zone` | `timestamptz` | 時間帯付き日付と時刻

> 互換性: 次に挙げるデータ型(あるいはその綴り方)はSQLで規定されています。 `bit`、`bit varying`、`boolean`、`char`、 `character varying`、`character`、`varchar`、 `date`、`double precision`、`integer`、 `interval`、`numeric`、`decimal`、`real`、 `smallint`、`time`(時間帯付き、無しの両方)、 `timestamp`(時間帯付き、無しの両方)。

それぞれのデータ型はそのデータ型の入出力関数で決定される外部表現を保有しています。 組み込みデータ型の多くには、はっきりとした外部書式があります。 とはいっても、経路のようなPostgreSQLに特有な型や、あるいは、日付や時刻データ型のように書式を複数選択できる型が多くあります。 一部の入出力関数は転置することができません。 つまり、出力関数による結果は最初の入力と比較した場合精度を失う可能性があります。

# 8.1. 数値データ型

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

表 8-2. 数値データ型

型名 | 格納サイズ | 説明 | 範囲
--- | --- | --- | ---
`smallint` | 2バイト | 狭範囲の整数 | -32768から+32767
`integer` | 4バイト | 通常使用する整数 | -2147483648から+2147483647
`bigint` | 8バイト | 広範囲整数 | -9223372036854775808から9223372036854775807
`decimal` | 可変長 | ユーザ指定精度、正確 | 最大1000桁[訳注:原文ではno limitです]
`numeric` | 可変長 | ユーザ指定精度、正確 | 最大1000桁[訳注:原文ではno limitです]
`real` | 4バイト | 可変精度、不正確 | 6桁精度
`double precision` | 8バイト | 可変精度、不正確 | 15桁精度
`serial` | 4バイト | 自動増分整数 | 1から2147483647
`bigserial` | 8バイト | 広範囲自動増分整数 | 1から9223372036854775807

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

## 8.1.1. 整数データ型

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

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

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

SQLでは整数の型として`integer`(または`int`)と`smallint`のみを規定しています。 `bigint`と`int2`、`int4`、および `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を付与されることなく格納されます。 従って、列の宣言された精度と位取りは最大であり、固定的に割当てられていません。 (この意味では`numeric`は`char(`n`)`よりも`varchar(`n`)`に似ています。)

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

`decimal`と`numeric`型は等価です。 2つのデータ型は共に標準SQLに従っています。

## 8.1.3. 浮動小数点データ型

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

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

- （金銭金額など）正確な記録と計算が必要な時は代わりに`numeric`を使用してください。

- これらのデータ型で何か重要な件に対し複雑な計算を必要とする時、特に（無限大とかアンダーフローのような）境界線におけるある種の振舞いについて信頼を置かなければならないのであれば、実装を注意深く検証しなければなりません。

- 2つの浮動小数点値が等価であるのかどうかの比較は予想通りに行く時もあれば行かない時もあります。

ほとんどのプラットフォームでは`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の`float`と`float(`p`)`をサポートしています。 ここで、`p`は2進数の桁数で最低受け付ける精度を指定します。 PostgreSQLは`float(1)`から`float(24)`を`real`を選択するものとして受け付け、`float(25)`から`float(53)`を`double precision`を選択するものとして受け付けます。 許容範囲外の`p`の値はエラーになります。 精度指定の無い`float`は`double precision`として解釈されます。

> 注意: 7.4より前のPostgreSQLでは、`float(`p`)`の精度は10進数桁数として解釈されました。 これは、2進数桁数の精度を規定する標準SQLに一致するように変更されたものです。 `real`と`double 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 DEFAULT nextval('tablename_colname_seq') NOT NULL
    );

このように整数列を作成し、その列のデフォルト値が連番生成器から割り当てられるようにしました。 また、`NOT NULL`制約を適用することによって、null値が明示的に挿入されないようにします。 たいていの場合は、重複する値を間違って挿入しないように、`UNIQUE`制約または`PRIMARY KEY`制約も追加することが推奨されますが、これは自動的には行われません。

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

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

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

`serial`列用に作成されたシーケンスは、それを所有する列が削除された時に自動的に削除され、他の方法で削除されることはありません。 (このことは、PostgreSQLの7.3より前のバージョンには当てはまりません。 バージョン7.3より前のデータベースからのダンプをリロードすることによって作成されたシーケンスについては、この自動連鎖削除は発生しません。 それは、7.3より前のダンプファイルには、依存関係の繋がりを確立するために必要な情報が含まれていないからです。) 更にいえば、この依存関係は`serial`列によって生成されたシーケンスとこの列自体の間にだけ存在します。 もし他の列がこのシーケンスを参照していた(おそらく`nextval()`関数を手動で呼び出す)場合、このシーケンスが破棄されたらその関係は壊れてしまいます。 `serial`列のシーケンスをこのように使用することは好ましくないものとみなされています。 同一のシーケンス生成器から複数の列の値を提供したいのであれば、独立したオブジェクトとしてシーケンスを作成してください。

前のページ | ホーム | 次のページ
`LIMIT`と`OFFSET` | 上に戻る | 通貨型