随着浏览器功能的不断加强,越来越多的网站开始考虑将大量的数据存储在客户端。这样的考虑是为了直接从本地获取数据,减少从服务器获取数据耗费的网络资源。

原有的浏览器数据存储方案都不适合存储大量数据。Cookie的大小不超过4KB,且每次请求都会发送会服务器;WebStorage(LocalStorage、SessionStorage)的大小在2.5MB到10MB之间(各家浏览器不同,一般可以认为是5MB左右),而且不提供搜索功能,也不能建立自定义的索引。因此IndexedDB就诞生了,是H5提供的一种新的浏览器存储解决方案。

什么IndexedDB

通俗地说,IndexedDB就是浏览器提供的一个本地数据库,可以被网页脚本创建和操作。IndexedDB允许存储大量的数据,同时提供查找借口,还能创建索引。而这些都是Cookie和WebStorage所不具备的。就数据库而言,IndexedDB不属于关系型数据库(不支持SQL查询语句),更接近与NoSQL数据库。

Indexed具有以下特点:

1.键值对存储。IndexedDB内部采用对象仓库(Object Store)存放数据。所有类型的数据都可以直接存入,包括JavaScript对象。在对象仓库中,数据以键值对的形式保存,每一个数据记录都有对应的主键,且这个主键是唯一的,一旦重复就会抛出错误。

2.异步。IndexedDB操作的时候不会锁死浏览器(线程不会挂起),用户依然可以进行其他操作。这与LocalStorage形成对比,后者的操作是同步的(线程会挂起)。异步的设计是为了防止大量数据的读写拖慢网页的表现性能。

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

4.同源策略。IndexedDB受浏览器同源策略的限制,每一个数据库都对应创建它的域名。网页只能访问自身域名下的数据库,不能访问跨域的数据库。

5.存储空间大。IndexedDB的存储空间比WebStorage要大得多,一般来说不小于250MB,甚至没有上限。

6.支持二进制存储。IndexedDB不仅可以存储字符串,还可以存储二进制数据(ArrayBuffer和Blob对象)。

Indexed中的一些主要概念

IndexedDB是一个比较复杂的API,涉及到不少概念。它把不同的实体抽象成一个个对象接口。学习这个API实际上就是学习它提供的各种对象接口。

数据库 IDBDatabase对象
对象仓库 IDBObjectStore对象
索引 IDBIndex对象
事务 IDBTransaction对象
操作请求 IDBRequest对象
指针 IDBCursor对象
主键集合 IDBKeyRange对象

下面对一些主要概念进行说明:

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

2.对象仓库。每个数据库包含若干个对象仓库,类似于关系型数据库的表格。

3.数据记录。对象仓库保存的是数据记录。每条记录类似于关系型数据库的行,但是只有主键和数据体两个部分。主键用来建立默认的索引,必须是不同的,否则会报错。主键可以是实数据记录里面的一个属性,也可以另外指定为一个递增的整数编号。数据体可以是任意的数据类型,不限于对象。

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

5.事务。数据记录的读写和删改,都要通过事务来完成。事务对象提供了error、abort和complete三个事件用来监听操作的结果。

IndexedDB的常用操作

这里给出IndexedDB数据库常用操作的简单示例。

1.打开数据库

使用IndexedDB的第一步是打开数据库,使用indexed.open()方法。

var request = window.indexedDB.open(databaseName, version);

这个方法接受两个参数,第一个参数是字符串,表示数据库名,如果指定的数据库不存在,就会新建一个数据库。第二个参数是整数,表示数据库的版本,如果省略,就会打开现有的数据库版本。在新建数据库的时候,默认版本为1。

这个方法会返回一个IDBRequest对象。这个对象可以通过onerror、onsuccess和onupgradeneeded事件处理打开数据库的操作结果。

onerror事件,表示打开数据库失败。

request.onerror = function (event) {
console.log('数据库打开报错');
};

onsuccess事件,表示打开数据库成功。

request.onsuccess = function (event) {
var db = request.result;
console.log('数据库打开成功', db);
};

onupgradeneeded事件,如果指定的版本号大于数据库的实际版本号,就会发生数据库升级事件。

request.onupgradeneeded = function (event) {
var db = event.target.result;
}

2.新建数据库

新建数据库与打开数据库是同一个操作,如果指定的数据库不存在,就会新建一个数据库。不同之处在于,打开数据库是触发的onsuccess事件,而新建数据库是触发的onupgradeneeded事件,因为这时候版本是从无到有。

通常新建数据库之后的第一件事是新建对象仓库(新建表)。

var db;
request.onupgradeneeded = function(event) {
db = event.target.result;
var objectStore = db.createObjectStore('yanggb', {keyPath: 'id'});
}

上面的代码中,在数据库新建成功后会新增一张叫做yanggb的表,主键是id。

更好的写法是,先判断以下表格是否存在,如果不存在的话再新增。

var db;
request.onupgradeneeded = function(event) {
db = event.target.result;
var objectStore;
if (!db.objectStoreNames.contains('yanggb')) {
objectStore = db.createObjectStore('yanggb', {keyPath: 'id'});
}
}

