根据您对 iOS 上 Safari 的给定要求,除了 WebSQL 之外别无选择。其他移动浏览器(如 Opera 和 Blackberry)支持 WebSQL。我认为即使他们有 IndexedDB,他们也不会删除 WebSQL 支持。不知何故,它们是互补的。
另一方面,在浏览器存储大战中,IndexedDB 赢了。IE 和 FF 将只有 IndexedDB。具有讽刺意味的是,FF 在 Sqlite 之上实现了 IndexedDB。
我想说的是 IndexedDB 不仅仅是一个键值存储。它有索引和事务。仅这两者就提供了 SQL 查询的几乎所有功能,包括连接、条件和排序。由于它的异步 API,一开始并不明显。
IndexedDB 的性能优于 WebSQL。它更安全。对于 javascript 用例,它更加灵活。最后,它更易于使用。
为了说明这种情况,我将使用我库中的伪代码,但您可以直接使用 IndexedDB API:
'people' 商店有索引字段 'name' 和列表索引字段 'hobby'。在 JSON 中,
people = {
name: 'Foo Bar',
email: 'foo@bar.com'
hobby: ['camping', 'swimming']
};
从爱好是“露营”的“人”中检索名称。
var req = db.keys('people', 'hobby', IDBKeyRange.only('camping'));
req.done(function(campers) {
db.keys('people', campers, 'name').done(function(names) {
console.log(names);
});
});
这段代码的有趣之处在于不涉及序列化。因此它非常快。
以下示例说明了友谊图查询。friendship
对象存储只有一个列出的索引字段friend_list
。它使用人员对象存储键作为离线主键。people
对象存储有很多属性,其中有location
字段。me
查询是查找认识并other_guy
位于“新加坡”的朋友列表。
var q1 = new ydn.db.Iterator('friendship', 'friend_list', IDBKeyRange.only(me));
var q2 = new dn.db.Iterator('friendship', 'friend_list', IDBKeyRange.only(other_guy));
// if location is not indexed, a filtered value query is used.
var q3 = new ydn.db.Iterator('people', new ydn.db.Expression(['"location"', "'Singapore'", '=']));
// if location is indexed, an index query is used.
// var q3 = new ydn.db.Iterator('people', 'location', IDBKeyRange.only('Singapore'));
var current_loop = 2; // start from inner loop
var join_algo = function(keys, index_keys) {
var advancement = [];
advancement[keys.length - 1] = null;
var has_adv = false;
for (var i = 0; i < keys.length; i++) {
if (!goog.isDef(keys[i])) {
// completed iterator
if (i != 0) {
advancement[i] = false; // request to restart the iteration
advancement[i - 1] = true; // advance outer iterator
current_loop = i - 1;
} // i == 0 means we are done.
has_adv = true;
break;
}
}
if (!has_adv) {
// continue looping current
advancement[current_loop] = true;
}
return advancement;
}
var result = db.scan([q3, q1, q2], join_algo);
result.done(function(keys, index_keys, values) {
console.log(values); // should get desire list of friends
});
同样,此连接查询只是键扫描,因此速度非常快。默认情况下scan
使用排序合并算法来查找匹配键,但这里显示的是一个简单的嵌套循环连接算法。所以表连接是可能的,但你必须编写连接算法。但是像 zigzag 合并这样的新算法比使用 Sqlite 更快,因为所有输入都已排序,游标也可以前进,更重要的是,连接过程可以利用数据库中没有的外部知识。使用 SQL,连接操作是不透明的。
除此之外,IndexedDB 还可以使用流式处理和 map/reduce 处理等技术。