PostgreSQLのデータ型、迷ったらこれを選べ!現場で役立つ「適材適所」の選び方
データベース設計の現場で、新人エンジニアからよく相談されるのが「データ型、結局どれを選べばいいの?」という質問です。
PostgreSQLは非常に多機能で、`text`一つとっても、他のDBと比べて扱いが少し特殊だったりしますよね。教科書通りの定義を覚えるのも大切ですが、実務で大事なのは「後で泣きを見ないための選択」です。
今日は、僕が普段の設計で意識している「PostgreSQLデータ型の勘所」を、現場の知見を交えてお話しします。
—
1. 数値型:`integer`か、`numeric`か、それとも?
まずは数値型。ここでの鉄則はシンプルです。
- `integer` (または `bigint`): 整数なら迷わずこれ。IDなどのカウントアップ系は、将来を見越して最初から`bigint`にしておくのが僕の流儀です。「後から`integer`が溢れました」という改修は、テーブルロックの問題もあって胃が痛くなる作業ですからね。
- `numeric` (または `decimal`): 金額を扱うならこれ一択。`float`や`real`は厳密な計算には向きません。浮動小数点特有の誤差で、決済金額が1円合わない……なんて事故は絶対に避けたいところです。
— IDは余裕を持ってbigintで
CREATE TABLE orders (
id BIGINT PRIMARY KEY GENERATED ALWAYS AS IDENTITY,
— 金額は精度とスケールを指定(例:12桁、小数点以下2桁)
price NUMERIC(12, 2) NOT NULL
);
—
2. 文字列型:`varchar`より`text`を推す理由
PostgreSQLに慣れていない人がやりがちなのが、`varchar(255)`をとりあえず多用すること。
実はPostgreSQLにおいて、`varchar(n)`と`text`の性能差はほとんどありません。むしろ、`varchar(255)`と指定すると、後で「あ、300文字必要になった」という時に`ALTER TABLE`で長さを変更する手間が発生します。
「長さ制限がビジネスロジック的に必須な場合」以外は、`text`型を使っておけば間違いありません。 制限が必要なら、チェック制約(`CHECK`)を付ければいいだけですから。
—
3. 真偽値型:`boolean`は正義
他のDBだと「0と1」で管理することも多いですが、PostgreSQLには立派な`boolean`型があります。これを使わない手はありません。
— 読みやすさが段違い
ALTER TABLE users ADD COLUMN is_active BOOLEAN DEFAULT TRUE;
— クエリも直感的
SELECT FROM users WHERE is_active IS TRUE;
`IS TRUE` / `IS FALSE` という書き方ができるのもPostgreSQLの嬉しいところですね。
—
4. 日付・時刻型:沼にハマらないために
日付型で一番多いミスは、タイムゾーンの扱いです。
- `timestamp with time zone` (timestamptz): 現場の標準です。これを使っておけば、サーバーのタイムゾーンが変わってもPostgreSQLがいい感じに計算してくれます。
- `timestamp` (without time zone): タイムゾーンを考慮したくない、「ただのラベル」としての日時(例:カレンダーの予定など)以外では、基本避けるのが無難です。
— 日時データは迷わずtimestamptz
CREATE TABLE logs (
created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP
);
—
5. 最後に:設計は「未来への投資」です
データ型を適当に選ぶと、数年後の自分が苦しむことになります。
- 「将来的にデータが増えたら?」
- 「計算の精度でバグが出ないか?」
- 「アプリケーション側のコードと整合性が取れるか?」
これらを少し立ち止まって考えるだけで、システムの堅牢性はグッと上がります。PostgreSQLは非常に懐の深いデータベースです。適切な型を選んで、気持ちよく開発を進めていきましょう!
もし、「このデータ、何型にするのがベストなんだろう?」という具体的な悩みがあれば、いつでも相談してくださいね。現場からは以上です!
コメント