MLOpsのDBには「推論リクエストログ」「学習データ」「モデルメタ情報」など、柔軟に変化するデータが多く入ってきます。そこでよく使われるのが JSONB


JSONBとは?

PostgreSQLが提供する JSON型の拡張版 です。
通常のJSONは「文字列」として保存されますが、JSONBは バイナリ形式 で保存され、次のような特徴があります:

  • JSON構造を解析済みで保存するため、検索や比較が高速
  • キーや値を個別に抽出しやすい
  • インデックス(特にGINインデックス)を使うと検索性能が向上

つまり、「JSONの柔軟性」と「DBらしい検索性能」の両方をある程度兼ね備えたデータ型です。


JSONBのメリット

  • スキーマ変更なしで新しいフィールドを追加できる
  • メタ情報や可変パラメータの保存に便利
  • GINインデックスを張れば検索もそこそこ速い

JSONBに頼りすぎると…

  • クエリが複雑化して読みづらい
  • 正規化されていないためJOINが難しい
  • 一部だけを集計するときにパフォーマンスが落ちる

JSONBの使いどころ

  • 可変的なデータ構造の保存
    例: 推論結果の詳細、リクエスト時の可変パラメータ
  • スキーマが頻繁に変わる情報
    例: モデルのメタ情報(ハイパーパラメータ、環境設定など)
  • ログやイベントの詳細
    共通の枠組みは正規化しておき、詳細はJSONBに入れることで柔軟性を確保
  • 検索頻度が低いが保持しておきたいデータ
    例: デバッグ用の詳細情報や、まれに使う属性

うまい使い分けの指針

  • 基本の軸は正規化テーブル
    • 例: inference_logs(id, created_at, user_id, model_id, result_jsonb)
  • 変化しやすい部分をJSONBに閉じ込める
    • resultの詳細やリクエストパラメータなど
  • 検索頻度の高いキーは正規化してカラム化する
    • 例: statuslatency_ms は専用カラムを持たせる

クエリ例(JSONBとカラムの併用)

-- 正規化したカラムでの高速検索
SELECT id, created_at, status
FROM inference_logs
WHERE status = 'success'
AND created_at >= now() - interval '1 day';

-- JSONB内の柔軟検索
SELECT id, result->>'score' AS score
FROM inference_logs
WHERE (result->>'model_version')::int = 3;

✅ 今日のまとめ

Aurora/PostgreSQLでは 「安定した軸は正規化、変化の激しい部分はJSONB」 が鉄則。
柔軟性とパフォーマンスのバランスを取ることが、長期運用に効いてきます。

投稿者 kojiro777

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です