PostgreSQLの数値型、どれを選ぶのが正解?パフォーマンスと精度の「ここだけの話」
やあ。今日はPostgreSQLの数値型について話をしようか。
データベースの設計を始めたばかりの頃、とりあえず「全部 `numeric` にしておけば間違いないでしょ」なんて思ってなかったかな? 気持ちはよくわかる。小数点以下の計算で誤差が出るなんて悪夢だもんな。でも、データベースエンジニアとして長く現場にいると、その「とりあえず」が後になって重いツケとして返ってくる瞬間を何度も見てきたんだ。
今日は、PostgreSQLが提供する数値型を、現場のリアリティを交えながら整理してみよう。
—
1. 整数型:迷ったら `integer`、溢れそうなら `bigint`
整数型は `smallint` (2バイト)、`integer` (4バイト)、`bigint` (8バイト) の3兄弟だ。
- `smallint`: 最近はあまり出番がないね。昔の省メモリ設計の名残みたいなものだ。
- `integer`: これが標準だ。IDやカウントなど、たいていの用途はこれで足りる。
- `bigint`: SNSのいいね数や、アクセスログのユニークIDなど、21億を超えそうな時は迷わずこれを選ぼう。
先輩からのアドバイス:
たまに「将来のために全部 `bigint` にしておこう」という設計を見るけれど、個人的にはおすすめしない。テーブルサイズが肥大化すると、インデックスの効率が落ちるし、キャッシュのヒット率も下がる。必要なサイズを予測して、適切な型を選ぶのが「いい設計」の第一歩だよ。
—
2. `numeric` (または `decimal`):お金を扱うならこれ一択
「正確さ」が求められる場面、特に金額計算では `numeric` 以外の選択肢はないと思っていい。
`numeric(p, s)` で精度(p)と位取り(s)を指定できるけど、何も指定しない `numeric` は非常に大きな数値を正確に扱える。その代わり、計算コストは他の型に比べて少し重い。
— 10桁の数字で、小数点以下2桁までを保証する
ALTER TABLE orders ADD COLUMN total_amount numeric(10, 2);
現場の教訓:
`numeric` で計算した結果をアプリケーション側でどう扱うかも重要だ。DBは正確でも、アプリ側で `float` にキャストして計算しちゃったら、そこで誤差が爆誕する。型変換の境界線には常に気を配っておこう。
—
3. 浮動小数点型:`real` と `double precision` はどこで使う?
`real` (4バイト) と `double precision` (8バイト) は、科学技術計算や統計など、「多少の誤差は許容するが、とにかく速度とレンジを重視する」という用途向けだ。
- `double precision`: `double` 型。ほとんどの用途で使うならこっちだね。
- `real`: `float` 型。精度よりもメモリ効率を優先するニッチな場面向け。
注意点:
これらはIEEE 754規格に基づいているから、`0.1 + 0.2` が `0.3` にならないような現象が起きる。「えっ、なんで!?」と後輩が叫んでいる声が聞こえてきそうだよ。金額計算にこれらを使うのは、絶対にNGだ。 これだけは覚えて帰ってくれ。
—
インデックス設計への影響
さて、ここからがエンジニアの腕の見せ所だ。数値型の選択は、インデックスの性能に直結する。
1. サイズが小さいほど有利: `integer` は `bigint` よりインデックスが小さくなる。数億行規模のテーブルでは、この数バイトの差がクエリの応答速度に響いてくるんだ。
2. 比較演算のコスト: 整数同士の比較はCPUにとって非常に軽い。逆に `numeric` の比較は、内部的に特殊な構造を処理するため、整数よりはコストがかかる。
3. 範囲検索: `numeric` で精度を指定している場合、範囲検索の実行計画が最適化されやすい。
—
まとめ:どう使い分けるか?
現場での指針をまとめておくよ。
- IDやカウント: `integer` (足りなければ `bigint`)。
- 金額: `numeric` 一択。
- 科学計算や統計データ: `double precision`。
- 「とりあえず `numeric`」は禁止: 必要な精度を見極めること。それがパフォーマンスの最適化につながる。
データベース設計は、いわば「情報の器」を作る仕事だ。器が大きすぎれば持ち運びに苦労するし、小さすぎれば中身が溢れてしまう。
今日の話が、君の次なるDB設計のヒントになれば嬉しい。もし「このケースだとどうすればいい?」という悩みがあれば、いつでも相談してくれよな。
それじゃ、また現場で会おう。
コメント