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 類型陣列表示,例如 string
、number
、bigint
或 boolean
。值可以是任意 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);
get
和 list
操作 都會傳回一個具有以下屬性的 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()
結合使用,以從 seen
和 messageId
抓取所有新訊息。
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 鍵空間 的指南,以及此處的 教學和範例應用程式 集合。