惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

阮一峰的网络日志
阮一峰的网络日志
Scott Helme
Scott Helme
P
Proofpoint News Feed
T
Threat Research - Cisco Blogs
C
CERT Recently Published Vulnerability Notes
P
Privacy & Cybersecurity Law Blog
云风的 BLOG
云风的 BLOG
V
Visual Studio Blog
Martin Fowler
Martin Fowler
Cisco Talos Blog
Cisco Talos Blog
罗磊的独立博客
MyScale Blog
MyScale Blog
博客园 - 【当耐特】
L
LangChain Blog
AWS News Blog
AWS News Blog
Security Latest
Security Latest
C
CXSECURITY Database RSS Feed - CXSecurity.com
P
Proofpoint News Feed
T
True Tiger Recordings
aimingoo的专栏
aimingoo的专栏
宝玉的分享
宝玉的分享
月光博客
月光博客
The Hacker News
The Hacker News
L
Lohrmann on Cybersecurity
The GitHub Blog
The GitHub Blog
Stack Overflow Blog
Stack Overflow Blog
S
SegmentFault 最新的问题
Recorded Future
Recorded Future
S
Security Archives - TechRepublic
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
WordPress大学
WordPress大学
Y
Y Combinator Blog
Recent Commits to openclaw:main
Recent Commits to openclaw:main
大猫的无限游戏
大猫的无限游戏
Apple Machine Learning Research
Apple Machine Learning Research
小众软件
小众软件
博客园 - 聂微东
GbyAI
GbyAI
N
News and Events Feed by Topic
The Cloudflare Blog
Engineering at Meta
Engineering at Meta
Last Week in AI
Last Week in AI
博客园 - 三生石上(FineUI控件)
G
Google Developers Blog
A
About on SuperTechFans
K
Kaspersky official blog
NISL@THU
NISL@THU
S
Securelist
Microsoft Azure Blog
Microsoft Azure Blog
V
V2EX - 技术

V2EX

