您当前的位置:首页 > 电脑百科 > 程序开发 > 编程百科

IndexedDB 是什么

时间:2019-10-14 13:12:39  来源:  作者:

在现代浏览器的本地存储方案中,indexedDB 是一项重要的能力组成, 它是可以在浏览器端使用的本地数据库,可以存储大量数据,提供接口来查询,还可以建立索引,这些都是其他存储方案 Cookie 或者 LocalStorage 无法提供的能力。单从数据库类型来看,IndexedDB 是一个非关系型数据库(不支持通过 SQL 语句操作)。

IndexedDB 的主要概念

IndexedDB 是一个比较复杂的 API 组合,学习它的过程就相当于学习它的各个对象 API 接口,包括以下这些( IDB 指当前操作的数据库实例 ):

  • 数据库:IDBDatabase 对象
  • 仓库对象: IDBObjectStore 对象
  • 索引:IDBIndex 对象
  • 事务:IDBTransaction 对象
  • 操作请求:IDBRequest 对象
  • 指针:IDBCursor 对象
  • 主键:IDBKeyRange 对象

在这些 API 中包含一些主要概念:

  • 数据库:数据库是所有相关数据的基本容器。在同源策略( 协议 + 域名 + 端口 )的前提下,每个域名下可以新建任意多的数据库。IndexedDB 中有版本概念,这就规定了同一时刻下只有一个版本的数据库存在。
  • 对象仓库:对象仓库 ObjectStore 在 IndexedDB 中对应的是 MySQL 中的表 Table。
  • 数据:对象仓库中记录的是若干条数据,数据只有主键和数据体两个部分,主键不能重复,可以为自增的整数编号或者数据中指定的一个属性。数据体可以是任意数据类型,不限于对象。
  • 索引:为不同的属性建立索引可以加快数据的检索。
  • 事务:数据的 CURD (增删查改) 都要通过事务来完成。

通过简单的对比图来理解 IndexedDB 的概念:

IndexedDB 是什么

 

快速起步 IndexedDB

在介绍了 IndexedDB 的主要概念之后,可以通过一个简单实用的 CURD 例子来学习在日常开发中我们是怎么使用 IndexedDB 的,各个 API 细节日后可以慢慢深入学习。

  1. 必不可少的浏览器支持检查:
if(!('indexedDB' in window)){
 console.log('当前浏览器支持 IndexedDB');
 return;
} else {
 console.log('您的浏览器不支持 IndexedDB')
 // todo 建议升级或者更换其他浏览器
}
  1. 连接数据库
// 数据库实例
let db;
// 数据库打开操作,第一个参数是数据库名称, 第二个参数是数据库版本
let DBRequestLink = window.indexedDB.open('dataBaseName', 1)
DBRequestLink.onsuccess = function(event) {
 // 获取数据库实例
 db = DBRequestLink.result;
 // 其他操作
};
// 这个监听回调触发于数据库首次新建、open数据库时传递新版本(只能比之前传递的版本高)
DBRequestLink.onupgradeneeded = function(event) {};
  1. 创建数据库的主键和字段
DBOpenRequest.onupgradeneeded = function(event) {
 let db = event.target.result;
 // 创建一个数据库存储对象,并指定主键
 let objectStore = db.createObjectStore('person', { 
 keyPath: 'id',
 autoIncrement: true
 });
 /* 定义存储对象的数据项 
 * 第一个参数是创建的索引名称,可以为空
 * 第二个参数是索引使用的关键名称,可以为空
 * 第三个参数是可选配置参数,可以不传,常用参数之一就是 unique ,表示该字段是否唯一,不能重复
 */ 
 objectStore.createIndex('id', 'id', {
 unique: true 
 });
 objectStore.createIndex('name', 'name');
 objectStore.createIndex('age', 'age');
 objectStore.createIndex('sex', 'sex');
};
  1. 在上述操作中,我们先定义了上文中提到的 IDBObjectStore 对象,并指定主键为 id ,随后又通过 createIndex 来创建字段。值得注意的是虽然创建了四个字段,但在 IndexedDb 中数据还是分为主键 id 和数据主体两个部分,并不会像 MYSQL 中在 Table 中呈现四列。
  2. 向数据库中添加数据
