DBAtlas · データベース運用アトラス

判断: 適切なデータ型の選択

データ型の選択は、後から修正するのが最もコストの高い決定の 1 つ: 誤った型は誤った結果 (例: 金額に float)、領域の浪費、低速なクエリを生む。このツリーは、数値、テキスト、日付/時刻、キー (PK)、半構造化 (JSON)、カテゴリ (ENUM) の各フィールドに適切な型を導き、金額やキャラクタセットなどの典型的な落とし穴を強調する。

どのような種類のデータを格納するか?

適切な型はデータの性質によって決まる。フィールドはどのカテゴリに該当するか: 数値、テキスト、日付/時刻、テーブルの主キー、柔軟/半構造化 (JSON) データ、または限定されたカテゴリの集合か?

  • 数値 (数量、金額、測定値、カウンタ)
  • テキスト (名前、説明、コード)
  • 日付および/または時刻
  • 主キー (PK) を設計している
  • 柔軟/ネスト/可変のフィールド (半構造化データ)
  • 限定された既知のカテゴリの集合 (ステータス、種類、優先度)

数値は整数か小数か — そして金額か?

数値で最も重要な区別は正確性。値は整数 (数量、ID、カウンタ) か、小数か? 小数の場合、金額/財務上の金額か? 2 進浮動小数点 (FLOAT/DOUBLE) は丸め誤差を生じるため、金額や正確性が必要な場面では決して使用しない。

  • 整数 (数量、カウンタ、id)
  • 金額または正確な小数 (価格、残高、レート)

推奨: 整数 (SMALLINT / INT / BIGINT)

整数の場合、必要な範囲をカバーする最小の型を選ぶ。不必要に大きな型は領域とインデックスサイズを浪費する。ただし、カウンタ/PK など増加し得るフィールドでは、オーバーフローを防ぐために十分な幅が不可欠。

推奨: NUMERIC / DECIMAL — 金額には決して FLOAT を使わない

金額と正確な小数には固定小数点 (正確な) NUMERIC/DECIMAL を使用する。FLOAT/DOUBLE は 2 進浮動小数点であり、0.1 のような値を正確に格納できない。加算/乗算で端数のずれ、誤った残高、監査上の問題が生じる。

推奨: テキスト — VARCHAR vs TEXT vs CHAR

テキストには、可変長には VARCHAR/TEXT を、真の固定長には CHAR を使用する。最新のエンジンでは VARCHAR と TEXT のストレージ上の違いはほとんど無視できる。本当の判断は、意味上の上限 (長さ制約) を課すかどうか。

推奨: 日付/時刻 — タイムゾーン付き TIMESTAMP

時点 (イベントの時刻) を格納する場合は、タイムゾーンを考慮する型を選択する。タイムゾーンなしで格納すると、リージョン間/夏時間の切り替え時に計算と比較を誤る。

推奨: 主キー — BIGINT vs UUID

PK には主に 2 つの選択肢がある: 増加する数値 (BIGINT の identity/シーケンス) または UUID。数値の PK は小さくインデックスに適しているが、予測可能で集中的な採番が必要。UUID は分散して生成できるが、サイズが大きく、ランダムな順序がインデックスに悪影響を与える場合がある。

推奨: JSON / JSONB — 適度に使用する

JSON 型は、柔軟なスキーマを持つフィールド、ネストしたフィールド、疎なフィールドに対して強力。ただし、リレーショナルの規律 (制約、インデックス、型安全性) が失われる場合がある。ルール: 固定的で頻繁に照会されるフィールドは通常の列に移し、本当に可変な部分のみを JSON に保持する。

推奨: ENUM vs ルックアップ (参照) テーブル

限定されたカテゴリの集合には 2 つの選択肢がある: エンジンの ENUM 型、またはルックアップテーブル + 外部キー。ENUM はコンパクトでシンプルだが、値の追加にはスキーマ変更が必要。ルックアップテーブルは柔軟で、追加の属性 (説明、有効フラグ、表示順) を持たせられる。

DBAtlas で開く →