システム列

PostgreSQL 9.0.0文書
前のページ | 巻戻し | 第 5章データ定義 | 早送り | 次のページ

# 5.4. システム列

全てのテーブルには、システムによって暗黙的に定義されたシステム列がいくつかあります。 そのため、システム列の名前はユーザ定義列の名前として使うことはできません。 （これらの制約は名前がキーワードであるかどうかとは関係ありません。 つまり、名前を引用符で囲んでもこの制約を回避することはできません。） システム列については、あまり意識する必要はありません。 これらが存在することを知っていれば十分です。

`oid`

  行のオブジェクト識別子（オブジェクトID）です。 この列は`WITH OIDS`を付けた場合と、その時にdefault_with_oidsが設定されていた場合に作成されます。 この列の型は`oid`（列名と同じ）です。この型についての詳細は項8.16を参照してください。

`tableoid`

  この行を含むテーブルのOIDです。 この列は特に、継承階層からの選択問い合わせでは便利です（項5.8を参照してください）。 この列がないと、どのテーブルからその行が来たのかわかりにくいからです。 `tableoid`はテーブル名を得るために`pg_class`の`oid`列に結合することができます。

`xmin`

  この行バージョンの挿入トランザクションの識別情報（トランザクションID）です。 （行のバージョンとは、行の個別の状態です。 行が更新される度に、同一の論理的な行に対する新しいバージョンの行が作成されます。）

`cmin`

  挿入トランザクション内の（0から始まる）コマンド識別子です。

`xmax`

  削除トランザクションの識別情報（トランザクションID）です。 削除されていない行ではゼロです。 可視のバージョンの行でこの列が非ゼロの場合があります。 これは通常、削除トランザクションがまだコミットされていないこと、または、削除の試行がロールバックされたことを意味しています。

`cmax`

  削除トランザクション内のコマンド識別子、もしくはゼロです。

`ctid`

  テーブル内における、行バージョンの物理的位置を表します。 `ctid`は行バージョンを素早く見つけるために使うことができますが、行の`ctid`は更新されたり、`VACUUM FULL`により移動させられたりすると変わります。 したがって、`ctid`は長期の行識別子としては使えません。 論理行を識別するためには、OID、あるいはさらに良いのはユーザ定義の通番数を使うべきです。

OIDは32ビット数であり、クラスタ全体で1つのカウンタです。 大規模、もしくは長期間使用するデータベースでは、カウンタが一周してしまう可能性があります。 そのため、一意性を確保するための手順を踏んでいない限り、OIDが一意であると仮定してはなりません。 もしテーブル内の行を同定する必要がある場合は、シーケンスジェネレータを使用することを強く推奨します。 しかし、OIDはいくつかの注意を払うことによりシーケンスと同様に使用することができます。

- 一意性制約は、OIDが行を同定するために使用されるようなテーブルのOID列に作成されなくてはいけません。 このような一意性制約（もしくは一意インデックス）が存在する場合は、システムは既存の行に一致するようなOIDを生成しません。 （もちろん、これはテーブルの行数が232（40億）より少ない場合に可能となります。性能を考慮すると、実際には行数はそれよりずっと少ない方がよいでしょう。）

- OIDは複数のテーブルをまたがって一意であると仮定してはなりません。 データベース全体での識別子が必要な場合は`tableoid`と行OIDを組み合わせて使用してください。

- もちろん、問題にしているテーブルは、`WITH OIDS`を使用して作成されなくてはいけません。 PostgreSQL 8.1から`WITHOUT OIDS`がデフォルトです。

トランザクション識別子も32ビット量です。 長期間使用するデータベースでは、トランザクションIDが一周してしまう可能性があります。 これは、適切な保守作業を行うことで、致命的な問題にはなりません。 詳細は第23章を参照してください。 しかし、長期（10億トランザクション以上）にわたってトランザクションIDの一意性に依存することは賢明ではありません。

コマンド識別子もまた、32ビット量です。 このため、単一トランザクション内のコマンド数には232（40億）個までという制限が発生します。 実際、この制限は問題にはなりません。 これはSQLコマンド数に対する制限であり、処理される行数に対する制限ではないことに注意してください。 またPostgreSQL 8.3から、データベースの内容を実際に変更するコマンドのみがコマンド識別子を消費します。

前のページ | ホーム | 次のページ
制約 | 上に戻る | テーブルの変更