使用索引資料庫

本指南涵蓋 IndexedDB API。 我們使用 Jake Archibald 的 已建立索引的資料庫 與 IndexedDB API 非常類似 但使用了承諾 您可以 await 取得更簡潔的語法。這樣可簡化 API 以及維持原本的結構

什麼是 IndexedDB?

IndexedDB 是大規模的 NoSQL 儲存系統 對使用者瀏覽器中的所有資訊除了一般的搜尋、取得和 它更適合用於輸入操作 儲存大量結構化資料

每個 IndexedDB 資料庫都只屬於一個來源 (通常是網站網域或子網域) 表示無法存取或存取 不受其他來源影響其資料儲存空間限制 通常會很大,但也會有,但不同瀏覽器處理限制 以及資料撤銷方式如要瞭解相關資訊,請參閱其他資訊一節 瞭解詳情

IndexedDB 詞彙

資料庫
IndexedDB 的最高層。其中包含物件儲存庫, 包含要保留的資料。您可以建立多個資料庫 你選的名稱
物件存放區
用來儲存資料的個別值區,類似關聯資料庫中的資料表。 一般來說,每種「類型」 (非 JavaScript 資料) 都有一個物件儲存庫 自訂類型)。與資料庫表格不同的是,JavaScript 資料 儲存庫中的資料類型不需要一致。舉例來說 有一個 people 物件儲存庫,內含三個人的資訊 使用者的年齡屬性可以是 53'twenty-five'unknown
索引
一種物件儲存區,可用來整理其他物件存放區中的資料 (稱為 參照物件儲存庫)。系統會使用索引 以擷取此屬性在物件存放區中的記錄。舉例來說 儲存人員時,建議您日後依名稱、年齡或 最喜歡的動物
作業
與資料庫的互動。
交易
包裝一個能確保資料庫的作業或作業群組包裝函式 完整性。如果交易中的其中一項操作失敗,則沒有任何動作失敗 資料庫會回復為交易前的狀態 開始。IndexedDB 中的所有讀取或寫入作業都必須屬於交易的一部分。 如此一來,就能執行不可部分完成的讀取-修改-寫入作業,而不會產生衝突風險 由其他執行緒同時在資料庫中運作。
遊標
針對資料庫中多筆記錄疊代的機制。

如何查看 IndexedDB 支援

IndexedDB 幾乎可全面支援。 不過,如果您使用的是較舊的瀏覽器,那麼 功能偵測支援,以備不時之需最簡單的方法是查看 window 物件:

function indexedDBStuff () {
  // Check for IndexedDB support:
  if (!('indexedDB' in window)) {
    // Can't use IndexedDB
    console.log("This browser doesn't support IndexedDB");
    return;
  } else {
    // Do IndexedDB stuff here:
    // ...
  }
}

// Run IndexedDB code:
indexedDBStuff();

如何開啟資料庫

透過 IndexedDB,您可以使用任何名稱建立多個資料庫。如果 您嘗試開啟資料庫時不存在 如要開啟資料庫,請使用 idb 程式庫中的 openDB() 方法:

import {openDB} from 'idb';

async function useDB () {
  // Returns a promise, which makes `idb` usable with async-await.
  const dbPromise = await openDB('example-database', version, events);
}

useDB();

這個方法會傳回可解析為資料庫物件的承諾。使用 openDB() 方法,提供名稱、版本號碼和要設定的事件物件 以及資料庫。

以下是 openDB() 方法的範例:

import {openDB} from 'idb';

async function useDB () {
  // Opens the first version of the 'test-db1' database.
  // If the database does not exist, it will be created.
  const dbPromise = await openDB('test-db1', 1);
}

useDB();

將檢查 IndexedDB 的支援置於匿名函式的最上方。這個 如果瀏覽器不支援 IndexedDB,就會結束函式。如果函式可以 繼續,這個方法會呼叫 openDB() 方法,開啟名為 'test-db1' 的資料庫。 在這個範例中,選擇性的事件物件並未經過保留, 但您需要指定這個值,才能利用索引資料庫執行任何有意義的工作。

如何使用物件儲存庫

索引資料庫包含一或多個物件儲存庫, 資料欄,另一個是該鍵相關資料的資料欄。

建立物件儲存庫

結構良好的 IndexedDB 資料庫應針對每種類型各建立一個物件儲存庫 需要保存的資料數量例如:使用者持續瀏覽網站 設定檔和附註可能具有包含 personpeople 物件儲存庫 和包含 note 物件的 notes 物件儲存庫。