主键(key)是默认建立索引的属性。如果数据记录没有适合作为主键的属性,也可以让IndexedDB自动生成主键,下面的代码中就指定了主键为一个递增的整数。

var objectStore = db.createObjectStore('yanggb', {autoIncrement: true});

再新建了对象仓库之后,下一步就可以新建索引。

var db;
request.onupgradeneeded = function(event) {
db = event.target.result;
var objectStore;
if (!db.objectStoreNames.contains('yanggb')) {
objectStore = db.createObjectStore('yanggb', {keyPath: 'id'});
objectStore.createIndex('index_book', 'book', {unique: false});
objectStore.createIndex('index_email', 'email', {unique: true});
}
}

IDBObject.createIndex()的三个参数分别为索引名称、索引所在的属性和配置对象(说明该属性能否包含重复的值)。

3.新增数据

新增数据指的是向对象仓库中写入数据记录,需要通过事务对象来完成。

function addRecord() {
var request = db.transaction(['yanggb'], 'readwrite')
.objectStore('yanggb')
.add({id: 1, book: '十一种孤独', email: 'yanggb@yanggb.com'}); request.onsuccess = function (event) {
console.log('数据写入成功!');
}; request.onerror = function (event) {
console.log('数据写入失败!');
}
}

在上面的代码中,写入数据需要新建一个事务。新建的时候必须要指定表名和操作模式(只读read或者读写readwrite)。新建事务之后就可以通过IDBTransaction.objectStore(name)方法拿到IDBObjectStore对象,然后通过表格对象的add()方法向表格中写入一行记录。

这个写入操作是一个异步操作,通过监听连接对象的success事件和error事件可以了解是否写入成功或做相应的后续操作。

4.读取数据

读取数据同样也是通过事务对象来完成的。

function getRecord() {
var transaction = db.transaction(['yanggb']);
var objectStore = transaction.objectStore('yanggb');
var request = objectStore.get(1); request.onerror = function(event) {
console.log('事务失败');
}; request.onsuccess = function(event) {
if (request.result) {
console.log('book: ' + request.result.book);
console.log('email: ' + request.result.email);
} else {
console.log('未获得数据记录!');
}
};
}

IDBObjectStore.get()方法用于读取数据,接收一个参数,参数是主键的值。

5.遍历数据

如果要遍历数据仓库中的所有数据记录,要使用指针对象IDBCursor。

function getRecords() {
var objectStore = db.transaction('yanggb').objectStore('yanggb'); objectStore.openCursor().onsuccess = function (event) {
var cursor = event.target.result; if (cursor) {
console.log('id: ' + cursor.key);
console.log('book: ' + cursor.value.book);
console.log('email: ' + cursor.value.email);
cursor.continue();
} else {
console.log('没有更多数据了!');
}
};
}

这里,获取数据记录的操作是在IDBCursor对象中的onsuccess监听事件中完成的。

6.更新数据

更新数据要使用IDBObjectStore对象的put()方法。

function updateRecord() {
var request = db.transaction(['yanggb'], 'readwrite')
.objectStore('yanggb')
.put({id: 1, book: '追风筝的yanggb', email: 'renj@yanggb.com'}); request.onsuccess = function (event) {
console.log('数据更新成功!');
}; request.onerror = function (event) {
console.log('数据更新失败');
}
}

上面的代码中,IDBObject.put()方法会自动更新主键为1的记录。

7.删除数据

删除数据要使用IDBObjectStore对象的delete()方法。

function remove() {
var request = db.transaction(['yanggb'], 'readwrite')
.objectStore('yanggb')
.delete(1); request.onsuccess = function (event) {
console.log('数据删除成功');
};
}

IDBObjectStore.delete()方法用于删除数据,接受一个参数,参数值为主键的值。

8.使用索引

索引的意义在于可以快速通过任意字段拿到数据记录。如果不建立索引的话,默认只能搜索主键(从主键取值)。在上面新建表格的时候已经对book字段建立了索引,于是可以通过book字段找到对应的数据记录。

function searchRecordByIndexOfBook() {
var transaction = db.transaction(['yanggb'], 'readonly');
var store = transaction.objectStore('yanggb');
var index = store.index('book');
var request = index.get('追风筝的yanggb'); request.onsuccess = function (e) {
var result = e.target.result;
if (result) {
console.log('找到对应数据!');
} else {
console.log('未找到对应数据!');
}
}
}

如果想要了解更多的话,可以查看官网的API:https://developer.mozilla.org/en-US/docs/Web/API/IndexedDB_API

"我唱得不够动人你别皱眉。"

