deno.com
本頁面內容

Deno KV 快速入門

Deno KV 是一個直接建置於 Deno 執行階段的 鍵值資料庫,可在 Deno.Kv 命名空間 中使用。它可用於多種資料儲存使用案例,但在儲存受益於極快速讀寫的簡單資料結構方面表現出色。Deno KV 可在 Deno CLI 和 Deno Deploy 上使用。

讓我們逐步了解 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()。傳入多個鍵作為引數,您將收到每個鍵的值陣列。請注意,如果給定鍵不存在值,則值和 versionstamp 可能為 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("Preferences did not yet exist. Inserted!");
} else {
  console.error("Preferences already exist.");
}

在此處了解有關 Deno KV 交易的更多資訊 這裡

使用次要索引改進查詢 跳到標題

次要索引 使用多個鍵儲存相同的資料,從而可以更輕鬆地查詢您需要的資料。假設我們需要能夠透過使用者名稱和電子郵件存取使用者偏好設定。為了啟用此功能,您可以提供一個函數來包裝邏輯,以儲存偏好設定以建立兩個索引。

const kv = await Deno.openKv();

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

  // Set the primary key
  const r = await kv.set(key, prefs);

  // Set the secondary key's value to be the primary key
  await kv.set(["preferencesByEmail", prefs.email], key);

  return r;
}

async function getByUsername(username) {
  // Use as before...
  const r = await kv.get(["preferences", username]);
  return r;
}

async function getByEmail(email) {
  // Look up the key by email, then second lookup for actual data
  const r1 = await kv.get(["preferencesByEmail", email]);
  const r2 = await kv.get(r1.value);
  return r2;
}

在此處的手冊中了解有關 次要索引的更多資訊

在 Deno KV 中監看更新 跳到標題

您也可以使用 kv.watch() 從 Deno KV 監聽更新,這將發出您提供的鍵或多個鍵的新值。在下面的聊天範例中,我們監看鍵 ["last_message_id", roomId] 的更新。我們檢索 messageId,然後將其與 kv.list() 結合使用,以從 seenmessageId 抓取所有新訊息。

let seen = "";
for await (const [messageId] of kv.watch([["last_message_id", roomId]])) {
  const newMessages = await Array.fromAsync(kv.list({
    start: ["messages", roomId, seen, ""],
    end: ["messages", roomId, messageId, ""],
  }));
  await websocket.write(JSON.stringify(newMessages));
  seen = messageId;
}

在此處了解有關 使用 Deno KV 監看的更多資訊

生產環境使用 跳到標題

Deno KV 可在 Deno Deploy 上的即時應用程式中使用。在生產環境中,Deno KV 由 Apple 建立的開放原始碼鍵值儲存庫 FoundationDB 支援。

無需額外設定 即可在 Deploy 上執行使用 KV 的 Deno 程式 - 當您的程式碼需要時,將為您佈建新的 Deploy 資料庫。在此處了解有關 Deno Deploy 上的 Deno KV 的更多資訊 這裡

測試 跳到標題

預設情況下,Deno.openKv() 會根據調用它的腳本執行的路徑建立或開啟持久性儲存區。這通常不是測試所期望的,因為測試需要多次連續執行時產生相同的行為。

若要測試使用 Deno KV 的程式碼,您可以使用特殊引數 ":memory:" 來建立臨時 Deno KV 資料儲存區。

async function setDisplayName(
  kv: Deno.Kv,
  username: string,
  displayname: string,
) {
  await kv.set(["preferences", username, "displayname"], displayname);
}

async function getDisplayName(
  kv: Deno.Kv,
  username: string,
): Promise<string | null> {
  return (await kv.get(["preferences", username, "displayname"]))
    .value as string;
}

Deno.test("Preferences", async (t) => {
  const kv = await Deno.openKv(":memory:");

  await t.step("can set displayname", async () => {
    const displayName = await getDisplayName(kv, "example");
    assertEquals(displayName, null);

    await setDisplayName(kv, "example", "Exemplary User");

    const displayName = await getDisplayName(kv, "example");
    assertEquals(displayName, "Exemplary User");
  });
});

這是可行的,因為 Deno KV 在本機開發執行時由 SQLite 支援。就像記憶體中的 SQLite 資料庫一樣,可以同時存在多個臨時 Deno KV 儲存區,而不會相互干擾。如需有關特殊資料庫定址模式的更多資訊,請參閱 有關該主題的 SQLite 文件

下一步 跳到標題

在這一點上,您才剛開始接觸 Deno KV 的表面。請務必查看我們關於 Deno KV 鍵空間 的指南,以及此處的 教學和範例應用程式 集合。

您找到需要的資訊了嗎?

隱私權政策