做了个 Chrome 插件 DemoAlias,录 demo 时一键替换敏感数据 [Pixel] 想要入手个带一个 Sim 卡的 pixel10 在那块买更好 觉得现在入手合适吗 Mac pro M1 磁盘扩容问题 小米 mimo 模式是不是挂了,现在无应答了 Gemini 最近是降智了吗? 3.5 快是快但是回答的质量变差了 [程序员] 祝贺我司,月收入突破万刀~ [分享发现] [翻译] 为什么我要用 C# 构建数据库引擎 [分享创造] 使用 Skills 结合 NotebookLM 一人运营十个视频号 用 AI 如何做出好看的前端页面? 记一次令我非常无语的面试 [分享创造] GEO Wiki: 一个面向生成式引擎优化的百科全书 [分享发现] 哪位友友有滴滴 V8 [问与答] 有没有听力不太好,用苹果 air pod 的 [分享创造] Obsidian-Extensions-Activity 0.2 - 更好用的三方插件管理工具 《HelloGitHub》第 122 期 有没有阿里云的大佬,来说说这是真的,还是销售吹的? [Android] 看到 k80 可以解锁了 原来大型活动和人流量较多的地方有警察执勤并不是中国特色 [开源实时数字人] 商业级部署演示! 同时我们消费级卡的部署链路已经通啦,欢迎提意见~ [问与答] AI 搜索互联网资讯有啥好用的接口没? [副业] 跟风开了一个自助洗车店 [macOS] Mac 盖上盖子使用之后,每次开屏屏幕会花,这个是硬件问题还是驱动问题呢? 闪电藤即将下线,虾传正式上线 [DeepSeek] 今天 deepseek 崩了吗 codex 土区的 plus,能改成美区的 pro 吗,会触发手机验证吗 大家用过 Qwen3.7-Max 吗,说是比 GLM5.1, KIMI2.6 还强,真的假的? anthropic 既然如此抵触 cn,但是多国语言又提供简体中文? [程序员] 英语学了几十年,还是听不懂说不出,大家都是怎么练听说的? [问与答] 感觉有点 ai 阳痿了,话说你们都用 ai 做了啥 分享一个我做的 Apple Watch 独立游戏——30 秒打地鼠 [OpenAI] 有时候感觉言出法随比使用 superpowers 更方便快捷 [问与答] 有没有云南的?昆明彩礼一般多少啊? [生活] 我的无奈,我很想她,但是这不再可能 朋友用美国身份注册了 claude 账号,在国内使用会被封吗 [职场话题] 北京裁员赔偿上限是多少啊 [推广] 做了一个 AI 中转站 Lumi,新用户可免费订阅,每周送 2 元额度 17PM 7999 PDD、淘宝百亿补贴 [问与答] 我的 codex app 为什么这样? [分享创造] 无聊开发了一个蚊子白噪音助眠小程序,适合烦朋友 [程序员] Cursor 滞销了, 60 刀套餐回归玩家首月给 70% off [Wunder] edge.v2ex.com/chat 20260527 功能更新 [问与答] 寻找 image2,香蕉, seedance2 的 api; 取精室是怎么个流程?取不出来怎么办? opencode go 里的 mimov2.5 系列额度涨了 [酷工作] Crypto CEX 诚聘 AI 测试工程师 薪水 20K-30K RMB 纯远程办公 [生活] 你有给自己买什么商业保险吗,或者说有必要买商业保险吗 claude 发的这句话啥意思,说我问的多了吗 Quantumult X 又更新了 配置优化更新了一下 [问与答] 不知道是不是错觉, typeless 在 Macbook 上的耗电感觉有点快 老婆送了我个 iPhone17 Pro Max 1T,但我更舍不得我的 iPhone13 巨魔 福利: 4 个住宅 IP 兑换码,新用户专享 mac 笔记本 500G,开发用,现在没有储存空间了怎么办 是否存在港卡以外的其他选择?比如东南亚各国? DigVPS 测评 - 100TB 新增美国 Los Angeles - Global Tier1 产品:这应该是 Y 系第一个美国产品?限量九折优惠中。 [程序员] OpenCode x MiMo V2.5 - 限时免费 现在的你有哪些骄傲和无奈呢 香港金管局:就内地投资者投资账户新增三项监管措施 开户核查倒查至 2023 年 1 月 做了个 macOS 网站与应用拦截器, 保持专注. [小米] 有没有安卓玩机高手请教点问题 我发现 it 类工作者是最严重的性压抑群体 包括我自己 it 类的工作者 [开源] 高阶魔方一键求解器 Cursor 还能买吗, 20 刀和 60 刀的大概能用多久? ai studio 被疯狂封 api 怎么回事 Zerolang 好像还没人讨论? [问与答] token 用量究竟是怎么算的? 香港众安银行开户返 300HKD+50USD 英伟达股票兑换券 活动时间 5.28 日至 7.1 日截止。 vibe coding 了个辅助颈腰椎病康复的体态相机小工具 有在用免费 VPS 的吗?可以当梯子用吗? 这个 sechub 网站搬运了很多 V 站的内容,站方能管到它吗 我的 AI(LLM) 和 vibe coding 使用技巧已经落伍了吗 我做了一个 Agent Team 协作平台——Rudder:让 Agent Team 在实践中成长 react 这个技术栈到底是如何做到每天都有新发现的? 我终于找到了 24 小时进行 coding 的终极方法,你可以在帖子当中看到最佳的 Vibe coding 助手 我不想看你的产出 Anker 已经不是原来的 Anker 了,从苹果生态到饭圈生意,一路从龙头企业做到现在韭菜头子。 [产品发布] [产品自荐] 业余两周做了个 AI Visual Agent,自动选模型、写 prompt、调参数,想请 V 友帮忙看看 [深圳] 居家办公距离南山科兴地铁 50 分钟有推荐的小区吗 [推广] 📊 [抽奖+1] 多券商开户福利(万 0.854/两融低至 3.x),回帖抽 coding plan 欢迎各位分子 AirPods4 降噪版在地铁上的表现实在糟糕,关门声差点我把送走 [酷工作] 远程 AI 前端招聘 30-50K 活过来了,继续推广一下我的 codex 中转站,依旧免费送 30 刀 复杂内网里的 WebRTC + gRPC 音视频通话方案:信令、媒体链路与自恢复 寻找 App 平台规则与技术合规咨询顾问 / 团队 做了个宠物拍立得风格照片生成器,给你的猫狗来张照片吧 [问与答] 国内网盘,大家都试过有哪些好用的原生支持 webdav 的网盘? [酷工作] [Golang] 兼职/全职大量招聘|团队扩招—跨境电商 AI+SaaS 用多模态大模型来做语音输入,效果碾压 typeless [推广] [FK Claude] 满血 Claude 折扣中转站 最近 claude code 频繁卡死有碰到同样问题的吗 [问与答] 香港金管局:就内地投资者开户核查倒查至 2023 年 1 月。啥意思? 各位小微企业创业的大佬,欢迎联系我购买财务软件 麻将洗牌 40 张牌跟踪, YOLO+ByteTrack 累积 1942 ID, SAM 2 / Cutie / CoTracker3 哪个能救? [Claude] 跪求 Claude 使用高手 [分享发现] 小米开发者计划送了 820 亿 token + 240 亿 credits,有人用得完吗? 有需要的可以用我的 前几天看到有坛友有 NAS 托管需求 ,刚好我们这边可以放这个 和大家讨论讨论可行性 [OpenAI] 高考期间国产 AI 工具部分功能或将禁用 哪些兄弟有 token 渠道,采购需求! [酷工作] 阿里国际急招 Agent 开发,流程快,最核心的交易业务,速来 网站公安备案,安全评估大家是怎么处理的 vibe 了一个可视化 sing-box 配置编辑器
秒杀传统数据库! Cloudflare D1 + Drizzle 组合拳,高并发高可用,让我们的成本爆降 10 倍 - D1
leia · 2025-07-10 · via V2EX

