Skip to content

边缘数据库: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-150ms5-20ms
上传图片500ms+100-300ms(就近上传)
语义搜索500ms+(需回源)50-150ms(边缘计算)
扩展性手动分片自动扩展

在亚洲用户访问美国数据库的场景下,边缘数据库可降低 80% 以上延迟

八、最佳实践

实践建议
D1 用于结构化数据用户、订单、配置等
R2 用于大文件存储图片、视频、备份
Vectorize 用于 AI 搜索结合外部模型生成嵌入
Hono 中间件处理错误统一处理数据库连接失败
本地开发使用 D1 CLIwrangler d1 execute
缓存热点数据结合 Cache API 减少数据库压力

九、总结

数据库用途Hono 集成方式
D1边缘 SQLitec.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)

立即开始构建你的下一个低延迟、高扩展、智能化的边缘应用,让数据真正“触手可及”!