cloudflare-d1
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseCloudflare D1 Database
Cloudflare D1 Database
Status: Production Ready ✅ | Last Verified: 2025-01-15
状态:已就绪可用于生产 ✅ | 最后验证时间:2025-01-15
Table of Contents
目录
What Is D1?
什么是D1?
Cloudflare D1 is serverless SQLite on the edge:
- SQL database without servers
- Global distribution
- Zero cold starts
- Standard SQLite syntax
- Read replication for global performance
Cloudflare D1是边缘环境中的无服务器SQLite:
- 无需服务器的SQL数据库
- 全球分布式部署
- 无冷启动
- 标准SQLite语法
- 读取复制以实现全球性能优化
🆕 New in 2025
🆕 2025年新功能
D1 received major updates throughout 2025:
D1在2025年进行了重大更新:
Performance (January 2025)
性能优化(2025年1月)
- 40-60% latency reduction globally (P50 query times)
- Optimized SQLite engine for edge execution
- Reduced cold start impact for databases <100 MB
- 全球延迟降低40-60%(P50查询耗时)
- 针对边缘执行优化SQLite引擎
- 减小了小于100MB数据库的冷启动影响
Reliability (September 2025)
可靠性提升(2025年9月)
- Automatic query retries: Read queries retry up to 2x on transient failures
- Transparent to application code (logged in )
wrangler tail
- 自动查询重试:读取查询在临时故障时最多重试2次
- 对应用代码透明(日志记录在中)
wrangler tail
Scalability (April 2025)
可扩展性增强(2025年4月)
- Read Replication (Public Beta): Deploy read replicas globally
- Up to 2x read throughput for read-heavy workloads
- Sessions API for read-write separation
- 读取复制(公开测试版):在全球范围内部署读取副本
- 针对读密集型工作负载,读取吞吐量最高提升2倍
- 用于读写分离的Sessions API
Compliance (November 2025)
合规性支持(2025年11月)
- Data Localization: Specify EU/US jurisdiction for GDPR/data sovereignty
- Configure via flag or wrangler.jsonc
--jurisdiction
- 数据本地化:为GDPR/数据主权需求指定欧盟/美国管辖区域
- 通过标志或wrangler.jsonc配置
--jurisdiction
⚠️ Breaking Change (February 10, 2025)
⚠️ 破坏性变更(2025年2月10日)
- Free tier hard limits enforced: 10 DBs, 500 MB each, 50 queries/invocation
- Exceeding limits = 429 errors (previously warnings only)
- Action: Review usage with and upgrade if needed
wrangler d1 list
Full details: Load
references/2025-features.md- 免费层硬限制生效:10个数据库,每个500MB,每次调用50个查询
- 超出限制将返回429错误(此前仅为警告)
- 操作建议:使用查看使用情况,必要时升级
wrangler d1 list
详细内容:加载
references/2025-features.mdQuick Start (5 Minutes)
快速入门(5分钟)
1. Create Database
1. 创建数据库
bash
bunx wrangler d1 create my-databaseSave the from output!
database_idbash
bunx wrangler d1 create my-database保存输出中的!
database_id2. Configure Binding
2. 配置绑定
Add to :
wrangler.jsoncjsonc
{
"name": "my-worker",
"main": "src/index.ts",
"compatibility_date": "2025-10-11",
"d1_databases": [
{
"binding": "DB", // env.DB
"database_name": "my-database",
"database_id": "<UUID>",
"preview_database_id": "local-db"
}
]
}添加到:
wrangler.jsoncjsonc
{
"name": "my-worker",
"main": "src/index.ts",
"compatibility_date": "2025-10-11",
"d1_databases": [
{
"binding": "DB", // env.DB
"database_name": "my-database",
"database_id": "<UUID>",
"preview_database_id": "local-db"
}
]
}3. Create Migration
3. 创建迁移
bash
bunx wrangler d1 migrations create my-database create_usersEdit :
migrations/0001_create_users.sqlsql
CREATE TABLE IF NOT EXISTS users (
user_id INTEGER PRIMARY KEY AUTOINCREMENT,
email TEXT NOT NULL UNIQUE,
username TEXT NOT NULL,
created_at INTEGER NOT NULL
);
CREATE INDEX IF NOT EXISTS idx_users_email ON users(email);
PRAGMA optimize;bash
bunx wrangler d1 migrations create my-database create_users编辑:
migrations/0001_create_users.sqlsql
CREATE TABLE IF NOT EXISTS users (
user_id INTEGER PRIMARY KEY AUTOINCREMENT,
email TEXT NOT NULL UNIQUE,
username TEXT NOT NULL,
created_at INTEGER NOT NULL
);
CREATE INDEX IF NOT EXISTS idx_users_email ON users(email);
PRAGMA optimize;4. Apply Migration
4. 应用迁移
bash
undefinedbash
undefinedLocal
本地环境
bunx wrangler d1 migrations apply my-database --local
bunx wrangler d1 migrations apply my-database --local
Production
生产环境
bunx wrangler d1 migrations apply my-database --remote
undefinedbunx wrangler d1 migrations apply my-database --remote
undefined5. Query from Worker
5. 在Worker中查询
typescript
import { Hono } from 'hono';
type Bindings = {
DB: D1Database;
};
const app = new Hono<{ Bindings: Bindings }>();
app.get('/users/:email', async (c) => {
const { results } = await c.env.DB.prepare(
'SELECT * FROM users WHERE email = ?'
)
.bind(c.req.param('email'))
.all();
return c.json(results);
});
export default app;Load for complete walkthrough.
references/setup-guide.mdtypescript
import { Hono } from 'hono';
type Bindings = {
DB: D1Database;
};
const app = new Hono<{ Bindings: Bindings }>();
app.get('/users/:email', async (c) => {
const { results } = await c.env.DB.prepare(
'SELECT * FROM users WHERE email = ?'
)
.bind(c.req.param('email'))
.all();
return c.json(results);
});
export default app;完整入门指南:加载
references/setup-guide.mdCritical Rules
核心规则
Always Do ✅
必须遵循 ✅
- Use prepared statements with (never string concatenation)
.bind() - Create indexes for WHERE/JOIN/ORDER BY columns
- Use migrations for schema changes (never manual SQL)
- Batch queries for multiple operations (.batch())
- Run PRAGMA optimize after schema changes
- Handle errors explicitly (try/catch)
- Use INTEGER for timestamps (Date.now())
- Test locally before deploying migrations
- Use read replicas for global read performance
- Validate input before SQL queries
- 使用预编译语句配合(绝不要字符串拼接)
.bind() - 创建索引用于WHERE/JOIN/ORDER BY列
- 使用迁移进行 schema 变更(绝不要手动执行SQL)
- 批量处理查询以执行多个操作(.batch())
- 在schema变更后运行PRAGMA optimize
- 显式处理错误(try/catch)
- 使用INTEGER存储时间戳(Date.now())
- 在部署迁移前先在本地测试
- 使用读取副本提升全球读取性能
- 在SQL查询前验证输入
Never Do ❌
绝对禁止 ❌
- Never concatenate user input into SQL
- Never commit database_id to public repos
- Never skip migrations for schema changes
- Never use VARCHAR (use TEXT instead)
- Never skip indexes for filtered columns
- Never ignore SQLite type affinity rules
- **Never use SELECT *** without LIMIT
- Never run migrations without testing locally
- Never exceed 1MB per row
- Never use DATETIME (use INTEGER for timestamps)
- 绝不要拼接用户输入到SQL中
- 绝不要将database_id提交到公开代码仓库
- 绝不要跳过迁移进行schema变更
- 绝不要使用VARCHAR(改用TEXT)
- 绝不为过滤列跳过索引
- 绝不要忽略SQLite类型亲和性规则
- **绝不要在无LIMIT的情况下使用SELECT ***
- 绝不要在未本地测试的情况下运行迁移
- 绝不要让单行数据超过1MB
- 绝不要使用DATETIME(改用INTEGER存储时间戳)
D1 API Methods
D1 API 方法
prepare() - Execute Queries
prepare() - 执行查询
typescript
// Single result
const { results } = await env.DB.prepare(
'SELECT * FROM users WHERE email = ?'
)
.bind(email)
.all();
// First result only
const user = await env.DB.prepare(
'SELECT * FROM users WHERE user_id = ?'
)
.bind(userId)
.first();
// Raw results (faster)
const { results } = await env.DB.prepare(
'SELECT username FROM users'
)
.raw(); // Returns arrays instead of objectstypescript
// 单条结果
const { results } = await env.DB.prepare(
'SELECT * FROM users WHERE email = ?'
)
.bind(email)
.all();
// 仅第一条结果
const user = await env.DB.prepare(
'SELECT * FROM users WHERE user_id = ?'
)
.bind(userId)
.first();
// 原始结果(更快)
const { results } = await env.DB.prepare(
'SELECT username FROM users'
)
.raw(); // 返回数组而非对象batch() - Multiple Queries
batch() - 多查询批量处理
typescript
const results = await env.DB.batch([
env.DB.prepare('INSERT INTO users (email, username, created_at) VALUES (?, ?, ?)')
.bind('user1@example.com', 'user1', Date.now()),
env.DB.prepare('INSERT INTO users (email, username, created_at) VALUES (?, ?, ?)')
.bind('user2@example.com', 'user2', Date.now()),
env.DB.prepare('SELECT COUNT(*) as count FROM users')
]);
console.log('Users count:', results[2].results[0].count);All queries execute in single transaction (all succeed or all fail).
typescript
const results = await env.DB.batch([
env.DB.prepare('INSERT INTO users (email, username, created_at) VALUES (?, ?, ?)')
.bind('user1@example.com', 'user1', Date.now()),
env.DB.prepare('INSERT INTO users (email, username, created_at) VALUES (?, ?, ?)')
.bind('user2@example.com', 'user2', Date.now()),
env.DB.prepare('SELECT COUNT(*) as count FROM users')
]);
console.log('用户总数:', results[2].results[0].count);所有查询在单个事务中执行(要么全部成功,要么全部失败)。
exec() - Run SQL String
exec() - 运行SQL字符串
typescript
// For migrations/setup only
await env.DB.exec(`
CREATE TABLE IF NOT EXISTS users (
user_id INTEGER PRIMARY KEY,
email TEXT NOT NULL
);
CREATE INDEX idx_email ON users(email);
`);NEVER use for queries with user input!
Load for complete API reference.
references/query-patterns.mdtypescript
// 仅用于迁移/初始化
await env.DB.exec(`
CREATE TABLE IF NOT EXISTS users (
user_id INTEGER PRIMARY KEY,
email TEXT NOT NULL
);
CREATE INDEX idx_email ON users(email);
`);绝不要用于包含用户输入的查询!
完整API参考:加载
references/query-patterns.mdTop 5 Use Cases
Top 5 使用场景
Use Case 1: User CRUD
场景1:用户CRUD操作
typescript
// Create
app.post('/users', async (c) => {
const { email, username } = await c.req.json();
const { results } = await c.env.DB.prepare(
'INSERT INTO users (email, username, created_at) VALUES (?, ?, ?) RETURNING *'
)
.bind(email, username, Date.now())
.all();
return c.json(results[0]);
});
// Read
app.get('/users/:id', async (c) => {
const user = await c.env.DB.prepare(
'SELECT * FROM users WHERE user_id = ?'
)
.bind(c.req.param('id'))
.first();
if (!user) {
return c.json({ error: 'Not found' }, 404);
}
return c.json(user);
});
// Update
app.patch('/users/:id', async (c) => {
const { username } = await c.req.json();
await c.env.DB.prepare(
'UPDATE users SET username = ?, updated_at = ? WHERE user_id = ?'
)
.bind(username, Date.now(), c.req.param('id'))
.run();
return c.json({ success: true });
});
// Delete
app.delete('/users/:id', async (c) => {
await c.env.DB.prepare(
'DELETE FROM users WHERE user_id = ?'
)
.bind(c.req.param('id'))
.run();
return c.json({ success: true });
});typescript
// 创建
app.post('/users', async (c) => {
const { email, username } = await c.req.json();
const { results } = await c.env.DB.prepare(
'INSERT INTO users (email, username, created_at) VALUES (?, ?, ?) RETURNING *'
)
.bind(email, username, Date.now())
.all();
return c.json(results[0]);
});
// 读取
app.get('/users/:id', async (c) => {
const user = await c.env.DB.prepare(
'SELECT * FROM users WHERE user_id = ?'
)
.bind(c.req.param('id'))
.first();
if (!user) {
return c.json({ error: '未找到' }, 404);
}
return c.json(user);
});
// 更新
app.patch('/users/:id', async (c) => {
const { username } = await c.req.json();
await c.env.DB.prepare(
'UPDATE users SET username = ?, updated_at = ? WHERE user_id = ?'
)
.bind(username, Date.now(), c.req.param('id'))
.run();
return c.json({ success: true });
});
// 删除
app.delete('/users/:id', async (c) => {
await c.env.DB.prepare(
'DELETE FROM users WHERE user_id = ?'
)
.bind(c.req.param('id'))
.run();
return c.json({ success: true });
});Use Case 2: Batch Operations
场景2:批量操作
typescript
app.post('/users/bulk', async (c) => {
const users = await c.req.json(); // Array of users
const statements = users.map(user =>
c.env.DB.prepare(
'INSERT INTO users (email, username, created_at) VALUES (?, ?, ?)'
).bind(user.email, user.username, Date.now())
);
const results = await c.env.DB.batch(statements);
return c.json({ inserted: results.length });
});typescript
app.post('/users/bulk', async (c) => {
const users = await c.req.json(); // 用户数组
const statements = users.map(user =>
c.env.DB.prepare(
'INSERT INTO users (email, username, created_at) VALUES (?, ?, ?)'
).bind(user.email, user.username, Date.now())
);
const results = await c.env.DB.batch(statements);
return c.json({ inserted: results.length });
});Use Case 3: Read Replication (Global Reads)
场景3:读取复制(全球读取)
typescript
// Configure read replica (any region)
const session = c.env.DB.withSession({
preferredRegion: 'auto' // or 'weur', 'wnam', 'enam', 'apac'
});
// Read from nearest replica
const { results } = await session.prepare(
'SELECT * FROM users WHERE email = ?'
)
.bind(email)
.all();
// Check which region served request
console.log('Served by:', results[0].served_by_region);Load for complete guide.
references/read-replication.mdtypescript
// 配置读取副本(任意区域)
const session = c.env.DB.withSession({
preferredRegion: 'auto' // 或 'weur', 'wnam', 'enam', 'apac'
});
// 从最近的副本读取
const { results } = await session.prepare(
'SELECT * FROM users WHERE email = ?'
)
.bind(email)
.all();
// 查看请求由哪个区域提供服务
console.log('服务区域:', results[0].served_by_region);完整指南:加载
references/read-replication.mdUse Case 4: Transactions with Batch
场景4:事务与批量处理
typescript
// Transfer credits between users (atomic)
const results = await c.env.DB.batch([
c.env.DB.prepare(
'UPDATE users SET credits = credits - ? WHERE user_id = ?'
).bind(amount, fromUserId),
c.env.DB.prepare(
'UPDATE users SET credits = credits + ? WHERE user_id = ?'
).bind(amount, toUserId),
c.env.DB.prepare(
'INSERT INTO transactions (from_user, to_user, amount, created_at) VALUES (?, ?, ?, ?)'
).bind(fromUserId, toUserId, amount, Date.now())
]);
// All succeed or all fail (transaction)typescript
// 用户间积分转账(原子操作)
const results = await c.env.DB.batch([
c.env.DB.prepare(
'UPDATE users SET credits = credits - ? WHERE user_id = ?'
).bind(amount, fromUserId),
c.env.DB.prepare(
'UPDATE users SET credits = credits + ? WHERE user_id = ?'
).bind(amount, toUserId),
c.env.DB.prepare(
'INSERT INTO transactions (from_user, to_user, amount, created_at) VALUES (?, ?, ?, ?)'
).bind(fromUserId, toUserId, amount, Date.now())
]);
// 要么全部成功,要么全部失败(事务特性)Use Case 5: Pagination
场景5:分页
typescript
app.get('/users', async (c) => {
const page = parseInt(c.req.query('page') || '1');
const limit = 20;
const offset = (page - 1) * limit;
const { results } = await c.env.DB.prepare(
'SELECT * FROM users ORDER BY created_at DESC LIMIT ? OFFSET ?'
)
.bind(limit, offset)
.all();
return c.json({
users: results,
page,
limit
});
});typescript
app.get('/users', async (c) => {
const page = parseInt(c.req.query('page') || '1');
const limit = 20;
const offset = (page - 1) * limit;
const { results } = await c.env.DB.prepare(
'SELECT * FROM users ORDER BY created_at DESC LIMIT ? OFFSET ?'
)
.bind(limit, offset)
.all();
return c.json({
users: results,
page,
limit
});
});Migrations Best Practices
迁移最佳实践
1. Always Use Migrations
1. 始终使用迁移
bash
bunx wrangler d1 migrations create my-database add_users_avatarbash
bunx wrangler d1 migrations create my-database add_users_avatar2. Make Migrations Idempotent
2. 确保迁移具有幂等性
sql
-- ✅ GOOD: Idempotent
CREATE TABLE IF NOT EXISTS users (...);
CREATE INDEX IF NOT EXISTS idx_email ON users(email);
DROP TABLE IF EXISTS old_table;
-- ❌ BAD: Fails on re-run
CREATE TABLE users (...);
CREATE INDEX idx_email ON users(email);sql
-- ✅ 推荐:幂等性语句
CREATE TABLE IF NOT EXISTS users (...);
CREATE INDEX IF NOT EXISTS idx_email ON users(email);
DROP TABLE IF EXISTS old_table;
-- ❌ 不推荐:重复执行会失败
CREATE TABLE users (...);
CREATE INDEX idx_email ON users(email);3. Test Locally First
3. 先在本地测试
bash
bunx wrangler d1 migrations apply my-database --local
bunx wrangler d1 execute my-database --local --command "SELECT * FROM users"bash
bunx wrangler d1 migrations apply my-database --local
bunx wrangler d1 execute my-database --local --command "SELECT * FROM users"4. Add PRAGMA optimize
4. 添加PRAGMA optimize
sql
-- End of migration
PRAGMA optimize;Load for complete schema template.
templates/schema-example.sqlsql
-- 迁移末尾添加
PRAGMA optimize;完整schema模板:加载
templates/schema-example.sqlWhen to Load References
何时加载参考文档
Load references/setup-guide.md
when:
references/setup-guide.md加载references/setup-guide.md
的场景:
references/setup-guide.md- First-time D1 setup
- Creating first database
- Configuring bindings
- Applying first migration
- 首次设置D1
- 创建第一个数据库
- 配置绑定
- 应用第一个迁移
Load references/query-patterns.md
when:
references/query-patterns.md加载references/query-patterns.md
的场景:
references/query-patterns.md- Need complete API reference
- Complex query patterns
- Batch operations
- Error handling
- 需要完整API参考
- 复杂查询模式
- 批量操作
- 错误处理
Load references/read-replication.md
when:
references/read-replication.md加载references/read-replication.md
的场景:
references/read-replication.md- Setting up global reads
- Need low latency worldwide
- Understanding Sessions API
- Sequential consistency required
- 设置全球读取
- 需要全球低延迟
- 理解Sessions API
- 需要顺序一致性
Load references/best-practices.md
when:
references/best-practices.md加载references/best-practices.md
的场景:
references/best-practices.md- Optimizing query performance
- Schema design decisions
- Index strategies
- Production deployment checklist
- 优化查询性能
- schema设计决策
- 索引策略
- 生产部署检查清单
Load references/limits.md
when:
references/limits.md加载references/limits.md
的场景:
references/limits.md- Encountering 429 errors or quota warnings
- Planning capacity for free vs paid tiers
- Understanding database/query limits
- Migrating to paid plan
- 遇到429错误或配额警告
- 规划免费版与付费版的容量
- 了解数据库/查询限制
- 迁移到付费计划
Load references/metrics-analytics.md
when:
references/metrics-analytics.md加载references/metrics-analytics.md
的场景:
references/metrics-analytics.md- Investigating performance issues
- Setting up monitoring and alerts
- Using command
wrangler d1 insights - Analyzing query efficiency
- 排查性能问题
- 设置监控与告警
- 使用命令
wrangler d1 insights - 分析查询效率
Load references/2025-features.md
when:
references/2025-features.md交互式工具
- Upgrading from v2.x to v3.x
- Enabling new features (auto-retry, jurisdiction, replication)
- Understanding breaking changes (Feb 10, 2025 enforcement)
- Migrating before deadlines
智能代理(自主诊断):
- :9阶段诊断(配置、迁移、查询、绑定、错误、限制、性能、时光回溯)
agents/d1-debugger.md - :性能分析(慢查询、缺失索引、优化建议)
agents/d1-query-optimizer.md
命令工具(交互式向导):
- :交互式首次设置向导
commands/cloudflare-d1:setup.md - :带验证的迁移创建向导
commands/d1-create-migration.md
Interactive Tools
使用捆绑资源
—
参考文档(references/)
Agents (Autonomous diagnostics):
- : 9-phase diagnostic (config, migrations, queries, bindings, errors, limits, performance, Time Travel)
agents/d1-debugger.md - : Performance analysis (slow queries, missing indexes, optimization recommendations)
agents/d1-query-optimizer.md
Commands (Interactive wizards):
- : Interactive first-time setup wizard
commands/cloudflare-d1:setup.md - : Guided migration creation with validation
commands/d1-create-migration.md
- setup-guide.md - 完整设置指南
- query-patterns.md - 带示例的完整API参考
- read-replication.md - 全球读取副本设置指南
- best-practices.md - 性能与优化建议
Using Bundled Resources
模板(templates/)
References (references/)
—
- setup-guide.md - Complete setup walkthrough
- query-patterns.md - Complete API reference with examples
- read-replication.md - Global read replicas setup
- best-practices.md - Performance and optimization
- schema-example.sql - 带索引的完整schema
- d1-worker-queries.ts - Worker中的所有查询模式
- cloudflare-d1:setup-migration.sh - 完整设置脚本
Templates (templates/)
常见模式
—
错误处理
- schema-example.sql - Complete schema with indexes
- d1-worker-queries.ts - All query patterns in Workers
- cloudflare-d1:setup-migration.sh - Complete setup script
typescript
try {
const { results } = await env.DB.prepare(
'SELECT * FROM users WHERE email = ?'
)
.bind(email)
.all();
return c.json(results);
} catch (error) {
console.error('D1错误:', error);
return c.json({ error: '数据库错误' }, 500);
}Common Patterns
原始模式(性能优化)
Error Handling
—
typescript
try {
const { results } = await env.DB.prepare(
'SELECT * FROM users WHERE email = ?'
)
.bind(email)
.all();
return c.json(results);
} catch (error) {
console.error('D1 Error:', error);
return c.json({ error: 'Database error' }, 500);
}typescript
// 返回数组而非对象(更快)
const { results } = await env.DB.prepare(
'SELECT user_id, email FROM users'
)
.raw();
// results = [[1, 'user1@example.com'], [2, 'user2@example.com']]Raw Mode (Performance)
COUNT查询
typescript
// Returns arrays instead of objects (faster)
const { results } = await env.DB.prepare(
'SELECT user_id, email FROM users'
)
.raw();
// results = [[1, 'user1@example.com'], [2, 'user2@example.com']]typescript
const count = await env.DB.prepare(
'SELECT COUNT(*) as count FROM users'
)
.first('count'); // 获取单列值
console.log('用户总数:', count);COUNT Queries
SQLite 类型亲和性
typescript
const count = await env.DB.prepare(
'SELECT COUNT(*) as count FROM users'
)
.first('count'); // Get single column value
console.log('Total users:', count);D1使用SQLite类型亲和性:
| 声明类型 | 亲和性 |
|---|---|
| INTEGER, INT | INTEGER |
| TEXT, VARCHAR, CHAR | TEXT |
| REAL, FLOAT, DOUBLE | REAL |
| BLOB | BLOB |
| (无类型) | BLOB |
最佳实践:
- 使用存储数字
INTEGER - 使用存储字符串(而非VARCHAR)
TEXT - 使用存储时间戳(Date.now())
INTEGER - 使用存储二进制数据
BLOB
SQLite Type Affinity
Top 5 可预防错误
D1 uses SQLite type affinity:
| Declared Type | Affinity |
|---|---|
| INTEGER, INT | INTEGER |
| TEXT, VARCHAR, CHAR | TEXT |
| REAL, FLOAT, DOUBLE | REAL |
| BLOB | BLOB |
| (no type) | BLOB |
Best practices:
- Use for numbers
INTEGER - Use for strings (not VARCHAR)
TEXT - Use for timestamps (Date.now())
INTEGER - Use for binary data
BLOB
- SQL注入:使用,绝不要字符串拼接
.bind() - 缺失索引:为WHERE/JOIN列创建索引
- 迁移失败:先在本地测试
- 类型混淆:使用INTEGER存储时间戳
- 批量大小超限:限制批量语句数量在500以内
完整错误预防指南:加载
references/best-practices.mdTop 5 Errors Prevented
官方文档
- SQL Injection: Use , never string concatenation
.bind() - Missing Indexes: Create indexes for WHERE/JOIN columns
- Migration Failures: Test locally first
- Type Confusion: Use INTEGER for timestamps
- Batch Size: Limit batch to <500 statements
Load for complete error prevention.
references/best-practices.md- D1概述:https://developers.cloudflare.com/d1/
- 快速入门:https://developers.cloudflare.com/d1/get-started/
- 客户端API:https://developers.cloudflare.com/d1/build-with-d1/d1-client-api/
- 读取复制:https://developers.cloudflare.com/d1/reference/read-replication/
有疑问?遇到问题?
- 查看解决设置问题
references/setup-guide.md - 查阅获取API参考
references/query-patterns.md - 参考了解全球读取
references/read-replication.md - 加载获取优化建议
references/best-practices.md
Official Documentation
—
- D1 Overview: https://developers.cloudflare.com/d1/
- Get Started: https://developers.cloudflare.com/d1/get-started/
- Client API: https://developers.cloudflare.com/d1/build-with-d1/d1-client-api/
- Read Replication: https://developers.cloudflare.com/d1/reference/read-replication/
Questions? Issues?
- Check for setup
references/setup-guide.md - Review for API reference
references/query-patterns.md - See for global reads
references/read-replication.md - Load for optimization
references/best-practices.md
—