主キーに最適?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 までの整数を格納できます。