请解释 IndexedDB 的作用和用法。如何使用 IndexedDB 存储和查询大量结构化数据?

推荐答案

IndexedDB 是浏览器提供的客户端本地存储数据库,它允许你存储大量的结构化数据,包括文件和二进制数据。与 localStorage 相比,IndexedDB 具有以下优势:

  • 存储容量大: 可以存储远超 localStorage 的数据量,通常受到浏览器可用磁盘空间的限制。
  • 事务支持: 支持事务,保证数据操作的原子性。
  • 索引支持: 允许你创建索引来高效地查询数据。
  • 异步 API: 所有操作都是异步的,不会阻塞主线程。

存储数据流程:

  1. 打开或创建数据库: 使用 indexedDB.open() 方法。
  2. 创建对象存储空间:onupgradeneeded 事件中创建对象存储空间 (object store) ,相当于表,并定义索引。
  3. 打开事务: 使用 db.transaction() 创建读写事务。
  4. 添加数据: 使用 objectStore.add()put() 方法添加数据。
  5. 提交事务: 事务自动提交或显式调用 transaction.commit()

查询数据流程:

  1. 打开数据库: 使用 indexedDB.open() 方法。
  2. 打开只读事务: 使用 db.transaction() 创建只读事务。
  3. 获取对象存储空间: 使用 transaction.objectStore() 获取对象存储空间。
  4. 使用索引或游标查询:
    • 使用索引: objectStore.index().get(), objectStore.index().getAll(), objectStore.index().openCursor() 等。
    • 使用游标: objectStore.openCursor(),遍历查询。

示例(简化):

-- -------------------- ---- -------
----- ------ - -------------
----- --------- - ----------------

-- --------
----- ------- - ---------------------- ---

----------------------- - ------- -- -
  ----- -- - --------------------
  ----- ----------- - ------------------------------- - -------- ----- -------------- ---- ---
    -- ----
  ------------------------------- ------- - ------- ----- ---
--


----------------- - ------- -- -
  ----- -- - --------------------

    -- ------
  -------- ------------- -
        ----- ----------- - ------------------------- -------------
        ----- ----------- - -----------------------------------
        ----------------------
        ----------------------- -- -- -
            ---------------------
        -
  -

    -- ------
  -------- --------------- -
    ----- ----------- - ------------------------- ------------
    ----- ----------- - -----------------------------------
    ----- ----- - --------------------------
    ----- ----- - -------------------

      --------------- - --- -- -
        ------------------- -----------------
      --
    -

  --------- ----- -------- ---- --- ---- -------- ---
  --------- ----- ------ ---- --- ---- ------ ---
    ------------------

--

--------------- - ------- -- -
  ------------------------ --------------------
--

本题详细解读

IndexedDB 作为浏览器端的一个 NoSQL 数据库,主要用于在客户端存储大量结构化数据,并且提供了事务支持和索引,可以帮助我们更好地管理数据。

IndexedDB 的核心概念

  1. 数据库 (Database): 一个 IndexedDB 数据库包含多个对象存储空间。
  2. 对象存储空间 (Object Store): 类似于关系数据库中的表,用于存储数据。每个对象存储空间都存储着一组带有键值对的数据。
  3. 索引 (Index): 在对象存储空间的基础上,创建的用于优化查询的索引。可以基于数据中的某些属性进行查询。
  4. 事务 (Transaction): 一系列数据库操作的集合,要么全部成功,要么全部失败,保证数据的一致性。
  5. 游标 (Cursor): 用于遍历数据,可以按照键或者索引遍历对象存储空间中的记录。

IndexedDB 的使用步骤

  1. 打开/创建数据库:

    • 使用 indexedDB.open(dbName, version) 方法打开数据库。如果数据库不存在,则会创建。
    • dbName 是数据库名称,version 是数据库版本。
    • onupgradeneeded 事件中,当数据库版本升级或首次创建时,进行对象存储空间的创建或更新。
  2. 添加数据:

    • 使用 db.transaction(storeName, 'readwrite') 方法创建一个读写事务。
    • 使用 transaction.objectStore(storeName) 获取对象存储空间。
    • 使用 objectStore.add(data)objectStore.put(data) 添加数据。
  3. 查询数据:

    • 使用 db.transaction(storeName, 'readonly') 创建只读事务。
    • 通过以下方式之一进行查询:
      • 使用索引:

      • 使用游标:

  4. 使用事务:

    • 事务可以保证一组操作的原子性,要么全部成功,要么全部失败。
    • 事务会自动提交。可以使用 transaction.commit() 显式提交事务。
    • 可以使用 transaction.abort() 中止事务。

存储和查询大量结构化数据

  1. 数据结构设计:

    • 合理设计对象存储空间的数据结构,选择合适的 keyPath 和索引。
    • 避免嵌套过深的数据结构,尽量扁平化。
  2. 使用索引:

    • 在需要快速查询的字段上创建索引,提高查询效率。
    • 根据查询场景选择合适的索引类型(唯一索引、多值索引)。
  3. 使用游标:

    • 对于大数据量的遍历,使用游标而不是 getAll 可以避免内存溢出。
    • 分批处理数据,避免一次性加载过多的数据。
  4. 数据分片:

    • 如果单个对象存储空间数据量过大,可以考虑将数据分片存储在不同的对象存储空间。
    • 可以按照时间、类型等维度进行分片。
  5. 异步操作:

    • IndexedDB 所有操作都是异步的,要使用 Promise 或者 async/await 处理异步结果。
    • 避免同步操作阻塞主线程。

总结

纠错
反馈