為確保資料庫完整性,您只能在 openDB() 呼叫中的事件物件。事件物件公開 upgrade() 方法可讓您建立物件儲存庫在 createObjectStore()敬上 upgrade() 方法中的方法建立物件儲存庫:

import {openDB} from 'idb';

async function createStoreInDB () {
  const dbPromise = await openDB('example-database', 1, {
    upgrade (db) {
      // Creates an object store:
      db.createObjectStore('storeName', options);
    }
  });
}

createStoreInDB();

這個方法使用物件儲存庫的名稱,以及選用設定 物件,可讓您定義物件儲存區的各種屬性。

以下範例說明如何使用 createObjectStore()

import {openDB} from 'idb';

async function createStoreInDB () {
  const dbPromise = await openDB('test-db1', 1, {
    upgrade (db) {
      console.log('Creating a new object store...');

      // Checks if the object store exists:
      if (!db.objectStoreNames.contains('people')) {
        // If the object store does not exist, create it:
        db.createObjectStore('people');
      }
    }
  });
}

createStoreInDB();

在這個範例中,事件物件會傳遞至 openDB() 方法,以便建立 物件存放區;和先前一樣,建立物件儲存庫的工作即完成 事件物件的 upgrade() 方法中。不過,由於瀏覽器 如果嘗試建立已存在的物件儲存庫, 將 createObjectStore() 方法包裝在用於檢查的 if 陳述式中 物件儲存空間是否存在在 if 區塊中,呼叫 createObjectStore():建立名為 'firstOS' 的物件儲存庫。

如何定義主鍵

定義物件儲存時,您可以定義如何利用 如果是透過主鍵提交儲存庫如要定義主鍵,您可以定義 金鑰路徑或金鑰產生器

金鑰路徑是一種永遠存在且包含不重複值的屬性。適用對象 舉例來說,如果是 people 物件儲存庫,您可以選擇 做為金鑰路徑:

import {openDB} from 'idb';

async function createStoreInDB () {
  const dbPromise = await openDB('test-db2', 1, {
    upgrade (db) {
      if (!db.objectStoreNames.contains('people')) {
        db.createObjectStore('people', { keyPath: 'email' });
      }
    }
  });
}

createStoreInDB();

這個範例會建立名為 'people' 的物件儲存庫,並指派 email 將屬性做為 keyPath 選項中的主鍵。

您也可以使用金鑰產生器,例如 autoIncrement。金鑰產生器 會為物件儲存區中的每個物件建立專屬的值。根據預設 如未指定索引鍵,IndexedDB 會建立索引鍵,並分開儲存 從資料中取用

以下範例會建立名為 'notes' 的物件儲存庫,並設定 自動遞增的主鍵:

import {openDB} from 'idb';

async function createStoreInDB () {
  const dbPromise = await openDB('test-db2', 1, {
    upgrade (db) {
      if (!db.objectStoreNames.contains('notes')) {
        db.createObjectStore('notes', { autoIncrement: true });
      }
    }
  });
}

createStoreInDB();

下例與先前的範例類似,但這次的例子 自動遞增值已明確指派給名為 'id' 的屬性。

import {openDB} from 'idb';

async function createStoreInDB () {
  const dbPromise = await openDB('test-db2', 1, {
    upgrade (db) {
      if (!db.objectStoreNames.contains('logs')) {
        db.createObjectStore('logs', { keyPath: 'id', autoIncrement: true });
      }
    }
  });
}

createStoreInDB();

請根據您的資料內容,選擇正確的金鑰定義方法。如果您的 資料的屬性不會重複,您可以將其設為 keyPath, 強制規定的唯一性否則,請使用自動遞增值。

以下程式碼會建立三個物件儲存庫,展示 定義物件存放區中的主鍵:

import {openDB} from 'idb';

async function createStoresInDB () {
  const dbPromise = await openDB('test-db2', 1, {
    upgrade (db) {
      if (!db.objectStoreNames.contains('people')) {
        db.createObjectStore('people', { keyPath: 'email' });
      }

      if (!db.objectStoreNames.contains('notes')) {
        db.createObjectStore('notes', { autoIncrement: true });
      }

      if (!db.objectStoreNames.contains('logs')) {
        db.createObjectStore('logs', { keyPath: 'id', autoIncrement: true });
      }
    }
  });
}

createStoresInDB();

如何定義索引

