数据库选项

本页内容

EmDash 支持多种数据库后端。根据您的部署目标进行选择。

概述

数据库最适合部署
D1Cloudflare WorkersEdge,全球分布
PostgreSQL生产环境 Node.js任何支持 Postgres 的平台
libSQL远程数据库Edge 或 Node.js
SQLiteNode.js,本地开发单服务器

Cloudflare D1

D1 是 Cloudflare 的无服务器 SQLite 数据库。在部署到 Cloudflare Workers 时使用它。

import { d1 } from "@emdash-cms/cloudflare";

export default defineConfig({
	integrations: [
		emdash({
			database: d1({ binding: "DB" }),
		}),
	],
});

配置

选项类型默认值描述
bindingstring来自 wrangler.jsonc 的 D1 绑定名称
sessionstring"disabled"读取复制模式(见下文)
bookmarkCookiestring"__em_d1_bookmark"会话书签的 Cookie 名称

设置

wrangler.jsonc

{
  "d1_databases": [
    {
      "binding": "DB",
      "database_name": "emdash-db"
    }
  ]
}

wrangler.toml

[[d1_databases]]
binding = "DB"
database_name = "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 确保下一个请求至少看到该状态。
  • 写入请求POSTPUTDELETE)始终从主数据库开始。
  • 构建时查询(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,
			}),
		}),
	],
});

配置

选项类型描述
urlstring数据库 URL(libsql://...file:...
authTokenstring远程数据库的认证令牌(本地可选)

本地开发

在开发期间使用本地 libSQL 文件:

database: libsql({ url: "file:./data.db" });

PostgreSQL

PostgreSQL 支持需要完整关系数据库的 Node.js 部署。

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,
});
选项类型描述
connectionStringstringPostgreSQL 连接 URL
hoststring数据库主机
portnumber数据库端口
databasestring数据库名称
userstring数据库用户
passwordstring数据库密码
sslboolean启用 SSL
pool.minnumber最小池连接数(默认 0)
pool.maxnumber最大池连接数(默认 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" }),
		}),
	],
});

配置

选项类型描述
urlstring带有 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 在第一个请求时自动运行迁移,适用于每个支持的方言(D1、SQLite、libSQL、PostgreSQL)。迁移与 emdash 包捆绑在一起并嵌入到您的构建中。

如果数据库为空(没有集合)并且设置向导尚未完成,EmDash 还会在首次启动时应用种子文件。种子从 .emdash/seed.jsonpackage.json#emdash.seed 中的路径或 seed/seed.json 读取 — 以先找到的为准 — 并在编译时内联到构建中。如果都不存在,则使用内置的默认种子。针对现有数据库的后续启动会保持其内容不变。

基于环境的配置

为每个环境使用不同的数据库:

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" });