跳到主要内容

Deno KV 快速入门

Deno KV 是一个 key-value 数据库 直接内置于 Deno 运行时中,可在 Deno.Kv 命名空间 中使用。它可用于 许多种数据存储用途,但在存储简单数据结构并且需要非常快速读写的情况下表现出色。Deno KV 可用于 Deno CLI 和 Deno Deploy 中。

Deno KV 目前处于测试阶段

Deno 的 KV 及其相关的云基元 API,如队列和定时任务,目前仍处于实验性阶段,可能会发生变化。尽管我们尽力确保数据持久性,但特别是在 Deno 更新时,仍然存在数据丢失的可能性。

在启动使用 KV 的 Deno 程序时,需要添加--unstable标志,如下所示:

deno run -A --unstable my_kv_code.ts

让我们来看看 Deno KV 的主要特点。

打开数据库

在你的 Deno 程序中,你可以使用 Deno.openKv() 获取一个 KV 数据库的引用。你可以选择传入一个可选的文件系统路径,用于存储数据库,否则将基于你的脚本的当前工作目录为你创建一个。

const kv = await Deno.openKv();

创建、更新和读取键值对

Deno KV 中的数据存储为键值对,类似于 JavaScript 对象字面量或 Map 的属性。 表示为 JavaScript 类型的数组,如 stringnumberbigintboolean。值可以是任意的 JavaScript 对象。在此示例中,我们创建一个表示用户 UI 首选项的键值对,并使用 kv.set() 保存它。

const kv = await Deno.openKv();

const prefs = {
username: "ada",
theme: "dark",
language: "en-US",
};

const result = await kv.set(["preferences", "ada"], prefs);

一旦设置了键值对,你可以使用 kv.get() 从数据库中读取它:

const entry = await kv.get(["preferences", "ada"]);
console.log(entry.key);
console.log(entry.value);
console.log(entry.versionstamp);

getlist 操作 都返回一个 KvEntry 对象,具有以下属性:

  • key - 用于设置值的数组键
  • value - 为此键设置的 JavaScript 对象
  • versionstamp - 用于确定是否已更新键的生成值。

set 操作还用于更新已经存在于给定键的对象。当键的值被更新时,它的 versionstamp 将更改为新生成的值。

列出多个键值对

要获取有限数量的键的值,你可以使用 kv.getMany()。将多个键作为参数传递,你将收到每个键的值数组。注意,如果给定键的值不存在,值和版本戳可以为 null

const kv = await Deno.openKv();
const result = await kv.getMany([
["preferences", "ada"],
["preferences", "grace"],
]);
result[0].key; // ["preferences", "ada"]
result[0].value; // { ... }
result[0].versionstamp; // "00000000000000010000"
result[1].key; // ["preferences", "grace"]
result[1].value; // null
result[1].versionstamp; // null

通常,检索共享给定前缀的所有键值对的列表是有用的。使用 kv.list() 可以执行此类操作。在此示例中,我们获取共享 "preferences" 前缀的键值对列表。

const kv = await Deno.openKv();
const entries = kv.list({ prefix: ["preferences"] });
for await (const entry of entries) {
console.log(entry.key); // ["preferences", "ada"]
console.log(entry.value); // { ... }
console.log(entry.versionstamp); // "00000000000000010000"
}

返回的键是基于前缀后的键的下一个组件按字典顺序排序的。因此,具有这些键的 KV 对:

  • ["preferences", "ada"]
  • ["preferences", "bob"]
  • ["preferences", "cassie"]

将按 kv.list() 的顺序返回。

读操作可以在 强一致性或最终一致性模式 中执行。强一致性模式保证读取操作将返回最近写入的值。最终一致性模式可能返回陈旧的值,但更快。相比之下,写操作始终在强一致性模式下执行。

删除键值对

你可以使用 kv.delete() 从数据库中删除键。如果给定键找不到值,将不执行任何操作。

const kv = await Deno.openKv();
await kv.delete(["preferences", "alan"]);

原子事务

Deno KV 能够执行原子事务,这使你能够有条件地执行一个或多个数据操作。在下面的示例中,仅当首选项对象尚未创建时,我们创建一个新的首选项对象。

const kv = await Deno.openKv();

const key = ["preferences", "alan"];
const value = {
username: "alan",
theme: "light",
language: "en-GB",
};

const res = await kv
.atomic()
.check({ key, versionstamp: null }) // `null` versionstamps mean 'no value'
.set(key, value)
.commit();
if (res.ok) {
console.log("首选项尚未存在。已插入!");
} else {
console.error("首选项已经存在。");
}

在 Deno KV 中了解更多关于事务的内容 在此处

使用二级索引改进查询

辅助索引 通过多个键存储相同的数据,使得获取所需数据的查询变得更加简单。假设我们需要通过用户名和电子邮件两种方式访问用户偏好设置。为了实现这一点,您可以提供一个函数,该函数包装了保存偏好设置的逻辑,以创建两个索引。

const kv = await Deno.openKv();

async function savePreferences(prefs) {
const key = ["preferences", prefs.username];

// 设置主键
const r = await kv.set(key, prefs);

// 将辅助键的值设置为主键
await kv.set(["preferencesByEmail", prefs.email], key);

return r;
}

async function getByUsername(username) {
// 如之前所述...
const r = await kv.get(["preferences", username]);
return r;
}

async function getByEmail(email) {
// 通过电子邮件查找键,然后再次查找实际数据
const r1 = await kv.get(["preferencesByEmail", email]);
const r2 = await kv.get(r1.value);
return r2;
}

在手册中了解更多关于二级索引的内容。

生产用途

Deno KV 可在 Deno Deploy 上的实时应用程序中使用。在生产中,Deno KV 由 FoundationDB 支持,这是由 Apple 创建的开源键值存储。

无需额外配置,你可以在 Deploy 上运行使用 KV 的 Deno 程序 - 当你的代码需要时,将为你提供新的 Deploy 数据库。在此处了解更多关于 Deno Deploy 上的 Deno KV 的信息。

下一步

到目前为止,你仅仅开始了解 Deno KV 的基础知识。请确保查看我们的关于 Deno KV 键空间 的指南,以及这里的教程和示例应用程序集合。