# Deno KV

Deno KV 是内置于运行时的 key-value 存储，本地通过 `Deno.openKv()` 使用，在新 Deno Deploy 上作为可关联的数据库引擎提供。截至 2026-08-03，KV 官方仍标注为开发中、API 可能变化，本地运行需要 `--unstable-kv`。

```ts
const kv = await Deno.openKv();

await kv.set(["sessions", sid], { userId, createdAt: new Date() });
const entry = await kv.get(["sessions", sid]);

const result = await kv.atomic()
  .check(entry) // versionstamp 未变才提交
  .set(["sessions", sid], { userId, rotatedAt: new Date() })
  .commit();
```

本地开发：`Deno.openKv("./data/app.kv")` 持久化到文件，`Deno.openKv(":memory:")` 用于测试。

```bash
# KV 的底层磁盘访问不需要 --allow-read/--allow-write（官方权限文档明确列出），
# 只为应用自身的其他 I/O 授权
deno run --unstable-kv main.ts
```

<Callout type="warn" title="平台现状（2026-08-03 核实）">
Deploy Classic 已于 2026-07-20 关停。新 Deno Deploy 支持将 Deno KV 作为数据库引擎关联到 app，`Deno.openKv()` 自动连接当前 timeline 的隔离逻辑数据库；但官方迁移指南明确：Classic 的 KV 数据不会自动迁移，需联系 support@deno.com 协助；KV Queues（`kv.enqueue()` / `kv.listenQueue()`）在新平台不支持；单个 app 目前只能关联一个数据库实例，不能同时挂 KV 和 PostgreSQL。依赖这些能力的架构要先改设计再迁移。
</Callout>

## API 要点

- key 是数组：`["users", userId]`。组成部分可以是 string、number、boolean、bigint、Uint8Array，按字典序排序，类型序优先于值序。
- value 必须兼容 structured clone（对象、数组、Map、Set、Date、Uint8Array 等）；类实例、函数、Symbol 不支持。
- `get` / `getMany` / `list`：读取。`list` 按 prefix 或 range 分批返回，默认每批 500，批间不保证同一快照。
- `set` / `delete` 与 `sum` / `min` / `max`（后者仅 atomic 内、仅 `Deno.KvU64`）。
- `atomic()`：乐观并发控制，`.check()` 断言 versionstamp，`.commit()` 失败时重读重试；不使用锁式交互事务。
- `watch(keys)`：返回 `ReadableStream`，key 变更时推送；快速连续变更可能被合并，不保证看到每个中间状态。

## 一致性模型

- 写入始终强一致。
- 读取可选 strong（保证返回最近写入值）或 eventual（更快，可能返回旧值）；所有一致性级别下 `get` 都是快照读。
- 每次写入获得单调递增、非顺序的 12 字节 versionstamp，同一事务内的写入共享同一个。

主要限制（官方事务文档）：key 最大 2 KiB，value 最大 64 KiB；`getMany` 最多 10 个 key；`list` 单批最多 1000；单个 atomic 最多 100 个 check、1000 个 mutation、总大小 800 KiB；`watch` 最多 10 个 key。

## 新 Deno Deploy 上的 KV

- KV 通过组织 dashboard 的 databases 功能开通并指派给 app；生产、分支、preview timeline 自动获得隔离的逻辑数据库。
- 从 Deploy 之外访问（如本地连远端库）：连接 URL 为 `https://api.deno.com/v2/databases/<Database ID>/connect`，用 `DENO_KV_ACCESS_TOKEN` 环境变量放个人或组织 token。
- 数据驻留：官方注明 KV 主区域为美国 Northern Virginia，在欧洲和亚洲有只读副本，写入会经美国存储与传输，因此需要严格欧盟数据驻留的场景不适用，官方建议改用其 Postgres 方案。
- 当前限制：每个 app 只能关联一个数据库实例；preview 数据库由所有 preview deployment 共用；database explorer 暂不支持 KV。

## 何时不该用 KV

- 需要队列：新平台不支持 `enqueue` / `listenQueue`，改用外部队列或以数据库实现任务表。
- 需要关系查询、join、临时 SQL 分析：KV 只有 key 查找与前缀扫描，二级索引要自己维护。
- 单值超过 64 KiB，或单事务超过官方 atomic 限制。
- 严格欧盟数据驻留合规。
- 同一 app 同时需要 KV 和 PostgreSQL（当前平台限制）。
- 要求 API 长期冻结：KV 官方仍标注为可能变化。

官方参考：[Deno KV 概览](https://docs.deno.com/deploy/kv/)、[KV 操作与一致性](https://docs.deno.com/deploy/kv/operations/)、[KV 事务与限制](https://docs.deno.com/deploy/kv/transactions/)、[Key space 与值类型](https://docs.deno.com/deploy/kv/key_space/)、[新 Deploy 的 Deno KV](https://docs.deno.com/deploy/reference/deno_kv/)、[Classic 迁移指南](https://docs.deno.com/deploy/migration_guide/)。
