首页/新闻资讯/正文详情

IndexedDB 本地数据库

发布时间:2026/9/25 18:35:19 来源:云帆数科 栏目:资讯中心
IndexedDB 本地数据库
5.4 IndexedDB 本地数据库IndexedDB 是浏览器原生提供的事务型结构化本地数据库专为解决 Web Storage 容量上限低、仅支持字符串存储、查询能力弱的问题。它支持大容量存储、索引查询、事务处理能够存储海量结构化业务数据与二进制资源是复杂离线应用、大数据本地缓存的核心存储方案。5.4.1 核心概念与基础操作一、核心特性大容量存储单域名存储上限通常在 50MB ~ 数百MB 级别远高于 Web Storage 的 5MB支持存储文件、二进制大对象。结构化存储以键值对形式存储 JavaScript 对象、数组、二进制数据等无需手动序列化支持嵌套数据结构。异步非阻塞所有操作均为异步事件驱动基于回调执行不会阻塞主线程避免大数据量操作导致页面卡顿。事务型保证所有数据操作都在事务中执行具备原子性、一致性操作失败自动回滚保证数据完整性。索引与查询支持创建多字段索引通过索引实现高效条件查询支持游标遍历与范围筛选。同源隔离严格遵循同源策略不同站点无法访问对方的数据库保障数据安全。二、核心概念IndexedDB 概念类比关系型数据库含义说明Database数据库数据库实例独立的存储单元通过名称唯一标识支持多版本管理Object Store对象仓库数据表数据存储的集合存储键值对记录每个仓库对应一类业务数据Index索引索引基于对象仓库的字段创建用于加速条件查询支持唯一约束Transaction事务事务数据操作的执行单元所有读写都必须在事务中进行分为只读/读写两种模式Cursor游标遍历指针用于逐条遍历对象仓库或索引中的数据支持范围筛选与增量读取三、基础操作语法1. 打开/创建数据库通过indexedDB.open(dbName, version)打开数据库若数据库不存在则自动创建版本号提升时触发升级事件。 数据库结构的修改创建仓库、创建索引只能在upgradeneeded事件中执行这是 IndexedDB 版本管理的核心机制。// 打开名为 UserDB 的数据库版本号为 1 const request indexedDB.open(UserDB, 1); let db null; // 数据库升级时触发首次创建、版本号提升 request.onupgradeneeded function(e) { db e.target.result; // 创建对象仓库相当于表指定主键为 id const userStore db.createObjectStore(users, { keyPath: id }); // 创建索引按用户名查询唯一索引 userStore.createIndex(name, name, { unique: true }); // 创建索引按年龄查询非唯一索引 userStore.createIndex(age, age, { unique: false }); }; // 数据库打开成功 request.onsuccess function(e) { db e.target.result; console.log(数据库初始化完成); }; // 数据库打开失败 request.onerror function(e) { console.error(数据库打开失败, e.target.error.message); };2. 新增数据使用readwrite模式的事务add()方法用于纯新增主键重复会抛出错误put()方法为「新增或覆盖更新」主键存在则更新、不存在则新增。function addUser(user) { // 创建读写事务指定操作的仓库 const transaction db.transaction([users], readwrite); // 获取对象仓库实例 const store transaction.objectStore(users); // 执行新增操作 const request store.add(user); request.onsuccess () console.log(用户新增成功); request.onerror () console.error(用户新增失败); } // 调用示例 addUser({ id: 1, name: zhangsan, age: 25, city: beijing });3. 查询数据主键查询get(key) 按主键获取单条数据全量查询getAll() 获取仓库中所有数据索引查询通过索引对象按指定字段快速查询// 1. 按主键查询单条数据 function getUserById(id) { const transaction db.transaction([users], readonly); const store transaction.objectStore(users); const request store.get(id); request.onsuccess () { console.log(查询结果, request.result); }; } // 2. 按索引查询 function getUserByName(name) { const transaction db.transaction([users], readonly); const store transaction.objectStore(users); const nameIndex store.index(name); // 获取索引对象 const request nameIndex.get(name); request.onsuccess () { console.log(按名称查询结果, request.result); }; }4. 更新与删除// 更新数据put 方法主键存在则覆盖更新 function updateUser(user) { const transaction db.transaction([users], readwrite); const store transaction.objectStore(users); store.put(user); } // 按主键删除单条数据 function deleteUser(id) { const transaction db.transaction([users], readwrite); const store transaction.objectStore(users); store.delete(id); } // 清空仓库所有数据 function clearAllUsers() { const transaction db.transaction([users], readwrite); const store transaction.objectStore(users); store.clear(); }5. 游标遍历适合大批量数据遍历、范围查询场景避免一次性加载全部数据到内存支持增量处理。function traverseAllUsers() { const transaction db.transaction([users], readonly); const store transaction.objectStore(users); const request store.openCursor(); // 打开游标 request.onsuccess function(e) { const cursor e.target.result; if (cursor) { console.log(当前记录, cursor.value); cursor.continue(); // 移动到下一条 } else { console.log(遍历完成); } }; }5.4.2 常用封装思路原生 IndexedDB API 基于事件回调写法繁琐、容易形成回调地狱且版本管理、错误处理分散。实际项目中通常会进行分层封装简化调用方式统一管理底层逻辑。一、封装核心目标回调 Promise 化将事件回调转为 Promise支持 async/await 语法大幅提升代码可读性与可维护性。接口简化屏蔽事务、请求对象等底层概念对外提供简洁的增删改查业务方法。统一管理集中处理数据库打开、版本升级、错误捕获、事务生命周期管理。二、基础 Promise 封装最轻量化的封装将单次操作包装为 Promise适合简单业务场景快速接入。// 封装打开数据库 function openDB(dbName, version, onUpgrade) { return new Promise((resolve, reject) { const request indexedDB.open(dbName, version); request.onupgradeneeded e onUpgrade(e.target.result); request.onsuccess e resolve(e.target.result); request.onerror e reject(e.target.error); }); } // 封装新增操作 function addItem(db, storeName, data) { return new Promise((resolve, reject) { const transaction db.transaction([storeName], readwrite); const store transaction.objectStore(storeName); const request store.add(data); request.onsuccess () resolve(request.result); request.onerror () reject(request.error); }); } // 使用示例 async function demo() { const db await openDB(DemoDB, 1, (db) { // 升级回调中创建仓库 db.createObjectStore(items, { keyPath: id }); }); await addItem(db, items, { id: 1, title: 测试数据 }); }三、类式封装将数据库操作封装为独立工具类统一管理数据库实例、配置与生命周期是中型项目的主流方案。class IndexedDBHelper { constructor(dbName, version, storesConfig) { this.dbName dbName; this.version version; this.storesConfig storesConfig; // 仓库配置名称、主键、索引 this.db null; } // 初始化数据库 init() { return new Promise((resolve, reject) { const request indexedDB.open(this.dbName, this.version); request.onupgradeneeded (e) { const db e.target.result; // 批量创建对象仓库与索引 this.storesConfig.forEach(config { if (!db.objectStoreNames.contains(config.name)) { const store db.createObjectStore(config.name, { keyPath: config.keyPath }); config.indexes?.forEach(idx { store.createIndex(idx.name, idx.field, { unique: idx.unique || false }); }); } }); }; request.onsuccess (e) { this.db e.target.result; resolve(this); }; request.onerror (e) reject(e.target.error); }); } // 新增数据 add(storeName, data) { return this._execute(storeName, readwrite, store store.add(data)); } // 按主键查询 get(storeName, key) { return this._execute(storeName, readonly, store store.get(key)); } // 通用事务执行方法统一封装 Promise _execute(storeName, mode, handler) { return new Promise((resolve, reject) { const transaction this.db.transaction([storeName], mode); const store transaction.objectStore(storeName); const request handler(store); request.onsuccess () resolve(request.result); request.onerror () reject(request.error); }); } } // 使用示例 const db new IndexedDBHelper(AppDB, 1, [ { name: users, keyPath: id, indexes: [{ name: name, field: name, unique: true }] } ]); db.init().then(async () { await db.add(users, { id: 1, name: lisi, age: 30 }); const user await db.get(users, 1); });四、开源库方案复杂项目推荐使用成熟的开源封装库避免重复造轮子Dexie.js最主流的 IndexedDB 封装库提供类似 MongoDB 的链式查询 API完整支持事务、索引、范围查询功能完善生态成熟。localForageAPI 风格与 Web Storage 高度一致简单易用自动降级适配 Web Storage、IndexedDB 等多种存储引擎适合简单的键值存储场景。五、适用场景与边界适用场景海量结构化业务数据存储、离线应用数据持久化、大文件/二进制数据本地缓存、复杂条件查询场景。不适用场景少量简单配置数据优先使用 localStorage强实时性的高频读写场景需注意异步开销。

