web 数据库

之前的章节有讨论过 web 中的存储方式,包括传统的 cookie 和新的 localstorage,这两种方式实现了 HTML 中的离线存储,但是存储方式比较简单,在有些复杂的业务场景可能不能满足条件。本章我们介绍一个计算机中一个重要的学科数据库,以及它在 HTML5 中的支持。数据库是一个内容庞大的知识体系,本章只介绍一些简单的用法以及它在 HTML 中的适用场景。

1. 适用场景

既然适用 localstorage 也可以做简单的数据存储,那么为什么还需要适用数据库呢?假设一个业务场景中将所有用户信息临时存储到浏览器中,这些信息包括昵称、姓名、性别等,现在需要搜索出性别是男的所有用户。如果使用 localstorage 的话,需要将所有的数据提取出来,一条条遍历,得出结果。这样的搜索算法的时间复杂度是 O(n),性能较差。如果使用数据库存储的话,只需要给性别列加上索引,然后使用 SQL 搜索,时间复杂度是 O(lgn),性能提升了一个等量级。关系型数据库的特点是:

  • 数据模型基于关系,结构化存储,完整性约束;
  • 支持事务,数据一致性;
  • 支持 SQL,可以复杂查询;

缺点是:

  • SQL 解析会影响性能;
  • 无法适应非结构化存储;
  • 横向扩展代价高;
  • 入门门槛较高。

2. Web SQL

Web SQL不是 HTML5 标准中的一部分,它是一个独立的规范,引入了 SQL 的 api,关于 SQL 的语法可以参考第三方的教程,在此不做解释。Web SQL 有 3 个函数

2.1 openDatabase

这个函数用于打开一个数据库,如果数据库不存在就创建。它有 5 个参数,分别表示:

  • 数据库名称;
  • 版本号;
  • 数据库备注;
  • 初始化数据大小;
  • 创建/打开成功回调函数
/**
     * 创建数据库 或者此数据库已经存在 那么就是打开数据库
     * name: 数据库名称
     * version: 版本号
     * displayName: 对数据库的描述
     * estimatedSize: 设置数据的大小
     * creationCallback: 回调函数(可省略)
     */
    var db = openDatabase("MySql", "1.0", "数据库描述", 1024 * 1024);

2.2 transaction

这个函数使用事务执行 SQL 语句,它是一个闭包,例如:

dataBase.transaction( function(tx) { 
    tx.executeSql(
    "create table if not exists test (id REAL UNIQUE, name TEXT)", 
    [],
    function(tx,result){ alert('创建test表成功'); }, 
    function(tx, error){ alert('创建test表失败:' + error.message); 
    });
});

2.3 executeSql

这个方法用于执行 SQL 语句。

tx.executeSql(
"update stu set name = ? where id= ?",
[name, id],
function (tx, result) {
},
function (tx, error) {
alert('更新失败: ' + error.message);
});
});

3. indexedDB

IndexedDB 是 HTML5 规范里新出现的浏览器里内置的数据库。它提供了类似数据库风格的数据存储和使用方式。存储在 IndexedDB 里的数据是永久保存,不像 cookies 那样只是临时的。IndexedDB 里提供了查询数据的功能,在线和离线模式下都能使用。

3.1 对比 Web SQL

跟 WebSQL 不同的是,IndexedDB 更像是一个 NoSQL 数据库,而 WebSQL 更像是关系型数据库。

3.2 判断浏览器是否支持


window.indexedDB = window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB;
if(!window.indexedDB){
    console.log("你的浏览器不支持IndexedDB");
}

3.3 创建库

使用 open 方法创建数据库。

 var request = window.indexedDB.open("testDB", 2);//第一个参数是数据库的名称,第二个参数是数据库的版本号。版本号可以在升级数据库时用来调整数据库结构和数据
 request.onsuccess = function(event){
    console.log("成功打开DB");
 }//成功之后的回调函数

3.4 添加数据

var transaction = db.transaction(["students"],"readwrite");//先创建事务,具有读写权限
transaction.oncomplete = function(event) {
    console.log("Success");
};
transaction.onerror = function(event) {
    console.log("Error");
};  
var test = transaction.objectStore("test");
test.add({rollNo: rollNo, name: name});//添加数据

3.5 查询

var request = db.transaction(["test"],"readwrite").objectStore("test").get(rollNo);//创建具备读写功能的事务
request.onsuccess = function(event){
    console.log("结果 : "+request.result.name);    
};//成功查询的回调函数

3.6 修改


var transaction = db.transaction(["test"],"readwrite");//创建事务
var objectStore = transaction.objectStore("test");
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);//执行修改
};

3.7 删除

//创建事务,并删除数据
db.transaction(["students"],"readwrite").objectStore("students").delete(rollNo);

4. 实际项目应用

实例演示
预览 复制