主キーに最適?PostgreSQLのbigserialデータ型を徹底解説


特性

  • 自動採番: 各行挿入時に、直前の行の値 + 1 が自動的に割り当てられる
  • デフォルト値: なし
  • 格納値: 1 から 9,223,372,036,854,775,807までの正整数
  • データ型: bigint

利点

  • 参照整合性: 外部キーとの参照整合性を容易に実現
  • 整列: 順序付けられた行IDとして機能
  • 主キー: ユニークな行識別子をシンプルに実装できる

欠点

  • 小数点: 表現できない
  • 負の値: 格納できない
  • シーケンス管理: 内部的にシーケンスを利用するため、パフォーマンスへの影響が若干懸念される

類似データ型との比較

データ型説明
smallserial: 1 から 2,147,483,647までの整数を格納bigserialよりも小さい範囲
serial: 1 から 4,294,967,295までの整数を格納bigserialよりも小さい範囲
integer: -2,147,483,648から 2,147,483,647までの整数を格納自動採番機能なし
bigint: -9,223,372,036,854,775,807から 9,223,372,036,854,775,807までの整数を格納手動による値設定が必要

使用例

CREATE TABLE users (
  user_id BIGSERIAL PRIMARY KEY,
  username VARCHAR(255) NOT NULL,
  email VARCHAR(255) UNIQUE NOT NULL,
  created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
);

上記の例では、users テーブルに user_id という列が作成されています。 この列は bigserial 型で、自動的に採番される主キーとなります。

bigserial は、主に以下の用途で役立ちます。

  • 順序付けが必要なデータのID
  • トランザクション履歴やログエントリの識別子
  • ユーザーテーブルなどのエンティティを表すテーブルの主キー
  • bigserial 型は、シーケンスと呼ばれる内部オブジェクトを使用して実装されています。 各テーブルに対して専用のシーケンスが作成され、行挿入時にシーケンスの次ぎの値が割り当てられます。


例1:シンプルなユーザーテーブルの作成

この例では、users というテーブルを作成し、user_id という bigserial 型の主キー列を追加します。

CREATE TABLE users (
  user_id BIGSERIAL PRIMARY KEY,
  username VARCHAR(255) NOT NULL,
  email VARCHAR(255) UNIQUE NOT NULL,
  created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
);

例2:bigserial列の値の取得

この例では、users テーブルから user_id 列の値を取得する方法を示します。

SELECT user_id FROM users;

例3:bigserial列を使用したシーケンスの操作

この例では、users テーブルに対応するシーケンスを操作する方法を示します。

-- シーケンスの現在値を取得
SELECT nextval('users_user_id_seq');

-- シーケンスの最大値を設定
ALTER SEQUENCE users_user_id_seq MAXVALUE 100000;

-- シーケンスのインクリメント値を変更
ALTER SEQUENCE users_user_id_seq INCREMENT BY 10;

例4:bigserial列の制約の追加

この例では、users テーブルの user_id 列に制約を追加する方法を示します。

ALTER TABLE users
ADD CONSTRAINT user_id_min_value CHECK (user_id >= 1);

ALTER TABLE users
ADD CONSTRAINT user_id_max_value CHECK (user_id <= 1000);
  • 実際の使用場面に合わせて、適宜コードを修正してください。
  • 上記のコードは、PostgreSQL 9.6以降で動作確認済みです。


bigint 型とシーケンスの組み合わせ

  • シーケンスを用いて、各行挿入時に自動的に採番された値を割り当てることができます。
  • bigint 型は、-9,223,372,036,854,775,807 から 9,223,372,036,854,775,807 までの整数を格納できます。
CREATE TABLE users (
  user_id BIGINT PRIMARY KEY,
  username VARCHAR(255) NOT NULL,
  email VARCHAR(255) UNIQUE NOT NULL,
  created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
);

CREATE SEQUENCE users_user_id_seq;

ALTER TABLE users
  DEFAULT nextval('users_user_id_seq');

利点

  • シーケンスのカスタマイズが可能(開始値、インクリメント値など)
  • bigserial 型よりも柔軟性が高い

欠点

  • bigserial 型よりも若干複雑な記述が必要

uuid 型

  • 重複の可能性が極めて低いため、主キーとして適しています。
  • UUID は、128 ビットのランダムな値を表すデータ型です。
CREATE TABLE users (
  user_id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  username VARCHAR(255) NOT NULL,
  email VARCHAR(255) UNIQUE NOT NULL,
  created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
);

利点

  • 分散システムでのデータ連携に適している
  • ユニーク性の保証

欠点

  • ソートや比較演算に時間がかかる場合がある
  • bigint 型や smallserial 型よりも格納サイズが大きい

最適な代替方法の選択

  • ユニーク性の保証と分散システムでの利用: uuid 型がおすすめです。
  • 柔軟性とカスタマイズ性: bigint 型とシーケンスの組み合わせがおすすめです。
  • シンプルで使いやすい: bigserial 型がおすすめです。

上記に加え、以下の点も考慮する必要があります。

  • アプリケーションの要件
  • データベースのパフォーマンス
  • 既存のシステムとの互換性
  • integer 型: -2,147,483,648 から 2,147,483,647 までの整数を格納できます。
  • smallserial 型: 1 から 2,147,483,647 までの整数を格納できます。