HTML5索引数据库、Web SQL数据库和浏览器战争
我正在开始开发一个具有离线数据库存储需求的web应用程序。长话短说,该应用程序应该能够在以下设备上运行:HTML5索引数据库、Web SQL数据库和浏览器战争,html,indexeddb,web-sql,Html,Indexeddb,Web Sql,我正在开始开发一个具有离线数据库存储需求的web应用程序。长话短说,该应用程序应该能够在以下设备上运行: 作为主要的桌面浏览器之一,Chrome是首选浏览器 iOS上的狩猎 Android的本机浏览器(基于V8和WebKit) 所以问题是选择哪种技术:IndexedDB还是Web SQL数据库 关于Web SQL数据库,一方面,它可以用于上述任何场景。另一方面,Mozilla声明Firefox将永远不会实现它,根据HTML5,该规范已陷入僵局: 该规范陷入了僵局:所有感兴趣的实现者都使用了相
- 作为主要的桌面浏览器之一,Chrome是首选浏览器
- iOS上的狩猎
- Android的本机浏览器(基于V8和WebKit)
(CouchDB上的一个注释:您是否也将其视为一个替代方案?考虑到只有WebSQL支持您列出的所有三个需求,您的选择不应该很简单吗?您对Safari或Android的开发路线图没有深入了解,因此请使用您现有的资源。您的数据库需求是否远远超出了键/值存储?如果没有,我已经找到了许多用于基于本地浏览器的数据库抽象的javascript包。jStore就是这样一个包: 我最近用它来添加本地密钥/值存储。它有很好的文档记录,集成时间可以忽略不计——它通过API支持一系列存储后端,包括闪存本地存储
CouchDB是一个很好的解决方案——对于一个与您的问题不完全一致的问题。退房不是严格的“Web应用程序”,但它可以提供一个你可以运行的数据库基础,如果你对规范有一定的灵活性。
嗯,就像所有的计算一样,游戏是“抽象的”。 如果您能够找到一个既适用于SQL存储又适用于键/值存储的适当层,那么,理想情况下,您可以与问题隔离开来,并且可以在特定浏览器上支持适当的实现。如果您的数据模型和访问模式不符合最低公分母(即k/v存储),那么这就解决了您的问题
如果您可以使用任意一个存储,那么就在一个合适的访问层上工作,并从这个方向解决问题记住,仅仅因为后端有一个k/v存储,并不意味着您必须将数据建模为一个k/v模型。实际上,后端上的所有数据库都是k/v存储。如果你没有大量的数据,你可以做很多事情。由于数据量很大,您可能不得不跳过的障碍可能会降低性能,而这些性能在数据量较小的情况下可能看不到。这要看情况而定。根据您对iOS上Safari的特定要求,除了WebSQL之外,别无选择。WebSQL在其他移动浏览器(如Opera和Blackberry)中受支持。我认为即使他们有IndexedDB,他们也不会删除WebSQL支持。不知何故,它们是互补的 另一方面,在浏览器存储战争中,IndexedDB永远获胜。IE和FF将仅具有IndexedDB。具有讽刺意味的是,FF在Sqlite之上实现了IndexedDB 我想说的是IndexedDB不仅仅是键值存储。它有索引和事务。这两个特性构成了SQL查询的几乎所有特性,包括连接、条件和排序。由于它的异步API,一开始并不明显 IndexedDB的性能优于WebSQL。它更安全。它对于javascript用例更灵活。最后,它更容易使用 为了说明这种情况,我将使用来自的sudo代码,但您可以直接使用IndexedDB API: “人员”存储有索引字段“名称”和列表索引字段“爱好”。在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);
});
});
这段代码的有趣之处在于它不涉及序列化。因此速度非常快
下面的示例演示了友谊图查询<代码>友谊对象存储只有一个列出的索引字段朋友列表
。它使用people对象存储键作为越界主键people
objectstore有很多属性,其中有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
});
var q1=new ydn.db.Iterator('friends','friend_list',IDBKeyRange.only(me));
var q2=new dn.db.Iterator('friendy'、'friend_list',IDBKeyRange.only(other_guy));
//如果位置未编制索引,则使用筛选值查询。
var q3=new ydn.db.Iterator('people',new ydn.db.Expression([''location','Singapore',=']);
//如果位置已编制索引,则使用索引查询。
//var q3=new ydn.db.Iterator('people','location',IDBKeyRange.only('Singapore');
无功电流_回路=2;//从内环开始
变量连接算法=
//If the operation is a set(), and the referenced structures
//don't exist, they will be created automatically.
var webSQLOptionsObj = {
databaseName: "Example_DB",
databaseDisplayName: "Example DB",
databaseVersion: "",
estimatedDatabaseSize: 1024 * 1024,
tableData: {
name: "Main",
keyColumnName: "lastName",
columnDefinitions: "(lastName TEXT PRIMARY KEY, firstName TEXT)"
},
tableIndexDataArray: [name: "First_Name_Index", columnNames: "(firstName)"]
};
var indexedDBOptionsObj = {
databaseName: "Example_DB",
databaseVersion: 1,
objectStoreData: {
name: "Main",
keyPath: lastName,
autoIncrement: false
},
objectStoreIndexDataArray: [
{name: "First_Name_Index", keyPath: "firstName", unique: false, multiEntry: false}
],
};
var optionsObj = {
conductDisjointly: false,
webSQL: webSQLOptionsObj,
indexedDB: indexedDBOptionsObj
};
bakedGoods.set({
data: [
{value: {lastName: "Obama", firstName: "Barack"}},
{value: {lastName: "Biden", firstName: "Joe"}}
],
storageTypes: ["indexedDB", "webSQL"],
options: optionsObj,
complete: function(byStorageTypeStoredItemRangeDataObj, byStorageTypeErrorObj){}
});