IndexedDB 中的 index 是按非主键字段查询的唯一机制,objectStore.get() 仅支持主键查找;建索引需用 createIndex("name", "keyPath", { unique, multiEntry }),且必须在 onupgradeneeded 中配合版本升级操作。

IndexedDB 中的 index 是什么,为什么不能直接用 objectStore.get()?
索引(index)不是“加速查询的可选插件”,而是 IndexedDB 唯一支持按非主键字段查数据的机制。如果你建了一个 objectStore,主键是 id,但想按 email 或 status 查用户,objectStore.get() 完全无效——它只认主键。必须先在 email 字段上建 index,再用 index.get()。
createIndex() 的三个参数怎么填才不报错?
调用 objectStore.createIndex() 时最容易卡在第二个参数(keyPath)和第三个参数(options)。常见错误包括:keyPath 写成对象属性访问表达式(如 "user.email")、unique 设为 true 却没确保数据唯一、漏传 options 导致默认不支持多值索引。
-
keyPath必须是字符串,且只能是对象顶层字段名(如"email"),不支持嵌套路径("profile.name"会静默失败) - 如果字段可能为数组(例如
tags: ["a", "b"]),需显式传{ multiEntry: true },否则只索引第一个元素 -
unique: true仅在升级版本号(onupgradeneeded)中生效;已有重复数据时建唯一索引会直接抛AbortError
示例:
const store = db.createObjectStore("users", { keyPath: "id" });
store.createIndex("by_email", "email", { unique: true }); // ✅
store.createIndex("by_tags", "tags", { multiEntry: true }); // ✅ 支持数组字段
什么时候该用 index.openCursor() 而不是 index.get()?
index.get() 只返回**第一个匹配项**,哪怕你预期有多个;而 index.openCursor() 才是真正做范围查询、遍历、分页的入口。比如查所有 status === "active" 的用户,必须用游标。
生成可在 deepbi 沙箱 iframe 内运行或作为独立文件运行的交互式 HTML 页面,使用 `window.deepbi` JS SDK 实现数据查询、空间管理、文件浏览及用户操作。当用户提出以下需求时启用该能力: - 创建 KPI 仪表盘、数据表格、文件浏览器、成员列表、管理页面; - 明确要求“转成 dhtml”、“转译成 HTML”、“把 XX 页面转成……”、“控制台页面”、“管理后台”、“DeepBI 页面迁移”; - 提及位于 `apps/console/src/featur
立即学习“前端免费学习笔记(深入)”;
-
index.get("active")→ 返回第一个status: "active"的记录,其余忽略 -
index.openCursor(IDBKeyRange.only("active"))→ 遍历全部匹配项 - 要查
email以"test@"开头的?用IDBKeyRange.bound("test@", "test@~"),然后配openCursor() - 注意:游标默认正向;反向加
{ direction: "prev" }
删除或重建 index 为什么总失败?
IndexedDB 的 index 不能单独删——必须在 onupgradeneeded 中,通过 objectStore.deleteIndex("name") 操作,且数据库版本号必须递增。直接在已打开的 DB 实例上调用会静默无效,甚至引发事务 abort。
- 想改索引结构(比如从非唯一变唯一)?必须先
deleteIndex(),再createIndex(),都在同一个onupgradeneeded回调里 - 版本号不变,
onupgradeneeded根本不会触发 → 索引操作被跳过 - 已有大量数据时,重建索引会阻塞主线程;大表建议在 Worker 中做迁移,或分批处理
关键点就一句:索引变更永远绑定版本升级,没有捷径。


