// 这里的 db 就是第二步中的 db 对象, 
// transaction api 的第一个参数是数据库名称,第二个参数是操作类型
let newItem = {
 id: 1,
 name: '徐嘻嘻',
 age: 3,
 sex: 'female'
};
let transaction = db.transaction('dataBaseName', "readwrite");
// 找到对应的存储对象
let objectStore = transaction.objectStore('person');
// 添加到数据对象中, 传入JAVAscript对象
objectStore.add(newItem);
  1. 新建操作是在新建了一个 事务( IDBTransaction 对象)的前提下完成的,传入的数据不需要做任何转换,可以无缝传入 JavaScript 对象。
  2. 修改数据库中的数据
// 这里的 db 就是第二步中的 db 对象, 
// 新建事务
let transaction = db.transaction('dataBaseName', "readwrite");
// 新数据主体
let newRecord = {
 id: 1,
 name: '徐嘎嘎',
 age: 5,
 sex: 'male'
};
// 打开已经存储的数据对象
let objectStore = transaction.objectStore('person');
// 获取存储的对应键的存储对象, 传入主键 id,值为 1 
let objectStoreRequest = objectStore.get(1);
// 获取成功后替换当前数据
objectStoreRequest.onsuccess = function(event) {
 // 数据
 var record = objectStoreRequest.result;
 // 遍历替换
 for (let key in newRecord) {
 if (typeof record[key] != 'undefined' || key !== 'id') {
 record[key] = newRecord[key];
 }
 }
 // 更新数据库存储数据 
 objectStore.put(record);
};
  1. 基本思路是创建一个事务,先找到想要修改的数据主体,然后在更新该数据主体内容。 事务创建逻辑相同,并在创建之后调用事务的 get 和 put 操作。
  2. 删除数据库中的数据
// 这里的 db 就是第二步中的 db 对象, 
// 新建事务
let transaction = db.transaction('dataBaseName', "readwrite");
// 打开已经存储的数据对象
let objectStore = transaction.objectStore('person');
// 获取存储的对应键的存储对象, 传入主键 id,值为 1 
let objectStoreRequest = objectStore.delete(1);
  1. 调用 delete 接口,传入指定的 id 即可。

可以提效的类库

​ 从上面的例子中可以看出,每一次操作需要至少三行代码才能完成,而且需要一直维护 DB 的对象引用,避免它被回收,这样子开发代码膨胀得太厉害,所以我们在业务中引入其他类库来减少代码量

  • LocalForage
  • 可以指定数据存储方案,默认依次为 IndexedDB、WebSQL、LocalStorage,意味着当前 IndexedDB 失效可以有兜底措施。
  • API 简化为 CRUD ( getItem、removeItem、setItem、clear )
  • 库大小为 475b
  • Pouchdb
  • API 简化为 put、get、remove,基于 promise 来检查回收错误
  • 有较好的错误日志机制, 如失败,冲突等等,方便调试
  • 库大小为 255b

这两个类库比较符合我们的开发要求,我们当前使用的是 LocalForage。

结束语

在业务开发中,我们都会碰到或多或少的本地存储需求,本文介绍了其中一种存储方案 IndexedDB 的简单实践。就我们的应用场景来看,IndexedDB 的适用面还是很广的。考虑到 IE10 也可以支持,把它实践在实际项目中应该是没有问题的。

文章首发于:https://www.zoo.team/article/indexeddb