索引是一種物件儲存庫,用來從參照擷取資料 依據指定的屬性儲存物件索引位於參照物件中 儲存和包含相同的資料,但會使用指定的屬性做為其屬性 ,而不是參照儲存庫的主鍵。索引必須建立於 您可以建立物件儲存區,還能針對 資料。

如要建立索引,請呼叫 createIndex() 方法:

import {openDB} from 'idb';

async function createIndexInStore() {
  const dbPromise = await openDB('storeName', 1, {
    upgrade (db) {
      const objectStore = db.createObjectStore('storeName');

      objectStore.createIndex('indexName', 'property', options);
    }
  });
}

createIndexInStore();

這個方法會建立並傳回索引物件。已啟用的 createIndex() 方法 物件儲存庫的例項會採用新索引的名稱做為第一個 第二個引數則參照要儲存的資料上的屬性 索引。最後的引數則可讓您定義兩個選項 索引運作次數:uniquemultiEntry。如果將 unique 設為 true, 索引不允許單一鍵使用重複的值。下一步,multiEntry 決定已建立索引的屬性為陣列時,createIndex() 的行為。如果 設為 truecreateIndex() 會在每個陣列的索引中新增項目 元素。否則,會新增一個包含陣列的項目。

範例如下:

import {openDB} from 'idb';

async function createIndexesInStores () {
  const dbPromise = await openDB('test-db3', 1, {
    upgrade (db) {
      if (!db.objectStoreNames.contains('people')) {
        const peopleObjectStore = db.createObjectStore('people', { keyPath: 'email' });

        peopleObjectStore.createIndex('gender', 'gender', { unique: false });
        peopleObjectStore.createIndex('ssn', 'ssn', { unique: true });
      }

      if (!db.objectStoreNames.contains('notes')) {
        const notesObjectStore = db.createObjectStore('notes', { autoIncrement: true });

        notesObjectStore.createIndex('title', 'title', { unique: false });
      }

      if (!db.objectStoreNames.contains('logs')) {
        const logsObjectStore = db.createObjectStore('logs', { keyPath: 'id', autoIncrement: true });
      }
    }
  });
}

createIndexesInStores();

在這個範例中,'people''notes' 物件儲存庫具有索引。目的地: 建立索引,請先指派 createObjectStore() 的結果 (物件 儲存物件) 新增至變數中,因此您可以在該變數上呼叫 createIndex()

如何使用資料

本節說明如何建立、讀取、更新及刪除資料。這些 都是非同步作業,使用 IndexedDB API 的承諾 要求。這樣可簡化 API。與其監聽 要求,您可以對呼叫函式所傳回的資料庫物件呼叫 .then()。 用於與資料庫互動的 openDB() 方法,或 await 其 建立。

凡是已建立索引資料庫中的資料作業,都是在交易中執行。每項 作業的格式如下:

  1. 取得資料庫物件。
  2. 開啟資料庫上的交易。
  3. 在交易中開啟物件儲存庫。
  4. 在物件儲存庫執行作業。

交易可視為作業或群組周圍的安全包裝函式 作業。如果交易中的任一動作失敗,則所有 交易專屬於一或多個物件存放區 自訂範本可以是唯讀或讀取 以及寫入與寫入這代表交易內的作業是否讀取了 或對資料庫進行變更

建立資料

如要建立資料,請呼叫 add() 方法並傳入您要新增的資料。add() 方法的第一個引數是您要加入資料的物件儲存庫,而 第二個引數是包含所需欄位和關聯資料的物件 。以下為最簡單的範例,只會新增一列資料:

import {openDB} from 'idb';

async function addItemToStore () {
  const db = await openDB('example-database', 1);

  await db.add('storeName', {
    field: 'data'
  });
}

addItemToStore();

每次 add() 呼叫都會在交易中發生,因此即使承諾解析 但這不表示作業成功。為確保 執行新增作業後,您必須檢查整個 交易已透過 transaction.done() 方法完成。這是 保證會在交易自行完成時解析,如果 交易錯誤。您必須對所有「寫入」執行這項檢查作業 因為這是得知資料庫變更的唯一方法 。

以下程式碼顯示如何在交易中使用 add() 方法:

import {openDB} from 'idb';

async function addItemsToStore () {
  const db = await openDB('test-db4', 1, {
    upgrade (db) {
      if (!db.objectStoreNames.contains('foods')) {
        db.createObjectStore('foods', { keyPath: 'name' });
      }
    }
  });
  
  // Create a transaction on the 'foods' store in read/write mode:
  const tx = db.transaction('foods', 'readwrite');

  // Add multiple items to the 'foods' store in a single transaction:
  await Promise.all([
    tx.store.add({
      name: 'Sandwich',
      price: 4.99,
      description: 'A very tasty sandwich!',
      created: new Date().getTime(),
    }),
    tx.store.add({
      name: 'Eggs',
      price: 2.99,
      description: 'Some nice eggs you can cook up!',
      created: new Date().getTime(),
    }),
    tx.done
  ]);
}

