D1 数据库与 Hyperdrive

Cloudflare D1 / Hyperdrive

给边缘应用配的轻量 SQL 数据库;Hyperdrive 则负责让你的应用快速连上已有的传统数据库。

存储与数据出现时间 · 2022 年前后D1 免费额度含每天 500 万次读取;超出按行读写计费,Hyperdrive 按查询量分档。SQLiteServerless 数据库连接池边缘
看官方文档

01 它是干嘛的

D1 基于 SQLite,是给 Workers 配套的「开箱即用」关系型数据库,适合中小规模数据与边缘应用。Hyperdrive 解决另一个问题:传统数据库(PostgreSQL、MySQL)分布在一个区域,边缘函数每次连接都要跨洋握手,Hyperdrive 通过全球连接池把这份延迟抹平。

02 为什么会有它

Serverless 的一个隐藏难题:数据库连不上、连得慢

把应用搬到边缘之后,人们发现一个问题:计算可以全球分布,数据库却还在某个区域。边缘函数每个请求都新建一次数据库连接,要经历 TCP 握手、TLS 握手、身份认证,跨洋一次就是几十到上百毫秒;而传统数据库的连接数还有上限,边缘节点越多、并发越高,越容易把数据库连接数打满。

另一个方向是把数据库也分布出去,但关系型数据库的分片与一致性极难做对,大多数团队没有能力维护。

D1 的思路是面向边缘场景提供一个「够用的关系型数据库」:数据最终一致地在全球复制,读取就近、写入集中,适合配置、博客文章、用户轻量数据这类规模。Hyperdrive 则走务实路线——不改变你的数据库,只是在边缘与数据库之间放一个全球连接池与查询缓存,把重复的握手和查询消掉。

03 它怎么工作

D1 通过在全球边缘缓存只读副本实现就近查询;Hyperdrive 则在每个边缘节点维持到中心数据库的长期连接池,把「每请求一次握手」变成「复用现有连接」。

托管数据库:写只有一个方向,读可以分散① 写请求 → 主库② 读请求 → 副本③ 主从复制数据同步有毫秒级延迟定时快照你的应用连接池复用连接代理避免每次重新握手主库唯一的写入点只读副本 1承担查询压力只读副本 2就近读取自动备份时间点恢复刚写完立刻去副本读,可能读到旧数据——这叫「主从延迟」,强一致场景要回主库读。唯一写入点副本 / 备份
这张图同时画出主从复制的流向:写入只有一个方向(到主库),读取可以分发到多个副本,这正是「读多写少」业务的通用优化模式。

边缘应用查数据库:D1 的就近读取与 Hyperdrive 的连接复用

  1. 1
    ① 应用发起查询

    Workers 中调用 env.DB.prepare(...).all(),请求在本地边缘节点被处理。

  2. 2
    ② 判断读或写

    D1 是读取就近、写入集中:读走本地副本,写回主库并由主库同步到各副本,因此有明显写入延迟。

  3. 3
    ③ Hyperdrive 复用连接

    若后端是传统 PostgreSQL/MySQL,Hyperdrive 直接复用已建立的连接,跳过握手与认证。

  4. 4
    ④ 查询结果缓存

    对重复度高的只读查询,Hyperdrive 可缓存结果,进一步减少数据库压力。

  5. 5
    ⑤ 返回数据并保持一致性预期

    应用需要接受「写入后短时间读到旧值」的最终一致模型,必要时做读己之写处理。

04 谁在用它

边缘小型应用

博客、待办清单、表单收集、短链等应用,D1 加 Workers 即可构成完整后端。

给现有应用加速数据库访问

应用部署在边缘但数据库在中心,用 Hyperdrive 消除重复连接开销。

读多写少的配置与内容表

多语言文案、功能开关、目录数据等,读取就近、更新不频繁。

原型与教学项目

无需购买数据库实例、无需配置网络白名单,极大降低起步成本。

05 怎么用

命令行即可完成建库、建表与查询,几乎零运维。

  1. 01创建数据库:wrangler d1 create my-db,记下输出的 database_id。
  2. 02在 wrangler 配置中绑定 DB,本地开发时数据存在 .wrangler 目录里。
  3. 03建表:wrangler d1 execute my-db --file=./schema.sql。
  4. 04在代码里用 prepared statement 查询,务必使用参数绑定防止注入。
  5. 05发布时执行远程建表:wrangler d1 execute my-db --remote --file=./schema.sql。
  6. 06若用于既有数据库加速,创建 Hyperdrive 配置并把连接串交给它托管。
建表与查询示例sql
-- schema.sql:建一张文章表
CREATE TABLE IF NOT EXISTS articles (
  id         INTEGER PRIMARY KEY AUTOINCREMENT,
  title      TEXT NOT NULL,
  content    TEXT NOT NULL,
  created_at DATETIME DEFAULT CURRENT_TIMESTAMP
);
CREATE INDEX IF NOT EXISTS idx_articles_created ON articles(created_at DESC);

-- 查询(务必使用参数绑定,避免 SQL 注入)
-- const { results } = await env.DB
--   .prepare('SELECT id, title FROM articles ORDER BY created_at DESC LIMIT ?')
--   .bind(20)
--   .all()

避坑提示

  • !D1 是最终一致:刚写入的数据在其他地区可能几秒内读不到,涉及余额、库存等强一致场景不要用。
  • !SQLite 的并发写入能力有限,高并发写场景应选择传统关系型数据库或分布式数据库。
  • !数据库不存在「本地即生产」,发布前一定要记得对远程库执行建表语句。

06 关键概念

最终一致
写入后各地副本需要一点时间同步,暂时读到旧值属正常现象。
连接池
预先保持一批已建立的数据库连接重复使用,避免每次请求都握手。
参数绑定
用占位符传值而不是拼接字符串,是防 SQL 注入的根本手段。
副本(Replica)
主库数据的拷贝,只读,用于分担查询压力与就近访问。

07 容易混淆的对比

Supabase / Neon(PostgreSQL 系)功能更完整(事务、扩展丰富),适合需要复杂查询与强一致的项目。
Turso(分布式 SQLite)同样基于 SQLite,主打多区域复制,定位与 D1 相近。
图软件图鉴

纯静态站点,无后端、无追踪。内容为中文原创撰写,用于帮助非技术读者理解主流软件产品。

关于本站

全部内容在构建时生成
产品名称与商标归各自公司所有

© 2026 软件图鉴Nuxt 4 · Vue 3 · Tailwind 4 · 纯静态