データ型の選び方
型は「その列に何が入るか」を決めるだけのものではありません。並べ替えの順番、計算の精度、後から検索できるかどうかまで、全部この 1 語で決まります。ここでは、迷いやすくて後から直すのが高くつく 3 か所だけを押さえます。
| 入れたいもの | 既定で選ぶ型 | 使ってはいけない型 |
|---|---|---|
| 金額 | DECIMAL(12, 2) | FLOAT DOUBLE |
| 日付や日時 | DATE TIMESTAMP | VARCHAR |
| 名前やメール | VARCHAR(n) | CHAR(n) |
金額を FLOAT で持つと、1 円合わない
FLOAT と DOUBLE は、実数をおおよその値として高速に扱うための型です。0.1 + 0.2 が 0.3 にならない、あの世界がそのまま列の中で起きます。1 件では気付かなくても、1 万件を合計した請求書で数十円ずれます。
SQL クエリ
-- 避ける 合計するたびに端数がずれる
CREATE TABLE invoices (
total FLOAT
);
-- 使う 桁数を自分で決めて、ずれない
CREATE TABLE invoices (
total DECIMAL(12, 2)
);DECIMAL(全体の桁数, 小数の桁数) と読みます。12, 2 なら整数部 10 桁と小数 2 桁です。金額、税率、ポイント残高のように「1 円ずれたら困る」列には必ずこちらを使います。
数値でもう 1 つ。ID のように増え続ける整数は、INT の上限 (約 21 億) に届く前に BIGINT にしておきます。行が積み上がってから型を広げるのは、テーブル全体を作り直す作業になります。
日付を文字列で持つと、並べ替えで壊れる
日付を VARCHAR で持つと、まず書式が混ざります。2026-08-09 を入れる人と 2026/8/9 を入れる人が出て、どちらも通ってしまうからです。
SQL クエリ
-- 避ける '2026/8/9' が '2026/12/1' より後ろに並ぶ
published_on VARCHAR(20)
-- 使う
published_on DATE文字列の比較は辞書順なので、'2026/8/9' は '2026/12/1' より大きいと判定されます。並べ替えも期間の絞り込みも、静かに間違った結果を返します。日付型にしておけば、順番も、日数の足し引きも、データベース側が正しく面倒を見てくれます。時刻が要らないなら DATE、いつ起きたかを記録する列なら TIMESTAMP です。
文字数が読めない列は、可変長にする
CHAR(n) は常に n 文字分の場所を確保し、足りない分を空白で埋めます。長さが本当に固定のもの、たとえば通貨コードの JPY のような 3 文字のコードにだけ向いています。それ以外は VARCHAR(n) を既定にしてください。上限を決められない本文や記事は TEXT です。
SQL クエリ
-- 長さが本当に固定のときだけ CHAR
currency_code CHAR(3)
-- それ以外は可変長を既定にする
display_name VARCHAR(50)
article_body TEXTn には、アプリ側で許す最大の長さを素直に書きます。メールアドレスなら 255、表示名なら 50 といった具合です。「とりあえず 255」と置くと、後から見た人がその数字の根拠を追えなくなり、誰も縮められなくなります。
テーブル構造
SELECT 1;期待される出力
| column_name | data_type |
|---|---|
| id | bigint |
| character varying | |
| country_code | character |
| age | integer |
| balance | numeric |
| joined_at | timestamp without time zone |