秒杀传统数据库! Cloudflare D1 + Drizzle 组合拳,高并发高可用,让我们的成本爆降 10 倍 - D1

想象一下:我们的应用用户量稳步增长,​传统数据库的成本和维护压力也随之上升​。而在这个时代,有没有更高效、更经济的数据库解决方案?​Cloudflare D1 结合 Drizzle ORM 的组合​,正在为众多​出海应用开发提供一条全新的技术路径​。

传统数据库方案在高并发场景下往往需要复杂的扩容、分片和负载均衡,成本随着流量呈指数级增长。而当我们了解了 Cloudflare D1 这款​基于 SQLite 构建的边缘数据库​,再配合 Drizzle 这个轻量级 ORM 的强大能力,我们会惊讶于这个组合如何能在保持高性能的同时,​将我们的基础设施成本直接腰斩​!

无需复杂的数据库集群,无需昂贵的专用服务器,无需担心地理位置带来的延迟问题 — 这个方案将​彻底改变我们对数据库架构的认知​。

Cloudflare D1 实战:从零开始搭建高性能数据库

Cloudflare D1 是 Cloudflare 推出的一款分布式 SQL 数据库,它基于 SQLite 构建,完全集成在 Cloudflare Workers 生态系统中。D1 将 SQLite 数据库部署到 Cloudflare 的全球边缘网络,让我们的数据库与应用代码一样,运行在离用户最近的位置,大幅降低延迟。

D1 成本计算与对比

在深入技术细节前,让我们先来看看 D1 在成本方面的巨大优势。Cloudflare D1 采用了极具竞争力的定价模型:

资源类型 Workers Free (免费版) Workers Paid (付费版)
读取行数 每天 500 万行限制 每月前 250 亿行免费,超出部分 $0.001/百万行
写入行数 每天 10 万行限制 每月前 5000 万行免费,超出部分 $1.00/百万行
存储空间 总计 5GB 限制 前 5GB 免费,超出部分 $0.75/GB-月

