IndexedDB

452 阅读5分钟

为什么需要IndexedDB

随着浏览器功能的不断强大,越来越多的网站考虑将数据存储在客户端,从而减少像服务器发送请求,减少客户端的维护数据,可以直接从本地获取。

但是现有的几种客户端存储的方式都不满足要求。cookie的大小为4K,并且每次请求都会自动发送给服务器。loacalstorage的大小在2.5MB-10MB之间,而且不提供搜素功能,不支持自定义建立索引。所以需要一种新的解决方案,这就是indexedDB诞生的背景。通俗的来讲他就是浏览器本地的数据库,它可以被网页脚本创建。它提供索引,并且支持自定义索引。

IndexedDB的特点

(1)键值对存储:IndexedDB的存储是以键值对的形式进行。IndexedDB内部采用对象仓库进行数据存储。所有类型的数据都可以直接存入,包括js对象。对象仓库中,数据以键值对的形式进行存储,每一个数据记录都有对应的主键。主键是独一无二的,否则就会报错。

(2)异步:当IndexedDB操作时不会锁死浏览器,用户依然可以进行其他的操作,这与localstorage形成鲜明的对比,后者是同步的。异步的设计是为了防止如果有大量数据的读写会拖慢网页。

(3)支持事物。IndexedDB支持事务(transaction),这意味着一系列的操作步骤之中,只要有一步失败了,整个事务都会取消,数据库回滚的事务发生之前的状态,不存在只改写一部分的情况。

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

(5)存储空间大。IndexedDB不仅可以存储字符串,还可以存储二进制的树(比如说ArrayBuffer对象)

IndexedDB这个概念,之所以复杂是它把不同的实体抽象成了一个个的对象接口。下面是一些主要的概念。

数据库(IDBDateBase对象)。数据库是一系列数据的容器,每一个域名都可以创建任意多个数据库。
数据库有版本的概念,同一个时刻只能有一个版本的数据库存在,如果要修改数据库的结构(新增或删除表、索引、主键),只能通过版本升级来完成。

对象仓储(IDBObjectStore)。每个数据库包含若干个对象仓库(Object Store)。它类似于关系型数据库的表格。(用来存储对象)

数据记录。对象仓库保存的是数据记录,也就是说数据记录是一个个的对象。分为主键和数据体两个部分。因为主键用来建立默认的索引,所以主键是不一样的,否则的话就会报错。

索引。为了加速搜索,可以在对象仓库里面,为不同的属性建立索引。

事务。数据记录的增删改查都是通过事务来进行的。事务对象提供error、abort和compelete来监听操作的结果。

操纵流程

一、打开数据库

使用indexedDB.open()方法。
var request = window.indexedDB.open(databaseName,version);

第一个参数是字符串,表示数据库的名字;第二个参数是整数,表示数据库的版本。如果这个数据库原先并不存在,那就新建一个数据库,version为设置为1.
这个对象通过三种事件error、success、upgradeneeded,来处理打开数据库后的操作。
1、error事件表示打开数据库失败。

2、success事件表示打开数据库成功

var db ;
request.onsuccess=function(event){
    db=event.target.result;
    console.log('数据库创建成功')
}

3、upgradeneeded事件,如果指定版本号大于原来数据库的版本号就会触发版本升级事件。

二、创建数据库

其实打开数据库和创建数据库是一个操作,如果需要打开的数据库本身并不存在就会新建。不同之处在于新建数据库的后续操作基本要在upgradeneeded事件的监听函数里面完成,因为这个时候的版本是从无到有,所以出发这个事件

通常拿到数据库以后第一步是创建对象仓储

var request = window.indexedDB.open('dog',1)
var db ;
request.onupgradeneeded=function(event){
    db = event.target.result;//创建数据库实例
    let ObjectStore = db.createObjectStore('dog',{keyPath:'id'})
    // 在这里创建了数据存储对象,数据存储对象的名字叫做dog,主键是默认建立索引的属性,
    // 在这里就是id属性。
}

比如,数据记录是{id:1,name:'zhangsan'},那么id属性将会作为主键.如果说数据记录中没有适合作为主键的,那么可以让indexedDB进行自动生成.

 var objectStore = db.createObjectStore('dog',{
    aotoIncrement:true
})

新建仓库对象之后下一步应该就是新建索引

var request = window.indexedDB.open('dog',1)
        var db ;
request.onupgradeneeded=function(event){
    db = event.target.result;//创建数据库实例
    let ObjectStore = db.createObjectStore('dog',{keyPath:'id'})
    // 在这里创建了数据存储对象,数据存储对象的名字叫做dog,主键是默认建立索引的属性,
    // 在这里就是id属性。
    ObjectStore.createIndex('name','name',{unique:false})
    ObjectStore.createIndex('job','job',{unique:true})
}

IDBObject.createIndex()有三个参数,第一个索引名称,第二个索引所在的属性,第三个是配置对象.

数据记录的增删改查

数据记录的增删改查都是通过事务来实现的. 增加一个数据记录.

 function add(){
            var request = db.transaction(['dog'],'readwrite').ObjectStore('dog').add({
                id:1,name:'zhangsan',job:'doctor'
            })
            request.onerror = function(event){
                console.log('读取失败')
            }
            request.onsuccess=function(event){
                console.log('读取成功')
            }
        }
        add()