边缘数据库:D1、R2、Vectorize 如何与 Hono 协同?
在边缘节点执行数据库查询
Cloudflare 的 D1(SQLite)、R2(对象存储)、Vectorize(向量数据库) 是专为边缘计算设计的数据库服务,它们与 Hono 框架深度集成,使得开发者能够在离用户最近的边缘节点上执行数据库操作,极大降低延迟,提升应用性能。
本文将深入探讨这三大边缘数据库如何与 Hono 协同工作,并展示如何在边缘节点直接执行数据库查询,构建真正“数据就近处理”的全栈边缘应用。
一、为什么边缘数据库至关重要?
| 传统架构 | 边缘架构 |
|---|---|
| 数据库集中于中心机房 | 数据库分布在全球边缘 |
| 请求需跨地域传输 | 数据在本地边缘节点处理 |
| 延迟高(100ms+) | 延迟极低(< 10ms) |
| 扩展成本高 | 自动扩展,按需计费 |
边缘数据库 + Hono = 数据处理不再“绕路”
二、Hono 与 Cloudflare 生态的完美契合
Hono 原生支持 Cloudflare Workers,并提供了对 D1、R2、Vectorize 的类型定义和中间件支持,使得在边缘操作数据库变得简单、类型安全。
Hono可直接注入env中的数据库绑定;- 支持 TypeScript 类型推断;
- 与
@cloudflare/workers-types无缝集成。
三、D1:边缘 SQLite 数据库
D1 是 Cloudflare 的边缘 SQLite 数据库,数据自动复制到全球多个边缘位置,支持标准 SQL 查询。
1. 绑定 D1 到 Worker
在 wrangler.toml 中配置:
toml
[[d1_databases]]
binding = "DB" # 用于代码中访问
database_name = "my-app-db"
database_id = "xxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"2. 在 Hono 中使用 D1
ts
// src/routes/users.ts
import { Hono } from 'hono'
type Env = {
DB: D1Database
}
const app = new Hono<{ Bindings: Env }>()
// 获取所有用户
app.get('/users', async (c) => {
const { results } = await c.env.DB.prepare(
'SELECT id, name, email FROM users LIMIT 20'
).all()
return c.json(results)
})
// 创建用户
app.post('/users', async (c) => {
const { name, email } = await c.req.json()
const { success } = await c.env.DB.prepare(
'INSERT INTO users (name, email) VALUES (?, ?)'
).bind(name, email).run()
if (success) {
return c.json({ success: true }, 201)
}
return c.json({ error: 'Failed' }, 500)
})
export default app优势
- SQL 查询在边缘执行,无需回源;
- 支持事务、索引、JOIN;
- 适合用户数据、配置、日志等结构化数据。
四、R2:边缘对象存储
R2 提供零 egress 费用的对象存储,非常适合存储大文件(图片、视频、备份),并与 Hono 结合实现文件上传/下载服务。
1. 绑定 R2
toml
[[r2_buckets]]
binding = "ASSETS"
bucket_name = "my-app-assets"2. 文件上传与下载
ts
// src/routes/storage.ts
import { Hono } from 'hono'
type Env = {
DB: D1Database
ASSETS: R2Bucket
}
const app = new Hono<{ Bindings: Env }>()
// 上传文件
app.post('/upload', async (c) => {
const form = await c.req.formData()
const file = form.get('file') as File
if (!file) return c.json({ error: 'No file' }, 400)
await c.env.ASSETS.put(file.name, file.stream(), {
httpMetadata: file,
customMetadata: { uploadedBy: 'user-123' }
})
return c.json({ key: file.name })
})
// 下载文件
app.get('/download/:key', async (c) => {
const key = c.req.param('key')
const object = await c.env.ASSETS.get(key)
if (!object) return c.notFound()
const headers = new Headers()
object.writeHttpMetadata(headers)
headers.set('etag', object.httpEtag)
return new Response(object.body, { headers })
})
export default app优势
- 文件上传/下载在边缘完成;
- 无出口带宽费用;
- 支持版本控制、生命周期管理。
五、Vectorize:边缘向量数据库
Vectorize 是 Cloudflare 的向量数据库,专为 AI 应用设计,支持在边缘执行向量相似度搜索(如语义搜索、推荐系统)。
1. 创建向量表
sql
-- 在 D1 中创建向量表(或使用 Vectorize UI)
CREATE TABLE documents (
id INTEGER PRIMARY KEY,
content TEXT,
embedding BLOB -- 存储向量
);目前 Vectorize 仍处于早期阶段,可结合 D1 + Hono 在边缘执行轻量级向量搜索。
2. 使用 Hono + D1 实现语义搜索
ts
// src/routes/search.ts
import { Hono } from 'hono'
import { embed } from '../lib/embedding' // 调用外部模型生成向量
type Env = {
DB: D1Database
}
const app = new Hono<{ Bindings: Env }>()
// 向量化并存储文档
app.post('/docs', async (c) => {
const { content } = await c.req.json()
const vector = await embed(content) // 如调用 BERT、OpenAI 等
await c.env.DB.prepare(
'INSERT INTO documents (content, embedding) VALUES (?, ?)'
).bind(content, JSON.stringify(vector)).run()
return c.json({ success: true })
})
// 语义搜索
app.get('/search', async (c) => {
const q = c.req.query('q')
const queryVector = await embed(q)
// 简化的余弦相似度查询(实际应使用专用向量数据库)
const results = await c.env.DB.prepare(
`SELECT content, embedding FROM documents LIMIT 10`
).all()
// 在边缘进行向量计算(适合小规模)
const matches = results.results.map(row => {
const vec = JSON.parse(row.embedding)
const score = cosineSimilarity(queryVector, vec)
return { content: row.content, score }
}).sort((a, b) => b.score - a.score).slice(0, 5)
return c.json(matches)
})
function cosineSimilarity(a: number[], b: number[]): number {
const dot = a.reduce((sum, _, i) => sum + a[i] * b[i], 0)
const magA = Math.sqrt(a.reduce((sum, val) => sum + val * val, 0))
const magB = Math.sqrt(b.reduce((sum, val) => sum + val * val, 0))
return dot / (magA * magB)
}优势
- 向量搜索在边缘执行,低延迟;
- 适合聊天机器人、推荐系统、语义搜索;
- 可结合外部模型(如 OpenAI)生成嵌入。
六、完整应用示例:边缘博客系统
ts
// src/index.ts
import { Hono } from 'hono'
type Env = {
DB: D1Database
ASSETS: R2Bucket
}
const app = new Hono<{ Bindings: Env }>()
// 静态资源
app.get('/images/*', (c) => {
const key = c.req.path.replace('/images/', '')
return c.env.ASSETS.get(key).then(res => res ? new Response(res.body) : c.notFound())
})
// 文章列表
app.get('/posts', async (c) => {
const { results } = await c.env.DB.prepare(
'SELECT id, title, excerpt FROM posts ORDER BY created DESC'
).all()
return c.json(results)
})
// 语义搜索文章
app.get('/search', async (c) => {
const q = c.req.query('q')
const vector = await generateEmbedding(q)
// ... 向量搜索逻辑
})
export default app七、性能对比:边缘 vs 中心化数据库
| 操作 | 中心化数据库 | 边缘数据库(D1/R2) |
|---|---|---|
| 读取用户数据 | 80-150ms | 5-20ms |
| 上传图片 | 500ms+ | 100-300ms(就近上传) |
| 语义搜索 | 500ms+(需回源) | 50-150ms(边缘计算) |
| 扩展性 | 手动分片 | 自动扩展 |
在亚洲用户访问美国数据库的场景下,边缘数据库可降低 80% 以上延迟。
八、最佳实践
| 实践 | 建议 |
|---|---|
| D1 用于结构化数据 | 用户、订单、配置等 |
| R2 用于大文件存储 | 图片、视频、备份 |
| Vectorize 用于 AI 搜索 | 结合外部模型生成嵌入 |
| Hono 中间件处理错误 | 统一处理数据库连接失败 |
| 本地开发使用 D1 CLI | wrangler d1 execute |
| 缓存热点数据 | 结合 Cache API 减少数据库压力 |
九、总结
| 数据库 | 用途 | Hono 集成方式 |
|---|---|---|
| D1 | 边缘 SQLite | c.env.DB.prepare(...).all() |
| R2 | 对象存储 | c.env.ASSETS.put/get() |
| Vectorize | 向量搜索 | 结合 D1 + 外部模型 |
| Cache | 边缘缓存 | c.caches.default |
Hono + D1 + R2 + Vectorize = 全栈边缘应用的终极组合。
你可以在同一个边缘函数中完成:
- HTTP 路由(Hono)
- 结构化数据查询(D1)
- 文件存储(R2)
- AI 语义搜索(Vectorize)
立即开始构建你的下一个低延迟、高扩展、智能化的边缘应用,让数据真正“触手可及”!