相关推荐

动态 SQL 的 OGNL 求值陷阱:if、foreach 与 bind 在复杂参数下的正确写法与排障
动态 SQL 的 OGNL 求值陷阱:if、foreach 与 bind 在复杂参数下的正确写法与排障

动态 SQL 的 OGNL 求值陷阱&#xff1a;if、foreach 与 bind 在复杂参数下的正确写法与排障 1. 从一次线上报错说起 假设你写了一个按条件筛选订单的接口&#xff0c;Service 里组装了一个查询对象&#xff0c;Mapper 里用 <if test"status ! null and status ! "… · 2026/9/25 18:35:13

Linux进程间通信(二).匿名管道
Linux进程间通信(二).匿名管道

一.何谓管道?• 管道是Unix中最古⽼的进程间通信的形式。• 我们把从⼀个进程连接到另⼀个进程的⼀个数据流称为⼀个“管道”。二.匿名管道1.父子间通信的管道首先我们得记住&#xff0c;匿名管道通常用来做父子进程间的通信。父进程fork()子进程是浅拷贝&#xff0c;那么文件… · 2026/9/25 18:35:13

自动化变更风险评分模型:结合提交者资历与修改模块的综合评分
自动化变更风险评分模型:结合提交者资历与修改模块的综合评分

自动化变更风险评分模型&#xff1a;结合提交者资历与修改模块的综合评分在敏捷研发与持续集成的流水线中&#xff0c;代码审查&#xff08;Code Review&#xff09;常常陷入两难困境&#xff1a; 过度审查&#xff1a;修改一个文案或调整前端样式&#xff0c;也强制要求两位资… · 2026/9/25 18:35:01

