indexedDB之InDB

696 阅读3分钟

一些概念:indexedDB是HTML5标准。indexedDB的最主要优势在于,indexedDB是一个完整的数据库模型,它具有数据库应该有的库表结构,丰富的查询方式等等。除此之外,localStorage的容量在5M左右,而indexedDB达到惊人的500M。indexedDB还有可以存储arraybuffer,进程为异步等特征,这些特质都使得使用indexedDB作为前端数据存储的不二之选,localStorage降级为用于存储散列的快速读取配置项的存储工具。

缺点:api太复杂。

keyPath:localStorage是键值对;indexedDB是Object,也就是js对象。

key:indexedDB的key代表键值而非键名。

索引:indexedDB如其名,它的特色就是index(索引)。indexedDB具备了强大的索引系统,它根据keyPath创建索引,根据indexName查询对象记录,可以对一个indexName设置多个keyPath,而且还可以实现值域查询。

InDB简化indexDB操作。

安装:npm i indb

使用

  1. 连接到数据库
  2. 打开一个store(相当于表)
  3. 写入或修改数据
const idb = new InDB(options) // 实例化InDB,得到一个可以连接数据库的实例
const store = idb.use('store1') // 通过use方法,打开一个store

option参数列表
在进行InDB实例化时,需要传入参数:

name: 字符串,数据库名称
version: 正整数,数据库结构的版本,调整数据库结构时,需要升级version
stores: 数组,用以定义当前数据库中每个store的结构
    name: 字符串,store名称
    keyPath: 字符串,store keyPath
    indexes: 数组,用以定义store的索引
        name: 字符串,索引名称
        keyPath: 字符串,索引的keyPath
        unique: boolean,该索引是否是唯一的,不允许同一个store中同索引名存在两个及以上的索引值
		isKv: boolean,是否开启key-value模式,为true时keyPath和indexes无效

await store.add({ id, name, age })

注意:

相当于sql中的insert操作,需要注意,indexedDB中,对add的数据格式有要求,必须符合下面其中之一

  • options中没有设置autoIncrement,在add的对象中,必须包含keyPath属性,且key值相同的记录不能存在于store中
  • options中设置了autoIncerment为true,那么在add对象时,不必传keyPath,add成功时,会自动为该object加上该属性,并且保持自增的效果

如果add的对象key值已经存在于store中,会报错,因此,比较常规的操作是用put代替add。

await store.delete(key)

await store.put({ id, name, age })

注意:

put中key值其实也遵循上面add的规律,如果autoIncrement设置为true,那么不给key时,就是添加,给key时,就是更新。

一般,在代码中我们尽量少使用autoIncrement配置,因为我们很难完全掌握数据的实际情况。我们尽量使用put,而不是add,因为代码一旦部署,它就不能修改,如果在执行中add报错,那么很可能阻塞你的程序。

let value = await store.get(key)

注意:

  • @param {String} key 主键值,注意,是值,不是名
  • @return {Object} value

indexedDB真正强大的地方是利用索引进行查询。

注意:依赖于 index 的查询 API 需要在创建仓库时传入对应的 indexes,即使该属性已经被 keyPath 使用,也要在 indexes 中再次声明,否则无法使用下面的查询接口。

const store = new InDB({
  name: 'my-idb',
  stores: [
    {
      name: 'my-store',
      keyPath: 'id',
      indexes: [
        {
          name: '索引',
          keyPath: 'age',
        },
      ],
    },
  ],
})

let obj = await store.find('索引', 10)//找到数据库中第一条age = 10的数据,相当于sql里面的where age=10 limit 1 

注意:只有当你在创建store的时候,设置了这个索引,才能使用find去使用它