APP下载

实践 | Electron:使用IndexedDB

原创

Electron

在Electron应用场景下实践IndexedDB~

了解IndexedDB

  1. 什么是IndexedDB?

简单来说,就是浏览器提供的本地数据库,可以被网页脚本创建和操作。它是一种底层 API,用于在客户端存储大量的结构化数据(也包括文件/二进制大型对象(blobs))。

IndexedDB是一个事务型数据库系统,类似于基于 SQL 的 RDBMS。但就数据库类型而言,IndexedDB不属于关系型数据库(不支持SQL查询语句),更接近NoSQL数据库。

  1. 为什么需要IndexedDB?

当下,浏览器的功能越来越强大,一个真实的需求是:希望在客户端存储大量的数据,从而减少去服务器拉取数据,同时,允许大量数据可以被存储以供离线使用。

  1. 解决了什么问题?

首先了解下浏览器中其它数据存储方案:

  • cookie:大小不超过4kb,且在每次与服务器的请求通信中都需要携带;
  • WebSQL:不推荐使用;
  • LocalStorage:大小在2.5MB到10MB之间,各大浏览器之间有差异;不支持搜索;不支持建立自定义索引。

如果有大量的数据存储需求,就需要一种新的解决方案。

  1. 优势是什么呢?
  • 可以存储大量的结构化数据;
  • 提供查找接口;
  • 使用索引实现对数据的高性能搜索;
  • 使应用在在线和离线时都可以使用。
  1. 有哪些不足?
  • API设计比较传统,大部分数据读写操作都是异步的;
  • 使用时需要使用大量的回调函数和事件注册函数,没有Promise版本的API可用,导致开发效率并不高。
  1. IndexedDB的特征:
  • 键值对存储, IndexedDB 内部采用对象仓库(object store)存放数据。所有类型的数据都可以直接存入,包括 JavaScript 对象。对象仓库中,数据以“键值对”的形式保存,每一个数据记录都有对应的主键,主键是独一无二的,不能有重复,否则会抛出一个错误;
  • 异步, 操作都是异步的,不会阻塞主线程,对比LocalStorage, 它的操作都是同步的;
  • 支持事务(transzaction), 即在一系列操作中,只要有一步失败,整个事务都取消,数据库回滚到事务发生之前的状态,不存在只改写一部分数据的情况;
  • 同源限制;
  • 存储空间大, 一般来说不少于250MB,甚至没有上限;
  • 支持二进制存储, 即不仅可以存储字符串,还可以存储二进制数据,如:ArrayBuffer和Blob。

使用

  1. 一些概念:
  • 数据库:IDBDatabase对象,是一系列相关数据的容器,每个域名可以新建任意多个数据库;
  • 对象仓库:IDBObjectStore对象,一个数据库可以包含若干个对象仓库,类似于关系型数据库的表;
  • 数据记录:对象仓库保存的是数据记录。每条记录类似于关系型数据库的行,但是只有主键和数据体两部分。主键用来建立默认的索引,必须是不同的,否则会报错。主键可以是数据记录里面的一个属性,也可以指定为一个递增的整数编号;
  • 索引:IDBIndex对象,作用是加速数据的检索;
  • 事务:IDBTransation对象,数据记录的增、删、改和查,都要通过事务完成;
  • 操作请求:IDBRequest对象;
  • 指针:IDBCursor对象;
  • 主键集合:IDBKeyRange对象。
  1. 基础模式:

引用 ;

  • 打开数据库;
  • 在数据库中创建一个对象仓库(object store);
  • 启动一个事务,并发送一个请求来执行一些数据库操作,如:增加、读取数据等;
  • 监听正确类型的DOM事件以等待操作完成;
  • 在操作结果上进行一些操作(在request对象)。

数据库

  1. 新建数据库

新建数据库与打开数据库是同一个操作。如果指定的数据库不存在,就会新建。不同之处在于,后续的操作主要在upgradeneeded事件的监听函数里面完成,因为这时版本从无到有,所以会触发这个事件。

  1. IndexedDB 使用对象存储而不是表,并且一个单独的数据库可以包含任意数量的对象存储空间。每当一个值被存储进一个对象存储空间时,它会和一个键相关联。键的提供可以有几种不同的方法,这取决于对象存储空间是使用 key path 还是 key generator。

  2. indexedDB.open()方法用于打开数据库。这是一个异步操作,但是会立刻返回一个 IDBOpenDBRequest 对象。

