本地数据库IndexedDB

185 阅读4分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第1天,点击查看活动详情

前言

在浏览器上有两种数据库:webSQL和IndexedDB。但是如果在浏览器上需要用到数据库一般会使用Indexed DB数据库,webSQL基本上已经废弃了。

1.IndexedDB简介

MDN官网是这样解释Indexed DB的:

IndexedDB 是一种底层 API,用于在客户端存储大量的结构化数据(也包括文件/二进制大型对象(blobs))。该 API 使用索引实现对数据的高性能搜索。虽然 Web Storage 在存储较少量的数据很有用,但对于存储更大量的结构化数据来说力不从心。而 IndexedDB 提供了这种场景的解决方案。

官网上的这句话也很简单明了,意思就是IndexedDB主要用来客户端存储大量数据而生的,我们都知道cookie、localstorage等存储方式都有存储大小限制。如果数据量很大,且都需要客户端存储时,那么就可以使用IndexedDB数据库。

2.IndexedDB使用场景

所有的场景都基于客户端需要存储大量数据的前提下:

  1. 数据可视化等界面,大量数据,每次请求会消耗很大性能。
  2. 即时聊天工具,大量消息需要存在本地。
  3. 其它存储方式容量不满足时,不得已使用IndexedDB

3.IndexedDB特点

(1) 非关系型数据库(NoSql)

我们都知道MySQL等数据库都是关系型数据库,它们的主要特点就是数据都以一张二维表的形式存储,而Indexed DB是非关系型数据库,主要以键值对的形式存储数据。

(2)持久化存储

cookie、localStorage、sessionStorage等方式存储的数据当我们清楚浏览器缓存后,这些数据都会被清除掉的,而使用IndexedDB存储的数据则不会,除非手动删除该数据库。

(3)异步操作

IndexedDB操作时不会锁死浏览器,用户依然可以进行其他的操作,这与localstorage形成鲜明的对比,后者是同步的。

(4)支持事务

IndexedDB支持事务(transaction),这意味着一系列的操作步骤之中,只要有一步失败了,整个事务都会取消,数据库回滚的事务发生之前的状态,这和MySQL等数据库的事务类似。

(6)同源策略

IndexedDB同样存在同源限制,每个数据库对应创建它的域名。网页只能访问自身域名下的数据库,而不能访问跨域的数据库。

(7)存储容量大

这也是IndexedDB最显著的特点之一了,这也是不用localStorage等存储方式的最好理由。

4.IndexedDB重要概念讲解

数据库: 是所有相关数据的基本容器。在同源策略( 协议 + 域名 + 端口 )的前提下,每个域名下可以新建任意多的数据库。IndexedDB 中有版本概念,这就规定了同一时刻下只有一个版本的数据库存在。

对象仓库: 对象仓库 ObjectStore 在 IndexedDB 中对应的是 MYSQL 中的表 Table。

数据: 对象仓库中记录的是若干条数据,数据只有主键和数据体两部分,主键不能重复,可以为自增的整数编号或者数据中指定的一个属性。数据体可以是任意数据类型,不限于对象。

索引: 为不同的属性建立索引可以加快数据的检索。

事务: 数据的 CURD (增删查改) 都要通过事务来完成。

5.IndexedDB使用

IndexedDB语法比较底层,使用较为麻烦;一般都使用localForage来操作IndexedDB。

localForage 通过简单的key-value语法来异步存储数据。它能存储多种类型的数据,而不仅是字符串。它基于 IndexedDB 实现,并在不持支 IndexedDB 的浏览器中自动使用 WebSQL 和 localStorage。

localForage官网中文文档

使用示例:

// 配置
localforage.config({
    name: 'idoc',           // 数据库名称
    storeName:"interface",  // 仓库名称,相当于数据库中的表
});
localforage.setItem("fdas","faaaa");
localforage.setItem("fdaaaas","faaaa");


// 重新配置
localforage.config({
    name: 'idoc2',          // 数据库名称
    storeName:"interface2", // 仓库名称,相当于数据库中的表
});
localforage.setItem("fdas","faaa2a");
localforage.setItem("fdaaaas","faaaa22");

// 取值
localforage.getItem('somekey', function(err, value) {
    if(value === null){

    }else{

    }
});