addItemsToStore();

開啟資料庫後 (並視需要建立物件儲存庫),您需要 對應用程式呼叫 transaction() 方法,即可開啟交易。這個方法 表示您想交易的商店和交通方式 在這個範例中,我們要寫入商店 會指定 'readwrite'

下一步是開始在交易中新增商品。 在上述範例中,我們要處理 'foods' 上的三項作業 例如:

  1. 新增美味三明治的記錄。
  2. 正在新增幾顆能量蛋的記錄。
  3. 表示交易已完成 (tx.done)。

由於所有這些行動都是以承諾為基礎,因此需要等待 以完成這些步驟將這些承諾傳遞至 Promise.all敬上 是符合人體工學的 好方法Promise.all 可接受 保證並結束之後。

針對要新增的兩筆記錄,交易例項的 store 介面 呼叫 add() 並將資料傳遞至該函式。你可以awaitPromise.all通話 這項作業會在交易完成時結束

讀取資料

如要讀取資料,請呼叫 get() 方法是使用 openDB() 方法擷取。 get() 會使用商店的名稱,以及所建立物件的主鍵值 要擷取的內容基本範例如下:

import {openDB} from 'idb';

async function getItemFromStore () {
  const db = await openDB('example-database', 1);

  // Get a value from the object store by its primary key value:
  const value = await db.get('storeName', 'unique-primary-key-value');
}

getItemFromStore();

add() 一樣,get() 方法會傳回承諾值,因此您可以 await 您也可以使用承諾的 .then() 回呼。

以下範例在 'test-db4' 資料庫的get() 'foods' 物件儲存庫,透過 'name' 主鍵取得單一資料列:

import {openDB} from 'idb';

async function getItemFromStore () {
  const db = await openDB('test-db4', 1);
  const value = await db.get('foods', 'Sandwich');

  console.dir(value);
}

getItemFromStore();

從資料庫擷取單一資料列的方法非常簡單:開放 並指定該資料列的物件儲存庫和主鍵值 從中取得資料get() 方法會傳回承諾值,因此您可以 await

更新資料

如要更新資料,請呼叫 put() 方法。put() 方法與 add() 方法類似 也可以取代 add(),藉此建立資料。以下舉例說明 根據主鍵值,使用 put() 更新物件儲存庫中的資料列:

import {openDB} from 'idb';

async function updateItemInStore () {
  const db = await openDB('example-database', 1);

  // Update a value from in an object store with an inline key:
  await db.put('storeName', { inlineKeyName: 'newValue' });

  // Update a value from in an object store with an out-of-line key.
  // In this case, the out-of-line key value is 1, which is the
  // auto-incremented value.
  await db.put('otherStoreName', { field: 'value' }, 1);
}

updateItemInStore();

與其他方法一樣,這個方法會傳回承諾值。你也可以將 put() 用於以下用途: 交易的一部分以下是使用舊版 'foods' 商店的範例 更新三明治和雞蛋的價格:

import {openDB} from 'idb';

async function updateItemsInStore () {
  const db = await openDB('test-db4', 1);
  
  // Create a transaction on the 'foods' store in read/write mode:
  const tx = db.transaction('foods', 'readwrite');

  // Update multiple items in the 'foods' store in a single transaction:
  await Promise.all([
    tx.store.put({
      name: 'Sandwich',
      price: 5.99,
      description: 'A MORE tasty sandwich!',
      updated: new Date().getTime() // This creates a new field
    }),
    tx.store.put({
      name: 'Eggs',
      price: 3.99,
      description: 'Some even NICER eggs you can cook up!',
      updated: new Date().getTime() // This creates a new field
    }),
    tx.done
  ]);
}

updateItemsInStore();

項目更新方式取決於您設定金鑰的方式。如果您設定了 keyPath, 物件儲存庫中的每個資料列都會與一個內嵌鍵建立關聯。上述 範例會根據這個鍵更新資料列 在此情況下,您將需要指定該鍵,以更新 GRU 狀態中的 物件儲存空間你也可以建立脫行金鑰 autoIncrement 做為主鍵。

刪除資料

