EmDash 支持多种数据库后端。根据你的部署目标进行选择。
概述
| 数据库 | 最适合 | 部署 |
|---|---|---|
| D1 | Cloudflare Workers | 边缘,全球分布 |
| PostgreSQL | 生产环境 Node.js | 任何支持 Postgres 的平台 |
| libSQL | 远程数据库 | 边缘或 Node.js |
| SQLite | Node.js,本地开发 | 单服务器 |
Cloudflare D1
D1 是 Cloudflare 的无服务器 SQLite 数据库。在部署到 Cloudflare Workers 时使用它。
import { d1 } from "@emdash-cms/cloudflare";
export default defineConfig({
integrations: [
emdash({
database: d1({ binding: "DB" }),
}),
],
});
配置
| 选项 | 类型 | 默认值 | 描述 |
|---|---|---|---|
binding | string | — | 来自 wrangler.jsonc 的 D1 绑定名称 |
session | string | "disabled" | 读取复制模式(见下文) |
bookmarkCookie | string | "__em_d1_bookmark" | 会话书签的 Cookie 名称 |
设置
wrangler.jsonc
{
"d1_databases": [
{
"binding": "DB",
"database_name": "emdash-db",
"database_id": "your-database-id"
}
]
} wrangler.toml
[[d1_databases]]
binding = "DB"
database_name = "emdash-db"
database_id = "your-database-id" 创建 D1 数据库
wrangler d1 create emdash-db
读取副本
D1 支持读取复制,为全球分布的站点降低读取延迟。启用后,读取查询会路由到附近的副本,而不是总是访问主数据库。
EmDash 使用 D1 Sessions API 透明地管理这一点。使用 session 选项启用它:
import { d1 } from "@emdash-cms/cloudflare";
export default defineConfig({
integrations: [
emdash({
database: d1({
binding: "DB",
session: "auto",
}),
}),
],
});
会话模式
| 模式 | 行为 |
|---|---|
"disabled" | 无会话。所有查询都发送到主数据库。默认值。 |
"auto" | 匿名请求从最近的副本读取。已认证用户通过书签 Cookie 获得读写一致性。 |
"primary-first" | 类似 "auto",但第一个查询总是发送到主数据库。用于写入非常频繁的站点。 |
工作原理
- 匿名访问者获得
first-unconstrained— 读取发送到最近的副本以获得最低延迟。由于匿名用户从不写入,他们不需要一致性保证。 - 已认证用户(编辑者、作者)获得基于书签的会话。写入后,书签 Cookie 确保下一个请求至少看到该状态。
- 写入请求(
POST、PUT、DELETE)始终从主数据库开始。 - 构建时查询(Astro 内容集合)完全绕过会话并直接使用主数据库。
libSQL
libSQL 是 SQLite 的一个分支,支持远程连接。当你需要远程数据库而不使用 Cloudflare D1 时使用它。
import { libsql } from "emdash/db";
export default defineConfig({
integrations: [
emdash({
database: libsql({
url: process.env.LIBSQL_DATABASE_URL,
authToken: process.env.LIBSQL_AUTH_TOKEN,
}),
}),
],
});
配置
| 选项 | 类型 | 描述 |
|---|---|---|
url | string | 数据库 URL(libsql://... 或 file:...) |
authToken | string | 远程数据库的认证令牌(本地可选) |
本地开发
在开发期间使用本地 libSQL 文件:
database: libsql({ url: "file:./data.db" });
PostgreSQL
Node.js 部署需要完整关系数据库时支持 PostgreSQL。
import { postgres } from "emdash/db";
export default defineConfig({
integrations: [
emdash({
database: postgres({
connectionString: process.env.DATABASE_URL,
}),
}),
],
});
配置
你可以使用连接字符串或单独的参数进行连接:
// 连接字符串
database: postgres({
connectionString: "postgres://user:password@localhost:5432/emdash",
});
// 单独的参数
database: postgres({
host: "localhost",
port: 5432,
database: "emdash",
user: "emdash",
password: process.env.DB_PASSWORD,
ssl: true,
});
| 选项 | 类型 | 描述 |
|---|---|---|
connectionString | string | PostgreSQL 连接 URL |
host | string | 数据库主机 |
port | number | 数据库端口 |
database | string | 数据库名称 |
user | string | 数据库用户 |
password | string | 数据库密码 |
ssl | boolean | 启用 SSL |
pool.min | number | 最小池连接数(默认 0) |
pool.max | number | 最大池连接数(默认 10) |
连接池
适配器在底层使用 pg.Pool。根据你的部署调整池大小:
database: postgres({
connectionString: process.env.DATABASE_URL,
pool: { min: 2, max: 20 },
});
SQLite
使用 better-sqlite3 的 SQLite 是 Node.js 部署的最简单选项。
import { sqlite } from "emdash/db";
export default defineConfig({
integrations: [
emdash({
database: sqlite({ url: "file:./data.db" }),
}),
],
});
配置
| 选项 | 类型 | 描述 |
|---|---|---|
url | string | 带有 file: 前缀的文件路径 |
文件路径
url 必须以 file: 开头:
// 相对路径
database: sqlite({ url: "file:./data/emdash.db" });
// 绝对路径
database: sqlite({ url: "file:/var/data/emdash.db" });
// 来自环境变量
database: sqlite({ url: `file:${process.env.DATABASE_PATH}` });
迁移
EmDash 自动处理 SQLite、libSQL 和 PostgreSQL 的迁移。对于 D1,通过 Wrangler 运行迁移。
检查迁移状态
npx emdash init --database ./data.db
此命令:
- 如果需要,创建数据库文件
- 运行任何挂起的迁移
- 报告当前迁移状态
迁移文件
迁移与 EmDash 捆绑在一起。要手动运行它们:
# SQLite/libSQL - 迁移自动运行
# D1 - 通过 wrangler 运行
wrangler d1 migrations apply DB
基于环境的配置
为每个环境使用不同的数据库:
import { sqlite, libsql, postgres } from "emdash/db";
import { d1 } from "@emdash-cms/cloudflare";
const database = import.meta.env.PROD ? d1({ binding: "DB" }) : sqlite({ url: "file:./data.db" });
export default defineConfig({
integrations: [emdash({ database })],
});
或根据环境变量切换:
const database = process.env.DATABASE_URL
? postgres({ connectionString: process.env.DATABASE_URL })
: sqlite({ url: "file:./data.db" });