tips:

  • 第一次打开数据库时,会先触发upgradeneeded事件,然后触发success事件;
  • open()方法返回的是一个对象(IDBOpenDBRequest),监听函数就定义在这个对象上面;
  • success事件发生后,从openRequest.result属性可以拿到已经打开的IndexedDB数据库对象。
  1. indexedDB.deleteDatabase()方法用于删除一个数据库,参数为数据库的名字。它会立刻返回一个IDBOpenDBRequest对象,然后对数据库执行异步删除。

增、删和查

  1. 开启一个事务才能对创建的数据库进行操作。事务来自于数据库对象,而且须指定你想让这个事务跨越哪些对象仓库。一旦你处于一个事务中,你就可以目标对象仓库发出请求。你要决定是对数据库进行更改还是只需从中读取数据。事务提供了三种模式:
  • readonly:从已存在的对象仓库里读取记录;
  • readwrite:从已存在的对象仓库里读取和写记录;
  • versionchange:修改数据库模式或结构,如:新建或删除对象仓库或索引。
  1. 使用IDBDatabase.transaction启动一个事务。

它接受两个参数:storeNames (作用域,一个你想访问的对象仓库的数组),事务模式 mode(readonly 或 readwrite)。该方法返回一个包含 IDBIndex.objectStore 方法的事务对象,使用 IDBIndex.objectStore 可以访问你的对象仓库。

未指定 mode 时,默认为 readonly 模式。

  1. 新增数据,向对象仓库写入数据记录,这需要通过事务完成。

  2. 读取数据,也是通过事务完成,可以使用objectStore.get()方法读取数据,参数是主键的值。

  3. 遍历数据,遍历数据表格的所有记录,要使用指针对象 IDBCursor。

  4. 更新数据,使用IDBObject.put()方法。

  5. 删除数据,使用IDBObject.delete()方法删除记录。

索引

  1. 索引的意义在于,可以让你搜索任意字段,也就是说从任意字段拿到数据记录。如果不建立索引,默认只能搜索主键(即从主键取值)。

小结

  1. IndexedDB有版本的概念,它主要解决的一个问题是,如果应用程序有修改数据库的数据结构的需求,如何做数据迁移?

数据库的版本决定了数据库架构,即数据库的对象仓库(object store)和他的结构。如果数据库不存在,open 操作会创建该数据库,然后 onupgradeneeded 事件被触发,你需要在该事件的处理函数中创建数据库模式。如果数据库已经存在,但你指定了一个更高的数据库版本,会直接触发 onupgradeneeded 事件,允许你在处理函数中更新数据库模式。

注意:

  • 版本号是一个 unsigned long long 数字,不能使用浮点数。
  • 同一时刻,只能有一个版本的数据库存在。 如果要修改数据库结构,如:增删表、索引或主键,只能通过升级数据库版本完成。
  1. 大多数的 web 储存解决方案一样,IndexedDB 也遵守同源策略。

  2. 使用 IndexedDB 执行的操作是异步执行的,以免阻塞应用程序。

  3. onupgradeneeded是唯一可以修改数据库结构的地方。

第三方库

  1. idb

idb/github  - 4.5k stars;

一个微小的(〜1.15k)库,大多 API 与 IndexedDB 类似,但做了一些小的改进,让数据库的可用性得到了大大的提升。

  1. Dexie.js

Dexie.js/github  - 7.8k stars;

IndexedDB 的包装,通过简单的语法,可以更快地进行代码开发。

  1. pouchdb

pouchdb 

pouchdb/github  - 14.9k stars;

使用 IndexedDB 在浏览器中实现 CouchDB 的客户端。

  1. rxdb

rxdb/github  - 17.3k stars。

tips:

  • 这里小编推荐使用Dexie.js;
  • rxdb是一个运行在各大浏览器和Electron内的实时数据库,对于需要向用户显示实时数据的客户端应用来说,它非常有用。

实践

IndexedDB相关的API还是比较复杂的,且设计的比较传统,又涉及不少概念,有一定的学习成本和开发难度。

在生产环境中,建议使用第三方库来提高开发效率。

  1. 这里小编推荐dexie.js,可以查看它的官网 ,学习如何使用,这里不展开了。

  2. 如果结合React使用的话,可以参考这篇教程 

参考资料

  1. IndexedDB MDN .

  2. 使用IndexedDB MDN .

  3. IndexedDB WangDoc .

评论区

写评论

登录

所以,就随便说点什么吧...

这里什么都没有,快来评论吧...