V2EX 07月10日 19:06
[分享发现] 秒杀传统数据库! Cloudflare D1 + Drizzle 组合拳,高并发高可用,让我们的成本爆降 10 倍 - D1
index_new5.html
../../../zaker_core/zaker_tpl_static/wap/tpl_guoji1.html

 

文章介绍了Cloudflare D1和Drizzle ORM的组合,为出海应用提供了一种高效、经济的数据库解决方案。该方案基于SQLite构建,部署在Cloudflare的全球边缘网络,降低延迟,并显著降低基础设施成本。文章详细介绍了D1的成本优势、快速上手方法、实用命令以及在博客系统构建中的实战案例,帮助开发者快速搭建高性能数据库。

🚀 Cloudflare D1 是一个基于 SQLite 构建的分布式 SQL 数据库,它与 Cloudflare Workers 生态系统完全集成,将数据库部署到 Cloudflare 的全球边缘网络,从而降低延迟。

💰 D1 提供了极具竞争力的定价模型,免费版套餐足以满足大多数中小型应用的需求,包括每月 1.5 亿次的读取请求、300 万次的写入请求和 5GB 的存储空间。

🛠️ 通过 Wrangler CLI,可以轻松创建 D1 数据库、配置 wrangler.toml 文件、创建数据表以及在 Cloudflare Workers 中使用 D1 数据库,快速上手。

⚙️ D1 提供强大的命令行工具,例如数据库迁移、数据导入导出,方便管理数据库结构变更、备份与恢复数据,支持本地开发与调试,简化开发流程。

💡 实战案例展示了如何使用 D1 构建一个简单的博客系统,包括创建数据库结构、实现 API 接口,展示了 D1 在实际应用中的强大功能。

秒杀传统数据库! 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-月

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

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

快速上手 D1

1. 安装 Wrangler CLI

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

npm install -g wrangler

2. 创建 D1 数据库

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

wrangler loginwrangler d1 create my-database

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

✅ Successfully created DB 'my-database' in region APACCreated 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.sqlCREATE 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\,讲这个的主要目的是为了给大家普及一下`海外批量应用`的基础套件的知识关于我

Fish AI Reader

Fish AI Reader

AI辅助创作,多种专业模板,深度分析,高质量内容生成。从观点提取到深度思考,FishAI为您提供全方位的创作支持。新版本引入自定义参数,让您的创作更加个性化和精准。

FishAI

FishAI

鱼阅,AI 时代的下一个智能信息助手,助你摆脱信息焦虑

联系邮箱 441953276@qq.com

相关标签

Cloudflare D1 Drizzle 数据库 成本优化 边缘计算
相关文章