浏览器数据库系统-IndexedDB
前端存储数据,我们一般会用到cookie和Web Storage,但是他们都有存储长度的限制,尤其是cookie存储内容是比较小的。如果想要大容量的存储就要用到浏览器的数据库indexedDB了,第一次听说indexedDB是在美团开源的前端监控项目中,用indexedDB存储了日志,但是并没有去研究这个项目,也没有对indexedDB进行学习,但是前段时间接手了一个项目用到了indexedDB来存储数据,所以抽点时间来学习一下。
IndexedDB介绍
IndexedDB 是一种底层 API,用于在客户端存储大量的结构化数据(也包括文件/二进制大型对象(blobs))。该 API 使用索引实现对数据的高性能搜索。
IndexedDB 是一个事务型数据库系统,类似于基于 SQL 的 RDBMS。然而,不像 RDBMS 使用固定列表,IndexedDB 是一个基于 JavaScript 的面向对象数据库。IndexedDB 允许您存储和检索用键索引的对象;可以存储结构化克隆算法支持的任何对象。
IndexedDB并不支持SQL查询。
特点
- 键值对储存
IndexedDB内部采用对象仓库(object store)存放数据。所有类型的数据都可以直接存入。 - 每一个数据都有对应的主键,主键不能重复。
IndexedDB操作是异步的,不会堵塞浏览器。- 支持事务
- 遵守同源策略,不能操作其他域名下的数据库。
- 存储空间大。
关于异步问题,引自MDN:
使用
IndexedDB执行的操作是异步执行的,以免阻塞应用程序。IndexedDB最初包括同步和异步API。同步API仅用于Web Workers,且已从规范中移除,因为尚不清晰是否需要。但如果Web开发人员有足够的需求,可以重新引入同步API。
基本使用
连接数据库
直接放一段简单的代码,看一下怎么连接数据库:
1 | const request = window.indexedDB.open('db1') |
先解释一下代码的内容:
window.indexedDB.open('db1'): 我们打开一个名为db1的数据库,如果不存在会创建。onsuccess: 数据库连接成功触发onerror: 数据库连接失败触发onupgradeneeded: 数据库初次连接和版本升级触发
执行上面的代码,我们会看到控制台打印了内容,并成功创建了名为 db1 的数据库,且版本为1
其他的都很好理解,但是版本是怎么控制的呢?
其实window.indexedDB.open()接受两个参数:
name:string,数据库的名字version:number,数据库的版本,是一个可选参数,如果我们省略了该参数的情况下:- 如果数据库不存在,会创建version为1的数据库,即会触发
onupgradeneeded - 如果数据库已经存在了,会以当前的version打开,即不会触发
onupgradeneeded
- 如果数据库不存在,会创建version为1的数据库,即会触发
我们可以指定一个版本号来升级数据库的版本看一下:
1 | const request = window.indexedDB.open('db1', 5) |
可以看一下控制台与数据库的信息:
可以发现成功打开了数据库且触发了 onupgradeneeded
如果此时我们降低版本呢?
1 | const request = window.indexedDB.open('db1', 2) |
好吧,出错了,数据库版本并没有被降低,我们可以看到报错信息 The requested version (2) is less than the existing version (5). ,所以并不能通过这种方式来降低数据库的版本。
一般我们会在
onupgradeneeded中创建ObjectStore,版本更新后并不会删除之前版本创建的store,之前版本的store是依然存在的。多次创建相同名称的
store会抛出错误,即使数据库版本不同。例:
1
2
3
4
5
6
7 request.onupgradeneeded = function(event) {
// 保存 IDBDataBase 接口
var db = event.target.result;
// 为该数据库创建一个对象仓库
var objectStore = db.createObjectStore("name", { keyPath: "myKey" });
};
增删改查
我们先来对数据库写入一些数据用于后边的演示:
1 | const dbName = 'db1' |
执行代码可以发现已经写入了数据:
需要开启一个事务才能对你的创建的数据库进行操作。事务来自于数据库对象,而且你必须指定你想让这个事务跨越哪些对象仓库。一旦你处于一个事务中,你就可以目标对象仓库发出请求。你要决定是对数据库进行更改还是只需从中读取数据。事务提供了三种模式:readonly、readwrite 和 versionchange。
因为已经创建了数据库,如果不再修改版本号,是不会再次触发 onupgradeneeded事件的,所以后续的增删改查我们在 onsuccess 中获取数据库来进行演示:
增加数据使用 add 方法:
1 | request.onsuccess = function(event) { |
修改数据使用 put 方法
1 | request.onsuccess = function(event) { |
删除数据使用 delete 方法
1 | request.onsuccess = function(event) { |
查询数据使用 get/getAll 方法
1 | request.onsuccess = function(event) { |
以上就是一些 indexedDB 的常用 API 的说明了,用起来吧感觉确实不优雅,感觉自己也并没有什么应用场景,所以如果有场景深入使用有更深的理解再继续更这篇帖子吧。
浏览器数据库系统-IndexedDB