Tags:IndexedDB   点击:()  评论:()
声明:本站部分内容及图片来自互联网,转载是出于传递更多信息之目的,内容观点仅代表作者本人,如有任何标注错误或版权侵犯请与我们联系(Email:2595517585@qq.com),我们将及时更正、删除,谢谢。
▌相关推荐
在现代浏览器的本地存储方案中,indexedDB 是一项重要的能力组成, 它是可以在浏览器端使用的本地数据库,可以存储大量数据,提供接口来查询,还可以建立索引,这些都是其他存储方案 Co...【详细内容】
2019-10-14  Tags: IndexedDB  点击:(194)  评论:(0)  加入收藏
▌简易百科推荐
本文分为三个等级自顶向下地分析了glibc中内存分配与回收的过程。本文不过度关注细节,因此只是分别从arena层次、bin层次、chunk层次进行图解,而不涉及有关指针的具体操作。前...【详细内容】
2021-12-28  linux技术栈    Tags:glibc   点击:(3)  评论:(0)  加入收藏
摘 要 (OF作品展示)OF之前介绍了用python实现数据可视化、数据分析及一些小项目,但基本都是后端的知识。想要做一个好看的可视化大屏,我们还要学一些前端的知识(vue),网上有很多比...【详细内容】
2021-12-27  项目与数据管理    Tags:Vue   点击:(2)  评论:(0)  加入收藏
程序是如何被执行的  程序是如何被执行的?许多开发者可能也没法回答这个问题,大多数人更注重的是如何编写程序,却不会太注意编写好的程序是如何被运行,这并不是一个好...【详细内容】
2021-12-23  IT学习日记    Tags:程序   点击:(9)  评论:(0)  加入收藏
阅读收获✔️1. 了解单点登录实现原理✔️2. 掌握快速使用xxl-sso接入单点登录功能一、早期的多系统登录解决方案 单系统登录解决方案的核心是cookie,cookie携带会话id在浏览器...【详细内容】
2021-12-23  程序yuan    Tags:单点登录(   点击:(8)  评论:(0)  加入收藏
下载Eclipse RCP IDE如果你电脑上还没有安装Eclipse,那么请到这里下载对应版本的软件进行安装。具体的安装步骤就不在这赘述了。创建第一个标准Eclipse RCP应用(总共分为六步)1...【详细内容】
2021-12-22  阿福ChrisYuan    Tags:RCP应用   点击:(7)  评论:(0)  加入收藏
今天想简单聊一聊 Token 的 Value Capture,就是币的价值问题。首先说明啊,这个话题包含的内容非常之光,Token 的经济学设计也可以包含诸多问题,所以几乎不可能把这个问题说的清...【详细内容】
2021-12-21  唐少华TSH    Tags:Token   点击:(10)  评论:(0)  加入收藏
实现效果:假如有10条数据,分组展示,默认在当前页面展示4个,点击换一批,从第5个开始继续展示,到最后一组,再重新返回到第一组 data() { return { qList: [], //处理后...【详细内容】
2021-12-17  Mason程    Tags:VUE   点击:(14)  评论:(0)  加入收藏
什么是性能调优?(what) 为什么需要性能调优?(why) 什么时候需要性能调优?(when) 什么地方需要性能调优?(where) 什么时候来进行性能调优?(who) 怎么样进行性能调优?(How) 硬件配...【详细内容】
2021-12-16  软件测试小p    Tags:性能调优   点击:(20)  评论:(0)  加入收藏
Tasker 是一款适用于 Android 设备的高级自动化应用,它可以通过脚本让重复性的操作自动运行,提高效率。 不知道从哪里听说的抖音 app 会导致 OLED 屏幕烧屏。于是就现学现卖,自...【详细内容】
2021-12-15  ITBang    Tags:抖音防烧屏   点击:(25)  评论:(0)  加入收藏
11 月 23 日,Rust Moderation Team(审核团队)在 GitHub 上发布了辞职公告,即刻生效。根据公告,审核团队集体辞职是为了抗议 Rust 核心团队(Core team)在执行社区行为准则和标准上...【详细内容】
2021-12-15  InfoQ    Tags:Rust   点击:(25)  评论:(0)  加入收藏
相关文章
    无相关信息
最新更新
栏目热门
栏目头条