🗄️
ブログサイト構築 — Cloudflare D1 入門
Cloudflare エッジで動くサーバーレス SQLite、D1 の概要。KV との違い・Pages Functions からの利用方法・ブログへの応用例
Cloudflare D1 とは
Cloudflare が提供するサーバーレス SQLite データベース。 Workers / Pages Functions から SQL クエリを直接実行できる。
Pages Functions
└─ env.DB.prepare("SELECT * FROM posts WHERE id = ?")
└─ Cloudflare D1(SQLite)
KV との違い
| 特性 | Cloudflare KV | Cloudflare D1 |
|---|---|---|
| データモデル | Key-Value(文字列) | リレーショナル(SQL) |
| クエリ | get(key) / put(key, val) | SQL(SELECT / JOIN / 集計) |
| 整合性 | 結果整合性 | 強整合性(ローカルコピー) |
| 用途 | キャッシュ・カウンタ・設定 | 構造化データ・関係クエリ |
| 無料枠 | 読み 100k/日・書き 1k/日 | 5M 行読み/月・100k 行書き/月 |
KV の適用場面:
- 読み取りが圧倒的に多い(閲覧数カウントなど)
- 厳密な整合性が不要
D1 の適用場面:
- 構造化データ(ユーザー・コメント・タグなど)
- JOIN や集計クエリが必要
- トランザクションが必要
D1 のアーキテクチャ
D1 は SQLite を Cloudflare のエッジで動かす。 1 つのリージョンがプライマリとなり、読み取りはエッジにキャッシュされる。
Write → Primary (Cloudflare DC)
Read → エッジキャッシュ(数ミリ秒遅延の可能性)
KV のグローバル分散とは異なり、D1 は単一プライマリ + リードレプリカの構成。
基本的な使い方
1. データベース作成
wrangler d1 create my-blog-db
2. wrangler.toml にバインディング追加
[[d1_databases]]
binding = "DB"
database_name = "my-blog-db"
database_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
3. スキーマ作成
-- schema.sql
CREATE TABLE comments (
id INTEGER PRIMARY KEY AUTOINCREMENT,
post_id TEXT NOT NULL,
content TEXT NOT NULL,
author TEXT NOT NULL,
created TEXT NOT NULL DEFAULT (datetime('now'))
);
wrangler d1 execute my-blog-db --file=schema.sql
4. Pages Functions からクエリ
interface Env {
DB: D1Database;
}
export const onRequest: PagesFunction<Env> = async ({ env, params }) => {
const postId = params.slug as string;
const { results } = await env.DB.prepare(
'SELECT * FROM comments WHERE post_id = ? ORDER BY created DESC'
).bind(postId).all();
return Response.json(results);
};
ブログへの応用例
コメント機能
CREATE TABLE comments (
id INTEGER PRIMARY KEY AUTOINCREMENT,
post_id TEXT NOT NULL,
author TEXT NOT NULL,
content TEXT NOT NULL,
created TEXT NOT NULL DEFAULT (datetime('now'))
);
タグ集計
SELECT tag, COUNT(*) as count
FROM post_tags
GROUP BY tag
ORDER BY count DESC
LIMIT 20;
閲覧数(KV からの移行例)
CREATE TABLE views (
slug TEXT PRIMARY KEY,
count INTEGER NOT NULL DEFAULT 0
);
-- 閲覧時
INSERT INTO views (slug, count) VALUES (?, 1)
ON CONFLICT (slug) DO UPDATE SET count = count + 1;
KV より D1 の方が厳密なカウントが必要な場合に適している。 (KV は結果整合性のため、高頻度書き込みでカウントが失われる可能性がある)
本サイトでの位置づけ
現在の本サイトは閲覧数カウントに Cloudflare KV を使用している。 シンプルな用途には KV で十分だが、以下が必要になれば D1 への移行を検討する。
- コメント機能の追加
- タグ・シリーズの動的集計(ビルド時でなくランタイムで)
- 複数記事にまたがる統計クエリ
D1 の制限(2025年時点)
| 項目 | 制限 |
|---|---|
| データベースサイズ | 2GB(Workers Paid)/ 500MB(Free) |
| 行読み取り/月 | 25M(Paid)/ 5M(Free) |
| 行書き込み/月 | 50M(Paid)/ 100k(Free) |
| 同時接続 | Workers Isolates ごとに 1 接続 |
関連
- 1. 🏗️このサイトのアーキテクチャ
- 2. 🏗️ブログサイト構築 — 全体アーキテクチャ
- 3. 🚀ブログサイト構築 — Astro SSG と MPA 設計
- 4. ☁️ブログサイト構築 — Cloudflare ホスティング
- 5. 🖼️ブログサイト構築 — OGP 画像の自動生成
- 6. 🎨ブログサイト構築 — Satori で絵文字を描画する
- 7. 🗄️ブログサイト構築 — Cloudflare D1 入門