长假自驾跑长途,除碳这事可以提前排期!
长假自驾跑长途,除碳这事可以提前排期!

每次长假自驾前&#xff0c;总能见到这么一类车友&#xff1a;头天晚上收拾行李到半夜&#xff0c;临了往油箱里怼一瓶除碳剂&#xff0c;拍着油箱说“兄弟&#xff0c;路上辛苦你了”。结果上了高速跑两百公里进服务区&#xff0c;才后知后觉&#xff1a;这玩意儿刚要起效&… · 2026/9/25 19:11:05

闲鱼超级管家系统源码下载
闲鱼超级管家系统源码下载

源码下载&#xff1a;download.csdn.net/download/m0_66047725/93483853 简介&#xff1a; 闲鱼超级管家全面升级新版本&#xff0c;自动滑块、发货、评价、要花、擦亮通通稳定支持&#xff0c;时刻维护&#xff01;时刻更新&#xff01;坚决保证使用世界上最强 AI模型(5.6 s… · 2026/9/25 19:10:59

Raven Agent Loop全解:Turn、Iteration、子代理与检查点回滚如何协同工作
Raven Agent Loop全解:Turn、Iteration、子代理与检查点回滚如何协同工作

Raven Agent Loop全解&#xff1a;Turn、Iteration、子代理与检查点回滚如何协同工作 【免费下载链接】Raven The Harness of Harnesses: a trusted, persistent, self-evolving multi-agent ecosystem for all-domain collaboration. 项目地址: https://gitcode.com/gh_mirr… · 2026/9/25 19:10:28

小白程序员轻松入门AI Agent开发工程师之路
小白程序员轻松入门AI Agent开发工程师之路

随着大语言模型(LLM)的发展,企业需要的是能可靠完成真实业务任务的AI Agent软件系统,催生了"AI Agent开发工程师"这一新岗位。文章拆解了该岗位所需的8大核心能力域,包括后端工程基础、Python工程能力、LLM API与Prompt、Agent Loop与Tool Use、RAG与知识库、Context… · 2026/9/25 19:10:28

点云预处理与特征计算:任务导向的工业级实践指南
点云预处理与特征计算:任务导向的工业级实践指南

1. 为什么点云预处理不是“清洗一下就完事”的体力活点云数据预处理和特征计算&#xff0c;这两个词在测绘、自动驾驶、工业检测、数字孪生这些领域里天天被提起&#xff0c;但绝大多数人一上手就栽在第一步——误以为它只是“把噪点删掉、把空洞补上、再导出个ply文件”这种标… · 2026/9/25 19:10:04

基于昇腾Atlas 300V 24G推理卡的YOLO模型部署与调优实践
基于昇腾Atlas 300V 24G推理卡的YOLO模型部署与调优实践

前阵子团队准备把一套基于YOLOv5的检测服务从GPU服务器迁移到昇腾Atlas上&#xff0c;群里讨论最多的一句话就是&#xff1a;“atlas 300v 24g是运算加速卡吗&#xff1f;”我当时也愣了一下。后来翻完产品文档、踩了一周坑&#xff0c;才算把这卡的脾气摸清楚。如果你也是第一… · 2026/9/25 19:09:58

数值优化(Numerical Optimization)学习系列-03-共轭梯度方法(Conjugate Gradient)
数值优化(Numerical Optimization)学习系列-03-共轭梯度方法(Conjugate Gradient)

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/25 1:00:31

创维E900V22D刷机全攻略:S905L3SB芯片兼容性解析与救砖实战
创维E900V22D刷机全攻略:S905L3SB芯片兼容性解析与救砖实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/25 1:00:31

MQTT协议原理与Broker服务器搭建实战:从Mosquitto到EMQX
MQTT协议原理与Broker服务器搭建实战:从Mosquitto到EMQX

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/25 1:00:37

了解更多?预约专属演示

我们的顾问将为您一对一讲解产品与方案

企业微信二维码