はじめに
データ型の基本
データ型の役割と主要カテゴリ(数値 / 文字列 / 日時 / 真偽 / JSON / UUID / 空間)を俯瞰する。
なぜ「型」が重要なのか
RDBMS ではテーブルの各列にデータ型(型)を宣言します。型は単なる形式指定ではなく、データの意味・演算規則・格納サイズ・インデックスの有効性を決める設計判断です。
- 正しさを保証:
age INTEGERに"abc"は入らない。文字列と数値の誤混入を DBMS が弾く - 演算の意味が確定:
'2026-01-01' + 1が「1 日後」になるか「文字列連結」になるかは型で決まる - 容量と速度:
SMALLINTとBIGINTでは 1 行あたり 6 バイト差、1 億行なら約 600 MB の差になる - インデックス効率: 桁数を超えた長い文字列を
VARCHAR(n)で受け入れてしまうと B-Tree が肥大化する。適切な上限設定とインデックス対象列の型選びがポイント
型選びは「動けば何でもいい」ではなく、意味と性能と移植性のバランスを取る設計作業です。
テーブル例 — ユーザー / 口座 / 入出金
抽象論に入る前に、銀行の勘定系を小さくした 3 テーブルを ER 風に並べます。ID は BIGINT・金額は NUMERIC(14,2)・日時は TIMESTAMPTZ・フラグは BOOLEAN・分散採番したい PK は UUID のように、意味ごとに型を使い分けるのが型設計の基本です。各型の詳細は次節で整理します。
ER 図自体の書き方・読み方は ER 図入門 で解説しています。
主な型カテゴリ
RDBMS が提供する型は、用途ごとに以下のカテゴリに整理できます。まずこの分類を押さえれば、製品ごとの具体名(次節のマッピング表)は差分として捉えやすくなります。
| カテゴリ | 典型的な用途 | 代表的な型名 | ポイント |
|---|---|---|---|
| 整数 | 連番 / 件数 / 年齢 | SMALLINT / INTEGER / BIGINT | 範囲を見積もってサイズを選ぶ |
| 固定小数(exact) | 金額 / 単価 / 率 | NUMERIC(p,s) / DECIMAL(p,s) | 丸め誤差が出ないのが必須用途 |
| 浮動小数(approx) | 統計量 / 科学計算 | REAL / DOUBLE | 誤差を許容できる用途に限定 |
| 文字列 | 名前 / 本文 / コード | VARCHAR(n) / TEXT / CHAR(n) | 可変長が基本。固定長は ID コード等で |
| 日付・時刻 | 誕生日 / 予約日時 / ログ | DATE / TIME / TIMESTAMP | タイムゾーン付き型を基本にする |
| 真偽 | フラグ / 有効・無効 | BOOLEAN / BIT / TINYINT(1) | ネイティブ BOOLEAN があれば優先 |
| バイナリ | 画像 / ファイル / ハッシュ | BYTEA / BLOB / VARBINARY | 大きなファイルは DB 外に置く検討も |
| JSON | 半構造データ / スキーマ可変 | JSONB / JSON / NVARCHAR + JSON 関数 | 検索するなら列に出すのが基本 |
| UUID | 分散生成可能な一意識別子 | UUID / UNIQUEIDENTIFIER / RAW(16) | ネイティブ型が無い RDBMS では文字列代用 |
| 空間(ジオ) | 位置 / 範囲 / 経路 | GEOMETRY / GEOGRAPHY / POINT | 緯度経度 2 列ではなく空間型で距離・範囲検索 |
型選択の実務 tips
- 金額は必ず固定小数(NUMERIC / DECIMAL)。FLOAT / DOUBLE は丸め誤差が蓄積し、会計上の値不一致の原因になる
- 真偽は BOOLEAN ネイティブ型を優先。MySQL / Oracle のように無い場合も
TINYINT(1)/NUMBER(1)+CHECK (col IN (0,1))で意味を明示 - 日時は TZ 付き型を基本に。PostgreSQL の
TIMESTAMPTZ/ SQL Server のDATETIMEOFFSET。MySQL / SQLite は UTC で保存し、アプリ側で変換が定石 - VARCHAR(n) の n は「保存可能な最大文字数」であって「常に n バイト確保する」わけではない。短いデータでも無駄な領域は発生しない(固定長
CHAR(n)は別) - JSON は「検索しない付帯データ」に限定。頻繁に WHERE / ORDER BY の条件になる値は通常の列に出すのが性能上有利(詳しくは 型選択ガイド)
- UUID を主キーにする場合は v4(ランダム)より v7(時系列順)を選ぶ。B-Tree 挿入の断片化を避けられる(詳しくは UUID インデックス)
- SQLite は「型アフィニティ」で緩い。宣言した型と違う値も格納できてしまうため、厳密にしたい場合は
STRICTテーブル(3.37+)を使う
