@aws- blocks/ bb- 分布数据
无服务器SQL数据库由亚马逊·奥罗拉DSQL支持. 0-ops,即时提供,规模为零,可选的多区域活性写作.
何时使用 : 无服务器应用程序需要缩放,不需要操作管理,零闲成本要求的工作量,多区域活性写作,或者不需要行级安全,触发,程序,或PL/pgSQL功能的任何SQL应用程序.
不使用时 : 如果需要行级安全,触发器,程序,或PL/pgSQL函数——使用 Database (奥罗拉语). Aurora DSQL支持SQL语言功能. 如果您需要交易, 且交易不能在争议中失败 Database如果连接到Supabase——使用 Database 与 fromExisting()。 。 。 .
设计与模拟等价细节 : 设计
快速启动
import { DistributedDatabase, sql } from '@aws-blocks/bb-distributed-data';
const db = new DistributedDatabase(scope, 'main', {
migrationsPath: './aws-blocks/dsql-migrations',
});
// Same query API as Database — parameterized via sql tagged template
const users = await db.query<{ id: string; name: string }>(
sql`SELECT * FROM users WHERE active = ${true}`
);
const user = await db.queryOne<{ id: string; name: string }>(
sql`SELECT * FROM users WHERE id = ${userId}`
);
const { rowCount } = await db.execute(
sql`INSERT INTO users (id, name, email) VALUES (${id}, ${name}, ${email})`
);
交易(货币管制)
DSQL使用OCC——如果另一笔交易修改了同一行,交易可能会失败. 回调执行一次, 除非你选择重试 .
// Default: no retry. Throws SerializationFailureException (HTTP 409 Conflict, retriable) on conflict.
await db.transaction(async (tx) => {
await tx.execute(sql`UPDATE accounts SET balance = balance - ${100} WHERE id = ${fromId}`);
await tx.execute(sql`UPDATE accounts SET balance = balance + ${100} WHERE id = ${toId}`);
});
// Opt-in retry: callback may execute multiple times.
// ⚠️ Do NOT include external side effects (HTTP calls, emails) inside.
await db.transaction(async (tx) => {
await tx.execute(sql`UPDATE accounts SET balance = balance - ${100} WHERE id = ${fromId}`);
await tx.execute(sql`UPDATE accounts SET balance = balance + ${100} WHERE id = ${toId}`);
}, { retryOnConflict: true, maxRetries: 3 });
第二个论点 transaction() 接受:
interface TransactionOptions {
/** Retry on OCC conflict. Callback may execute multiple times. @default false */
retryOnConflict?: boolean;
/** Max retry attempts. Only applies when retryOnConflict is true. @default 3 */
maxRetries?: number;
}
移徙
每个文件有一个DDL语句. DML在不同的文件中。 这符合DSQL的交易限制.
aws-blocks/dsql-migrations/
001_create_users.sql ← single DDL
002_create_posts.sql ← single DDL
003_create_index.sql ← single DDL (CREATE INDEX ASYNC)
004_seed_admin.sql ← DML only
-- 001_create_users.sql
CREATE TABLE users (
id TEXT PRIMARY KEY DEFAULT gen_random_uuid(),
email TEXT UNIQUE NOT NULL,
name TEXT NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
-- 003_create_index.sql
CREATE INDEX ASYNC idx_users_email ON users(email);
移民情况得到检查 dsql-lint 在合成时间.
设定
migrationsPath与工程根相对的路径 (例如:.'./aws-blocks/dsql-migrations'); 由您运行的目录合成解析cdk编号 :npm run deploy进来 这是最简单的可靠模式.你用不着
fileURLToPath(import.meta.url)为了这个 您的后端模块在当地作为无害环境管理运行,但捆绑到 常见JS 在兰布达,在那里import.meta为空。 AWS 屏蔽闪烁import.meta.url编号 :import.meta.dirname{\fn黑体\fs22\bord1\shad0\3ahbe\4ah00\fscx67\fscy66\2chffffff\3ch808080}所以它不会在装货时坠毁 {\fn黑体\fs22\bord1\shad0\3ahbe\4ah00\fscx67\fscy66\2chffffff\3ch808080}但是在运行时 捆绑输出 位置,而不是您的源树。 所以别用import.meta.url在请求的时间读取与您来源相关的文件; 输入数据或将其作为Lambda资产.
邮递SQL 兼容性
Aurora DSQL是 PostgreSQL 有线-protocol相容的. SQL 特性兼容性不同于 PostgreSQL; 见 Aurora DSQL SQL 兼容文档 详细情况.
| 未支持 | 备选案文 |
|---|---|
| 行级安全 | 在应用程序代码中过滤条款的位置 |
| 触发器 | 事件驱动逻辑(Event Bridge、Lambda) |
| 程序 | LANGUAGE SQL 函数或应用程序逻辑 |
| PL/pgSQL 函数 | LANGUAGE SQL 函数或应用程序逻辑 |
| 职位/职位 | BIGINT GENERATED BY DEFAULT AS IDENTITY (CACHE 1) 或 UUID (% 1) (gen_random_uuid()(三); CACHE 用于身份栏和序列,必须是 1 或者说 >= 65536 |
| 特伦特 | DELETE FROM |
| 临时表格 | CTEs 或子电池 |
| 听/通知 | AppSync事件、事件桥或民意调查 |
| 扩展 | 不详 |
| ADD COLUMN 与国防 | 在不默认情况下添加列, 回填已存在的行, 然后使用 ALTER COLUMN ... SET DEFAULT |
索引密钥排序方向( E)ASC编号 :DESC(中文(简体) ) | 关闭它; 执行命令 ORDER BY 查询(NULLS FIRST/LAST 已支持) |
交易限制
| 约束 | 限制 |
|---|---|
| 货币模型 | OCC(可能发生冲突) |
| 隔离级别 | 固定: 可重复读取 |
| 每个交易的最大行变异 | 3 000个 |
| 每笔交易的最大数据 | 10个小米B |
| 最大交易期限 | 5分钟 |
| 每笔交易的DDL | 1个最大语句 |
| DDL + DML 混合 | 不允许 |
Kysely 查询构建器
import { createKyselyAdapter } from '@aws-blocks/bb-distributed-data';
interface Schema {
users: { id: string; email: string; name: string };
}
const kysely = createKyselyAdapter<Schema>(db);
const users = await kysely
.selectFrom('users')
.where('email', '=', '[email protected]')
.selectAll()
.execute();
别用Kysely的 .addForeignKeyConstraint() - 它会在DSQL上失败.
处理错误
import { DistributedDatabaseErrors } from '@aws-blocks/bb-distributed-data';
import { isBlocksError } from '@aws-blocks/core';
try {
await db.transaction(async (tx) => { /* ... */ });
} catch (e: unknown) {
if (isBlocksError(e, DistributedDatabaseErrors.SerializationFailure)) {
// OCC conflict — transaction was NOT committed. Serialized as HTTP 409
// (Conflict), retriable — safe to retry.
}
if (isBlocksError(e, DistributedDatabaseErrors.UniqueConstraintViolation)) {
// Duplicate key — serialized as HTTP 409 (Conflict), not retriable
// (a blind retry of the same insert fails identically).
}
if (isBlocksError(e, DistributedDatabaseErrors.QueryFailed)) {
// General query failure
}
if (isBlocksError(e, DistributedDatabaseErrors.TransactionRowLimitExceeded)) {
// More than 3,000 rows mutated in one transaction
}
if (isBlocksError(e, DistributedDatabaseErrors.ConnectionFailed)) {
// Cannot reach the DSQL cluster
}
if (isBlocksError(e, DistributedDatabaseErrors.TransactionFailed)) {
// Transaction could not commit (general failure distinct from serialization/row-limit)
}
}
测试 OCC 冲突
模型提供了 simulateConflict() 单位测试的助手。 它只与本地的嘲弄相悖:
部署 AWS 运行时间 cdk synth 它抛出通常的合成时错误.
db.simulateConflict(); // next commit will fail with SerializationFailureException
await expect(db.transaction(fn)).rejects.toThrow('SerializationFailureException');
db.simulateConflict(); // first attempt fails, second succeeds
const result = await db.transaction(fn, { retryOnConflict: true });
它的规定
- 奥罗拉DSQL集群 ——无服务器,不需要VPC,公开端点
- 移徙Lambda —运行
.sql关于通过自定义资源进行再试部署的文件 - 行政会议 —— 说
dsql:DbConnect(app Lambda,仅限DML),dsql:DbConnectAdmin(移民兰布达,DDL) - 环境变量 —— 说
BLOCKS_{name}_ENDPOINT, (中文(简体) ),BLOCKS_{name}_REGION
没有VPC,没有秘密,没有安全小组,没有代理. DSQL使用 IAM 令牌认证.
地方发展
- 引擎 : PGlite (WASM PostgreSQL) 由 DSQL 兼容层所包裹
- 存储 :
.bb-data/{fullId}/——在重启期间坚持不懈 - 验证 :
dsql-lint在 PGlite 执行前检查 SQL - 交易跟踪 : DDL/DML混合和3 000行限制在当地执行
迁移 SQL 还检查过 dsql-lint 在CDK合成时,在捆绑用于部署之前.
配置
interface DistributedDatabaseOptions {
/** Path to directory containing numbered .sql migration files. */
migrationsPath?: string;
/** Removal policy. @default 'retain' */
removalPolicy?: 'destroy' | 'retain';
/** Optional logger for internal operations. When omitted, a default Logger at error level is created. */
logger?: ChildLogger;
}
软件包导出条件
{
"exports": {
".": {
"cdk": "./dist/index.cdk.js",
"aws-runtime": "./dist/index.aws.js",
"default": "./dist/index.mock.js"
}
}
}
与数据库的差异(奥罗拉)
| 侧面 | Database (bb-data) (英语) | DistributedDatabase (bb-分布数据) |
|---|---|---|
| 发动机 | Aurora 无服务器 v2(数据 API) | 奥罗拉 DSQL (pg + IAM) |
| PostgreSQL 兼容性 | 满 | 电线协议兼容; 见 SQL 兼容性细节 |
| 交易 | 悲观主义(准确的一) | OCC(可能发生冲突) |
withRLS() | ✅ | ❌ |
fromExisting() | ✅ | ❌ |
crud() | ✅ | ❌ |
| 外国密钥 | ✅ | ✅ |
| 多国 | ❌ | 积极活动 |
| 要求 | 对 | 没有 |
| 部署时间 | ~10分钟 | 秒数 |
| 闲置费用 | 0美元(0 ACU) | 0美元 (单位:美元) |