KV・R2・D1の使い分け——業務システムでどのストレージを選ぶか

Cloudflareには用途の異なる複数のストレージサービスがあり、業務システムを設計する際に「どれをどこで使うか」を最初に決めておく必要があります。Alcogyでは主にKV・R2・D1の3つを組み合わせて使っており、それぞれの判断基準を整理します。

D1: 構造化データとトランザクションの中心

受発注情報や顧客マスタ、活動履歴といった、整合性が求められる構造化データはD1に置きます。SQLベースでリレーションを組め、トランザクションも扱えるため、業務システムの中核データは基本的にD1一択です。MidletonやKilbeggan(Alcogyが開発しているCRM/SFA・活動履歴マネージャーのプロダクト)でも、顧客情報や活動記録はD1に格納しています。

KV: 低頻度更新・高頻度読み取りの設定値やキャッシュ

KVは結果整合性のキーバリューストアで、書き込みはやや遅く、同一キーへの高頻度書き込みには向きません。一方で読み取りは非常に高速なため、Alcogyではアプリケーションの設定値、フィーチャーフラグ、外部APIレスポンスのキャッシュといった「頻繁に読むが滅多に書かない」データに使っています。

// 外部APIレスポンスをKVでキャッシュする例
async function getExchangeRate(platform: App.Platform, base: string) {
  const cacheKey = `rate:${base}`;
  const cached = await platform.env.CACHE_KV.get(cacheKey, 'json');
  if (cached) return cached;

  const res = await fetch(`https://api.example.com/rates/${base}`);
  const data = await res.json();

  // 1時間キャッシュ
  await platform.env.CACHE_KV.put(cacheKey, JSON.stringify(data), {
    expirationTtl: 3600,
  });
  return data;
}

セッション管理にKVを使うケースもよく見かけますが、Alcogyでは即時の整合性が求められる認証系のデータは、結果整合性の遅延が問題になりうるためD1側で持つようにしています。

R2: ファイル・添付ファイルの置き場

見積書PDFや現場写真、契約書のスキャンデータといったバイナリファイルはR2に置きます。R2はS3互換のオブジェクトストレージで、エグレス(送信)が無料な点がCloudflareを選ぶ大きな理由になっています。業務システムでは添付ファイルのダウンロードが頻発するため、この特性は運用コストに直結します。

// 添付ファイルのアップロード
export const POST: RequestHandler = async ({ request, platform, params }) => {
  const file = await request.blob();
  const key = `orders/${params.orderId}/${crypto.randomUUID()}.pdf`;

  await platform!.env.ASSETS_BUCKET.put(key, file, {
    httpMetadata: { contentType: 'application/pdf' },
  });

  // D1側にはファイルのメタデータ(キー・ファイル名・アップロード者)のみ保存する
  await platform!.env.DB.prepare(
    'INSERT INTO attachments (order_id, r2_key, filename) VALUES (?, ?, ?)'
  ).bind(params.orderId, key, 'estimate.pdf').run();

  return new Response(null, { status: 201 });
};

ここで意識しているのは、R2にはファイル実体だけを置き、検索・一覧表示に使うメタデータはD1に持たせるという役割分担です。R2は主キー的な取得は速いものの、複雑な条件での検索には向いていないため、D1側にインデックスを持たせておくことで一覧画面のパフォーマンスを確保できます。

判断基準のまとめ

Alcogyでは新しいデータを設計するとき、「整合性が必要か」「読み書きの頻度比」「バイナリかどうか」の3点で置き場所を判断しています。整合性が必要な構造化データはD1、読み取り中心の軽量な値はKV、バイナリファイルはR2、という原則を最初に決めておくことで、後から「どこに何を置いたか分からなくなる」事態を防げます。業務システムは扱うデータの種類が多岐にわたるからこそ、ストレージ選定の一貫したルールを早い段階で持っておくことが重要だと考えています。