虽然在HTML5 WebStorage介绍了html5本地存储的Local Storage和Session Storage,这两个是以键值对存储的解决方案,存储少许数据结构颇有用,可是对于大量结构化数据就无能为力了,灵活大不够强大。咱们常常在数据库中处理大量结构化数据,html5引入Web SQL Database概念,它使用 SQL 来操纵客户端数据库的 API,这些 API 是异步的,规范中使用的方言是SQLlite。这个文档曾经在W3C推荐规范上,但规范工做已经中止了。目前已经陷入了一个僵局:目前的全部实现都是基于同一个SQL后端(SQLite),可是咱们须要更多的独立实现来完成标准化。html
接下来将和W3C力推的IndexedDB作比较,看看为何要废弃这种方案。Web SQL Database 规范中定义的三个核心方法:html5
咱们可使用这样简单的一条语句,建立或打开一个本地的数据库对象web
var db = openDatabase('testDB', '1.0', 'Test DB', 2 * 1024 * 1024);
openDatabase接收五个参数:数据库
若是提供了回调函数,回调函数用以调用 changeVersion() 函数,无论给定什么样的版本号,回调函数将把数据库的版本号设置为空。若是没有提供回调函数,则以给定的版本号建立数据库。后端
transaction方法用以处理事务,当一条语句执行失败的时候,整个事务回滚。方法有三个参数api
db.transaction(function (context) {
var e_id =1,e_log = ‘dfa’; context.executeSql('CREATE TABLE IF NOT EXISTS testTable (id unique, name)'); context.executeSql('INSERT INTO testTable (id, name) VALUES (0, "Byron")');//插入操做 context.executeSql('INSERT INTO testTable (id, name) VALUES (1, "Casper")'); context.executeSql('INSERT INTO testTable (id, name) VALUES (2, "Frank")');
context.executeSql('INSERT INTO testTable (id,name) VALUES (?,?)',[e_id,e_log])浏览器
});
这个例子中,中咱们建立了一个table,并在表中插入三条数据,四条执行语句任何一条出现错误,整个事务都会回滚cookie
executeSql方法用以执行SQL语句,返回结果,方法有四个参数网络
db.transaction(function (context) { context.executeSql('SELECT * FROM testTable', [], function (context, results) { var len = results.rows.length, i; console.log('Got '+len+' rows.'); for (i = 0; i < len; i++){ console.log('id: '+results.rows.item(i).id); console.log('name: '+results.rows.item(i).name); } });
因为Web SQL Database规范已经被废弃,缘由说的很清楚,当前的SQL规范采用SQLite的SQL方言,而做为一个标准,这是不可接受的,每一个浏览器都有本身的实现这还搞毛的标准。这样浏览器兼容性就不重要了,估计慢慢会被遗忘。数据结构
indexedDB——浏览器里边的内置数据库
IndexedDB是HTML5规范里新出现的浏览器里内置的数据库。对于在浏览器里存储数据,你可使用cookies或local storage,但它们都是比较简单的技术,而IndexedDB提供了相似数据库风格的数据存储和使用方式。存储在IndexedDB里的数据是永久保存,不像cookies那样只是临时的。IndexedDB里提供了查询数据的功能,在online和offline模式下都能使用。你能够用IndexedDB存储大型数据。
IndexedDB里数据以对象的形式存储,每一个对象都有一个key值索引。IndexedDB里的操做都是事务性的。一种对象存储在一个objectStore里,objectStore就至关于关系数据库里的表。IndexedDB能够有不少objectStore,objectStore里能够有不少对象。每一个对象能够用key值获取。
一、indexedDB VS LocalStorage
IndexedDB和LocalStorage都是用来在浏览器里存储数据,但它们使用不一样的技术,有不一样的用途,你须要根据本身的状况适当的选择使用哪一种。LocalStorage是用key-value键值模式存储数据,但跟IndexedDB不同的是,它的数据并非按对象形式存储。它存储的数据都是字符串形式。若是你想让LocalStorage存储对象,你须要借助JSON.stringify()
能将对象变成字符串形式,再用JSON.parse()
将字符串还原成对象。但若是要存储大量的复杂的数据,这并非一种很好的方案。毕竟,localstorage就是专门为小数量数据设计的,它的api是同步的。
IndexedDB很适合存储大量数据,它的API是异步调用的。IndexedDB使用索引存储数据,各类数据库操做放在事务中执行。IndexedDB甚至还支持简单的数据类型。IndexedDB比localstorage强大得多,但它的API也相对复杂。
对于简单的数据,你应该继续使用localstorage,但当你但愿存储大量数据时,IndexedDB会明显的更适合,IndexedDB能提供你更为复杂的查询数据的方式。
二、IndexedDB vs Web SQL
WebSQL也是一种在浏览器里存储数据的技术,跟IndexedDB不一样的是,IndexedDB更像是一个NoSQL数据库,而WebSQL更像是关系型数据库,使用SQL查询数据。W3C已经再也不支持这种技术。由于再也不支持上面也大体分析了其用法,也就再也不赘诉。
三、IndexedDB vs Cookies
Cookies(小甜点)听起来很好吃,但实际上并非。每次HTTP接受和发送都会传递Cookies数据,它会占用额外的流量。例如,若是你有一个10KB的Cookies数据,发送10次请求,那么,总计就会有100KB的数据在网络上传输。Cookies只能是字符串。浏览器里存储Cookies的空间有限,不少用户禁止浏览器使用Cookies。因此,Cookies只能用来存储小量的非关键的数据。
四、IndexedDB的用法
想要理解这个API,最好的方法是建立一个简单的web应用:好比把大家班的学生的学号和姓名存储在IndexedDB里。IndexedDB里提供了简单的增、删、改、查接口。
(1)、浏览器是否支持:
window.indexedDB = window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB;
if(!window.indexedDB){ console.log("你的浏览器不支持IndexedDB"); }
(2)、建立
一旦你的浏览器支持IndexedDB,咱们就能够打开它。但不能直接打开IndexedDB数据库。IndexedDB须要你建立一个请求来打开它。
var request = window.indexedDB.open("testDB", 2);//第一个参数是数据库的名称,第二个参数是数据库的版本号。版本号能够在升级数据库时用来调整数据库结构和数据
但你增长数据库版本号时,会触发onupgradeneeded
事件,这时可能会出现成功、失败和阻止事件三种状况。
var db; request.onerror = function(event){ console.log("打开DB失败", event); } request.onupgradeneeded = function(event){ console.log("Upgrading"); db = event.target.result; var objectStore = db.createObjectStore("students", { keyPath : "rollNo" }); }; request.onsuccess = function(event){ console.log("成功打开DB"); db = event.target.result; }
onupgradeneeded
事件在第一次打开页面初始化数据库时会被调用,或在当有版本号变化时。因此,你应该在onupgradeneeded
函数里建立你的存储数据。若是没有版本号变化,并且页面以前被打开过,你会得到一个onsuccess
事件。若是有错误发生时则触发onerror
事件。若是你以前没有关闭链接,则会触发onblocked
事件。
(3)增——往ObjectStore里新增对象
//为了往数据库里新增数据,咱们首先须要建立一个事务,并要求具备读写权限。在indexedDB里任何的存取对象的操做都须要放在事务里执行。 var transaction = db.transaction(["students"],"readwrite"); transaction.oncomplete = function(event) { console.log("Success"); }; transaction.onerror = function(event) { console.log("Error"); }; var objectStore = transaction.objectStore("students"); objectStore.add({rollNo: rollNo, name: name});
(4)删——ObjectStore里删除对象
//删除跟新增同样,须要建立事务,而后调用删除接口,经过key删除对象。 db.transaction(["students"],"readwrite").objectStore("students").delete(rollNo);
(5)查——经过key取出对象,即往get()
方法里传入对象的key值,取出相应的对象。
var request = db.transaction(["students"],"readwrite").objectStore("students").get(rollNo); request.onsuccess = function(event){ console.log("Name : "+request.result.name); };
(6)改—— 为了更新一个对象,首先要把它取出来,修改,而后再放回去。
var transaction = db.transaction(["students"],"readwrite"); var objectStore = transaction.objectStore("students"); var request = objectStore.get(rollNo); request.onsuccess = function(event){ console.log("Updating : "+request.result.name + " to " + name); request.result.name = name; objectStore.put(request.result); };