让我们来分析一下免费版的套餐:

  • 读取成本​:每天 500 万行的读取量,一个月约 1.5 亿行,完全在免费额度内。即使你的应用流量翻倍,达到每天 1000 万行读取,每月 3 亿行,超出免费额度的 5000 万行只需要额外支付 $0.05/月。
  • 写入成本​:每天 10 万行的写入,一个月约 300 万行,远低于免费额度的 5000 万行。即使写入量增长 10 倍,仍然在免费额度内。
  • 存储成本​:5GB 的存储空间完全免费。对于大多数中小型应用来说,这已经足够存储数百万条记录

付费版的价格是 5$,免费版的规模足够处理 5000-20000 日活的应用,付费 20000-100w 日活。

快速上手 D1

1. 安装 Wrangler CLI

首先,我们需要安装 Cloudflare 的 Wrangler CLI 工具:

npm install -g wrangler

2. 创建 D1 数据库

登录我们的 Cloudflare 账户后,创建一个新的 D1 数据库:

wrangler login
wrangler d1 create my-database

执行后,我们会看到类似这样的输出:

✅ Successfully created DB 'my-database' in region APAC
Created D1 database 'my-database' with id: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx

请记下这个数据库 ID ,我们后续会用到。

3. 配置 wrangler.toml

在我们的项目根目录创建或编辑 wrangler.toml 文件,添加 D1 数据库配置:

[[d1_databases]]
binding = "DB" # 在 Workers 中使用的变量名
database_name = "my-database"
database_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" # 替换为我们的数据库 ID

4. 创建数据表

创建一个 SQL 文件,例如 schema.sql

CREATE TABLE users (
  id INTEGER PRIMARY KEY AUTOINCREMENT,
  name TEXT NOT NULL,
  email TEXT UNIQUE NOT NULL,
  created_at DATETIME DEFAULT CURRENT_TIMESTAMP
);

然后执行:

wrangler d1 execute my-database --file=./schema.sql

5. 在 Workers 中使用 D1

现在,我们可以在 Cloudflare Workers 中使用 D1 数据库了:

export interface Env {
  DB: D1Database
}

export default {
  async fetch(request: Request, env: Env): Promise<Response> {
    // 查询用户列表
    const { results } = await env.DB.prepare('SELECT * FROM users ORDER BY created_at DESC LIMIT 10').all()

    return new Response(JSON.stringify(results), {
      headers: { 'Content-Type': 'application/json' }
    })
  }
}

D1 的实用命令与简单实践

在实际开发中,我们需要更多的工具来管理数据库。D1 提供了一系列强大的命令行工具,让数据库管理变得轻松高效。 数据库迁移:管理我们的架构变更 数据库结构会随着需求不断变化。D1 提供了完善的迁移系统,让我们可以版本化管理数据库结构:

创建一个新的迁移文件
wrangler d1 migrations create my-database add_user_role

