IndexedDB不支持真正的实时读取,其“实时”能力需通过事务、索引、游标及外部机制(如事件监听、Service Worker)协同模拟:①主键get()最快,毫秒级;②索引查询支持条件检索,须预先创建;③游标实现可控批量遍历;④变更通知依赖应用层主动触发。

IndexedDB 本身不提供“实时读取”能力,它本质是本地持久化存储,所有读取都是对当前数据库快照的访问。所谓“实时”,实际依赖开发者结合事务、索引、游标和外部机制(如事件监听、轮询或 Service Worker)来模拟。关键在于理解不同读取方式的适用场景与性能边界。
直接键值读取:最快、最确定
通过 get() 或 getKey() 按主键精确查找单条记录,是 IndexedDB 中响应最快、开销最小的读取方式。它跳过索引和遍历,直接定位数据块。
- 适用于已知唯一 ID 的场景,比如打开某封离线邮件、加载指定用户档案
- 主键必须严格匹配,不支持模糊、范围或条件组合
- 即使对象存储中数据量达百万级,单次
get()仍保持毫秒级延迟
索引查询:带条件的高效读取
当需要按非主键字段检索(如按邮箱查用户、按时间范围查日志),索引是唯一可行的高性能方案。它让 IndexedDB 支持类似 SQL 的 WHERE 查询语义。
- 必须提前在
upgradeneeded中为常用查询字段创建索引,例如:store.createIndex('byEmail', 'email', { unique: true }) - 使用
index.get()、index.getAll()或index.openCursor()触发索引查找 - 复合索引暂不原生支持,需靠多级索引或客户端过滤折中处理
游标遍历:可控批量读取
游标(IDBCursor)用于顺序或定向扫描对象存储或索引,适合分页加载、全量同步、数据迁移等场景。它不一次性拉取全部数据,而是逐条或按块推进。
-
openCursor()默认从头开始;可传入lowerBound/upperBound实现范围遍历 - 配合
cursor.continue()或cursor.advance(n)控制步进节奏,避免内存溢出 - 遍历时可修改或删除当前项(仅限 readwrite 事务),适合清洗旧数据
“伪实时”实现:靠外部协同而非数据库本身
IndexedDB 没有内置变更通知机制(如 Firebase 的 onSnapshot 或 WebSockets)。所谓“实时读取”,需由应用层主动构建:
- 写入端在完成事务后,主动 dispatch 自定义事件(如
new CustomEvent('db-updated', { detail: { store: 'logs', id: 123 } })),供监听方刷新视图 - 搭配 Service Worker,在后台监听网络状态变化,触发增量同步 + 本地数据重读
- 对高频更新场景,可引入轻量轮询(如每 5 秒检查版本号或时间戳字段),但应避免无差别全表扫描

