indexeddb:浏览器中的数据库的更多相关文章

  1. 在 SQL Server 2005 中配置数据库邮件

    一.            SQL Server发邮件原理和组件介绍: 数据库邮件有4个组件:配置文件.邮件处理组件.可执行文件以及“日志记录和审核组件”. l  配置组件包括: 1)数据库邮件帐户包 ...

  2. IndexedDB:浏览器里内置的数据库(转)

    出处;http://www.webhek.com/indexeddb/ IndexedDB是HTML5规范里新出现的浏览器里内置的数据库.对于在浏览器里存储数据,你可以使用cookies或local ...

  3. HTML5 使用浏览器内置数据库之 indexedDB

    indexedDB是H5规范里的浏览器内置数据库,是nosql数据库的一种.因为另一种数据库Web SQL不再受W3C支持,所以还得学习下这个. 基本情况 兼容性:ie11及以上都支持, W3C是这么 ...

  4. 在浏览器中输入Google.com并且按下回车之后发生了什么(转载)

    原文地址:https://github.com/skyline75489/what-happens-when-zh_CN#id9 本文试图回答一个古老的面试问题:当你在浏览器中输入google.com ...

  5. 在浏览器中输入Google.com并且按下回车之后发生了什么?

    作者: skyline75489  来源: skyline75489的博客  发布时间: 2015-03-26 16:57  阅读: 4163 次  推荐: 23   原文链接   [收藏]      ...

  6. 网易笔试题:浏览器中输入一个url后回车到返回页面信息的过程

    You enter a URL into the browser输入一个url地址 The browser looks up the IP address for the domain name浏览器 ...

  7. 在Spring Boot中使用数据库事务

    我们在前面已经分别介绍了如何在Spring Boot中使用JPA(初识在Spring Boot中使用JPA)以及如何在Spring Boot中输出REST资源(在Spring Boot中输出REST资 ...

  8. 深入浅出经典面试题:从浏览器中输入URL到页面加载发生了什么 - Part 3

    备注: 因为文章太长,所以将它分为三部分,本文是第三部分. 第一部分:深入浅出经典面试题:从浏览器中输入URL到页面加载发生了什么 - Part 1 第二部分:深入浅出经典面试题:从浏览器中输入URL ...

  9. Python_socket常见的方法、网络编程的安全注意事项、socketsever模块、浏览器中在一段时间记录用户的登录验证机制

    1.socket常见的方法 socket_常见方法_服务器端 import socket from socket import SOL_SOCKET,SO_REUSEADDR sk = socket. ...

随机推荐

  1. 策略模式+注解 干掉业务代码中冗余的if else...

    前言: 之前写过一个工作中常见升级模式-策略模式 的文章,里面讲了具体是怎样使用策略模式去抽象现实中的业务代码,今天来拿出实际代码来写个demo,这里做个整理来加深自己对策略模式的理解.   一.业务 ...

  2. Django ORM 知识点总结

    Query是如何工作的 Django QuerySet是懒执行的,只有访问到对应数据的时候,才会去访问数据库.另外如果你再次读取查询到的数据,将不会触发数据库的访问,而是直接从缓存获取. 比如 # 这 ...

  3. scala函数式编程(二) scala基础语法介绍

    上次我们介绍了函数式编程的好处,并使用scala写了一个小小的例子帮助大家理解,从这里开始我将真正开始介绍scala编程的一些内容. 这里会先重点介绍scala的一些语法.当然,这里是假设你有一些ja ...

  4. 松软科技课堂:数据库-主键(PrimaryKey)

    主键就是一个表中每个数据行的唯一标识.不会有重复值的列才能当主键.一个表可以没有主键,但是会非常难以处理,因此没有特殊理由表都要设定主键 主键有两种选用策略:业务主键和逻辑主键.业务主键是使用有业务意 ...

  5. java架构之路-(设计模式)五种创建型模式之单例模式

    设计模式自身一直不是很了解,但其实我们时刻都在使用这些设计模式的,java有23种设计模式和6大原则. 设计模式是一套被反复使用.多数人知晓的.经过分类编目的.代码设计经验的总结.使用设计模式是为了可 ...

  6. 深入理解Three.js中正交摄像机OrthographicCamera

    前言 在深入理解Three.js中透视投影照相机PerspectiveCamera那篇文章中讲解了透视投影摄像机的工作原理以及对应一些参数的解答,那篇文章中也说了会单独讲解Three.js中另一种常用 ...

  7. Mysql学习笔记整理之选用B+tree结构

    为什么mysql不使用平衡二叉树? 数据处的深度决定着他的IO操作次数,IO操作耗时大 每一个磁盘块保存的数据量太小 B+Tree和B-Tree的区别? B+树几点关键字搜索采用闭合区间 B+树非叶节 ...

  8. 极光推送消息——Alias别称方式(Andirod)

    1.pom文件引入相关jar包 <!--极光推送消息start--> <dependency> <groupId>net.sf.json-lib</group ...

  9. springboot + mybatis + mycat整合

    1.mycat服务 搭建mycat服务并启动,windows安装参照. 系列文章: [Mycat 简介] [Mycat 配置文件server.xml] [Mycat 配置文件schema.xml] [ ...

  10. 基于hap的文件上传和下载

    序言 现在,绝大部分的应用程序在很多的情况下都需要使用到文件上传与下载的功能,在本文中结合hap利用spirng mvc实现文件的上传和下载,包括上传下载图片.上传下载文档.前端所使用的技术不限,本文 ...