这会在项目中创建一个类似 migrations/0001_add_user_role.sql` 的文件。编辑这个文件,添加我们的 SQL 变更:

-- Migration: add_user_role
-- Created at: 2023-10-15 14:30:00

-- 向用户表添加角色字段
ALTER TABLE users ADD COLUMN role TEXT DEFAULT 'user' NOT NULL;

-- 创建一个新的角色权限表
CREATE TABLE role_permissions (
  role TEXT NOT NULL,
  permission TEXT NOT NULL,
  PRIMARY KEY (role, permission)
);

然后应用这些迁移:

应用到本地开发环境
wrangler d1 migrations apply my-database --local

应用到生产环境
wrangler d1 migrations apply my-database --remote

这种方式让我们可以: - 追踪数据库的所有变更历史 - 在团队中同步数据库结构 - 在不同环境(开发、测试、生产)之间保持一致性

数据导入导出:备份与恢复

需要备份数据或将数据迁移到其他环境? D1 提供了简单的导出导入功能

导出整个数据库(结构+数据)
wrangler d1 export my-database --output=backup.sql

只导出特定表
wrangler d1 export my-database --table=users --output=users_backup.sql

只导出结构,不导出数据
wrangler d1 export my-database --output=schema.sql --no-data

导入数据同样简单:

wrangler d1 execute my-database --file=backup.sql

实战案例:构建一个博客系统

让我们通过一个实际案例来展示 D1 的强大功能。假设我们要构建一个简单的博客系统,需要存储文章和评论。

首先,创建数据库结构:

-- migrations/0001_create_blog_tables.sql
CREATE TABLE posts (
  id INTEGER PRIMARY KEY AUTOINCREMENT,
  title TEXT NOT NULL,
  content TEXT NOT NULL,
  author_id INTEGER NOT NULL,
  published_at DATETIME DEFAULT CURRENT_TIMESTAMP,
  status TEXT DEFAULT 'draft' NOT NULL
);

CREATE TABLE comments (
  id INTEGER PRIMARY KEY AUTOINCREMENT,
  post_id INTEGER NOT NULL,
  author_name TEXT NOT NULL,
  content TEXT NOT NULL,
  created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
  FOREIGN KEY (post_id) REFERENCES posts(id) ON DELETE CASCADE
);

CREATE INDEX idx_posts_status ON posts(status);
CREATE INDEX idx_comments_post_id ON comments(post_id);

npx wrangler d1 execute prod-d1-tutorial --local --file=./migrations/0001_create_blog_tables.sql

然后,在 Workers 中实现 API 接口:

export interface Env {
  DB: D1Database
}

export default {
  async fetch(request: Request, env: Env): Promise<Response> {
    const url = new URL(request.url)
    const path = url.pathname

    // 获取博客文章列表
    if (path === '/api/posts' && request.method === 'GET') {
      const { results } = await env.DB.prepare(
        "SELECT id, title, published_at FROM posts WHERE status = 'published' ORDER BY published_at DESC LIMIT 10"
      ).all()

      return new Response(JSON.stringify(results), {
        headers: { 'Content-Type': 'application/json' }
      })
    }

    // 获取单篇文章及其评论
    if (path.match(/^\/api\/posts\/\d+$/) && request.method === 'GET') {
      const postId = path.split('/').pop()

      // 获取文章详情
      const post = await env.DB.prepare('SELECT * FROM posts WHERE id = ?').bind(postId).first()

      if (!post) {
        return new Response(JSON.stringify({ error: 'Post not found' }), {
          status: 404,
          headers: { 'Content-Type': 'application/json' }
        })
      }

      // 获取文章评论
      const { results: comments } = await env.DB.prepare(
        'SELECT * FROM comments WHERE post_id = ? ORDER BY created_at DESC'
      )
        .bind(postId)
        .all()

      return new Response(JSON.stringify({ post, comments }), {
        headers: { 'Content-Type': 'application/json' }
      })
    }

    // 添加评论
    if (path.match(/^\/api\/posts\/\d+\/comments$/) && request.method === 'POST') {
      const postId = path.split('/')[3]
      const { author_name, content } = await request.json()

      // 插入评论
      const result = await env.DB.prepare(
        'INSERT INTO comments (post_id, author_name, content) VALUES (?, ?, ?) RETURNING id'
      )
        .bind(postId, author_name, content)
        .run()

      return new Response(JSON.stringify({ id: result.results[0].id }), {
        status: 201,
        headers: { 'Content-Type': 'application/json' }
      })
    }

    return new Response('Not Found', { status: 404 })
  }
}

这个简单的博客 API 已经能够: - 获取已发布的文章列表 - 获取单篇文章及其评论 - 为文章添加新评论

本地开发与调试

在开发过程中,我们可以使用本地数据库进行测试:

启动本地开发服务器,使用本地 D1 数据库
wrangler dev --local

这会在本地创建一个 SQLite 数据库文件,我们可以在开发过程中使用它,而不需要每次都操作远程数据库。当我们的代码准备好后,再将变更应用到远程数据库。

应用迁移到远程数据库
wrangler d1 migrations apply my-database --remote

通过这种方式,我们可以在本地快速迭代开发,同时确保生产环境的数据安全。

结束

而在下一章节中,就讲解``Drizzle\,讲这个的主要目的是为了给大家普及一下`海外批量应用`的基础套件的知识 关于我