如要刪除資料,請呼叫 delete() 方法:

import {openDB} from 'idb';

async function deleteItemFromStore () {
  const db = await openDB('example-database', 1);

  // Delete a value 
  await db.delete('storeName', 'primary-key-value');
}

deleteItemFromStore();

add()put() 一樣,您可以在交易中使用以下內容:

import {openDB} from 'idb';

async function deleteItemsFromStore () {
  const db = await openDB('test-db4', 1);
  
  // Create a transaction on the 'foods' store in read/write mode:
  const tx = db.transaction('foods', 'readwrite');

  // Delete multiple items from the 'foods' store in a single transaction:
  await Promise.all([
    tx.store.delete('Sandwich'),
    tx.store.delete('Eggs'),
    tx.done
  ]);
}

deleteItemsFromStore();

資料庫互動的結構與其他 作業。別忘了,請按照下列步驟檢查整筆交易 包括您傳遞給 Promise.all 的陣列中 tx.done 方法。

取得所有資料

到目前為止,您一次只能從商店擷取一個物件。你也可以 使用 getAll() 方法或遊標。

getAll() 方法

如要擷取物件儲存庫的所有資料,最簡單的方法是呼叫 getAll() ,如下所示:

import {openDB} from 'idb';

async function getAllItemsFromStore () {
  const db = await openDB('test-db4', 1);

  // Get all values from the designated object store:
  const allValues = await db.getAll('storeName');

  console.dir(allValues);
}

getAllItemsFromStore();

這個方法會傳回物件儲存庫中的所有物件,但沒有限制 隨便啦這是從物件儲存庫中取得所有值最直接的方式 同時也缺乏彈性

import {openDB} from 'idb';

async function getAllItemsFromStore () {
  const db = await openDB('test-db4', 1);

  // Get all values from the designated object store:
  const allValues = await db.getAll('foods');

  console.dir(allValues);
}

getAllItemsFromStore();

本範例會在 'foods' 物件儲存庫上呼叫 getAll()。這會傳回 來自 'foods' 的物件,依主鍵排序。

如何使用遊標

遊標是更靈活的擷取多個物件方法。遊標選取 或逐一建立索引 以及這些資料遊標與其他資料庫作業一樣 做為交易基礎

如要建立遊標,請呼叫 openCursor() 作為交易的一部分從以下位置使用 'foods' 商店: 先前的例子,這就是如何將遊標移到 物件儲存庫則:

import {openDB} from 'idb';

async function getAllItemsFromStoreWithCursor () {
  const db = await openDB('test-db4', 1);
  const tx = await db.transaction('foods', 'readonly');

  // Open a cursor on the designated object store:
  let cursor = await tx.store.openCursor();

  // Iterate on the cursor, row by row:
  while (cursor) {
    // Show the data in the row at the current cursor position:
    console.log(cursor.key, cursor.value);

    // Advance the cursor to the next row:
    cursor = await cursor.continue();
  }
}

getAllItemsFromStoreWithCursor();

在此情況下,交易會以 'readonly' 模式開啟, 系統會呼叫 openCursor 方法。在後續的 while 迴圈中, 遊標目前位置可以讀取其 keyvalue 屬性,以及 還是能以最合理的方式 應用程式。準備就緒後,即可呼叫 cursor 物件的 continue() 方法前往下一列,而 while 迴圈會在遊標時終止 輸出到資料集結尾

使用含有範圍和索引的遊標

索引可讓您以非 主鍵。您可以在任何屬性 (成為 keyPath 的屬性) 建立索引 為索引指定範圍,然後在 使用 getAll() 或遊標的範圍。

請使用 IDBKeyRange 物件定義範圍。和下列任一條件 方法:

upperBound()lowerBound() 方法會指定上限與下限 範圍內

IDBKeyRange.lowerBound(indexKey);

或:

IDBKeyRange.upperBound(indexKey);

每個引數都會擷取一個引數:所需項目的索引 keyPath 值 來指定上限或下限

bound() 方法會指定上限與下限:

IDBKeyRange.bound(lowerIndexKey, upperIndexKey);

根據預設,這些函式的範圍包含 指定為範圍上限的資料如果不想看到這些值 將 true 做為第二個引數傳遞,即可將範圍指定為「專屬」lowerBound()upperBound(),或是 bound(),分別適用於下限和上限。

下一個範例使用 'foods' 物件中 'price' 屬性的索引 也就是經過處理且會導入模型的資料 接著再透過特徵儲存庫與他人分享商店現在還附加了表單,其中包含了 目標範圍使用以下程式碼尋找含有 並設定下列價格:

import {openDB} from 'idb';

async function searchItems (lower, upper) {
  if (!lower === '' && upper === '') {
    return;
  }

  let range;

  if (lower !== '' && upper !== '') {
    range = IDBKeyRange.bound(lower, upper);
  } else if (lower === '') {
    range = IDBKeyRange.upperBound(upper);
  } else {
    range = IDBKeyRange.lowerBound(lower);
  }

  const db = await openDB('test-db4', 1);
  const tx = await db.transaction('foods', 'readonly');
  const index = tx.store.index('price');

  // Open a cursor on the designated object store:
  let cursor = await index.openCursor(range);

  if (!cursor) {
    return;
  }

  // Iterate on the cursor, row by row:
  while (cursor) {
    // Show the data in the row at the current cursor position:
    console.log(cursor.key, cursor.value);

    // Advance the cursor to the next row:
    cursor = await cursor.continue();
  }
}

// Get items priced between one and four dollars:
searchItems(1.00, 4.00);

程式碼範例會先取得上限的值,並檢查是否存在限制 個值。下一個程式碼區塊會決定要使用哪種方法限制 做出決定在資料庫互動中,開啟 接著,在物件儲存庫中開啟 'price' 索引。 'price' 索引可讓您按價格搜尋商品。

接著,程式碼會在索引上開啟遊標,並傳入該範圍。遊標 會傳回代表範圍內第一個物件的保證;如果傳回,則傳回 undefined 這個範圍內沒有任何資料cursor.continue() 方法會傳回 並持續不斷地循環顯示,直到進入下一個物件 達到範圍結尾處

資料庫版本管理

呼叫 openDB() 方法時,您可以指定資料庫版本號碼 。在本指南的所有示例中,版本都採用 設為 1,但如果需要將資料庫升級至新版本 以某種方式進行修改如果指定的版本大於 現有資料庫,而事件物件中的 upgrade 回呼會執行。 可讓您在資料庫中加入新的物件儲存庫與索引。

upgrade 回呼中的 db 物件具有特殊的 oldVersion 屬性。 ,指出瀏覽器可存取的資料庫版本號碼。 您可以將此版本號碼傳遞至 switch 陳述式,以執行 會因現有的資料庫版本 而在 upgrade 回呼中 號碼。範例如下:

import {openDB} from 'idb';

const db = await openDB('example-database', 2, {
  upgrade (db, oldVersion) {
    switch (oldVersion) {
      case 0:
        // Create first object store:
        db.createObjectStore('store', { keyPath: 'name' });

      case 1:
        // Get the original object store, and create an index on it:
        const tx = await db.transaction('store', 'readwrite');
        tx.store.createIndex('name', 'name');
    }
  }
});

以下範例會將資料庫的最新版本設定為 2。當此代碼 瀏覽器尚未有資料庫,因此 oldVersion0switch 陳述式從 case 0 開始。在這個範例中 並將 'store' 物件儲存庫新增至資料庫。

重點:在 switch 陳述式中,每個 case 後面通常都有 break 但這不是這裡的用意 這樣一來 資料庫落後數個版本;如果找不到,程式碼會繼續執行 直到更新到 case 為止。在這個範例中 瀏覽器會繼續透過 case 1 建立 name 索引, store 物件儲存庫。

如要在 'store' 物件儲存庫中建立 'description' 索引,請更新 並新增 case 區塊,如下所示:

import {openDB} from 'idb';

const db = await openDB('example-database', 3, {
  upgrade (db, oldVersion) {
    switch (oldVersion) {
      case 0:
        // Create first object store:
        db.createObjectStore('store', { keyPath: 'name' });

      case 1:
        // Get the original object store, and create an index on it:
        const tx = await db.transaction('store', 'readwrite');
        tx.store.createIndex('name', 'name');

      case 2:
        const tx = await db.transaction('store', 'readwrite');
        tx.store.createIndex('description', 'description');
    }
  }
});

如果您在前一個範例中建立的資料庫仍存在瀏覽器中, 當系統執行此項目時,oldVersion2。瀏覽器會略過 case 0case 1,並執行 case 2 中的程式碼,藉此建立 description 索引。之後,瀏覽器的資料庫位於第 3 版,且內含 store 擁有 namedescription 索引的物件儲存庫。

延伸閱讀

下列資源提供使用 IndexedDB 的更多資訊和背景資訊。

索引資料庫說明文件

資料儲存限制