我正在开发具有离线数据库存储要求的Web应用程序。长话短说,该应用程序应该能够继续运行:

  • Chrome首选的主要桌面浏览器之一
  • iOS上的野生动物园
  • Android的本机浏览器(基于V8和WebKit)

因此,问题是要选择哪种技术:IndexEdDB或Web SQL数据库?

关于Web SQL数据库,一方面可以在上述任何方案中使用它。另一方面,莫齐拉(Mozilla 工作草案 该规范已达到僵局:

该规范已达到僵局:所有感兴趣的实施者都使用了相同的SQL后端(SQLITE),但是我们需要多个独立的实现来沿着标准化路径进行。在另一个实施者有兴趣实施此规范之前,SQL方言的描述仅作为对SQLITE的引用,该引用是标准不可接受的。如果您是有兴趣实施独立SQL后端的实施者,请联系编辑器,以便他可以为方言编写规范,从而允许该规范继续前进。

IndexedDB是Mozilla提倡的替代性,但它仅在Firefox 4中。微软感兴趣,Chrome也将支持它。我对苹果关于索引的计划一无所知。

我个人倾向于选择Web SQL数据库,但是仅仅因为我习惯了SQLITE,我喜欢SQL的功能和表现力,并且我理解了关系模型。对我而言,索引是一种不确定性。

就是说,我害怕押注错误的马。即使IndexEdDB成为标准,也将继续存在对Web SQL数据库的支持安全吗?

(Couchdb上的注释:您还将其视为替代方案吗?)

有帮助吗?

解决方案

考虑到仅WebSQL支持您列出的所有三个要求,您的选择不应该简单吗?您对Safari或Android的开发路线图没有洞察力,因此请使用可用的东西。

其他提示

好吧,与所有计算机一样,游戏是“抽象”。

如果您可以提出一个适用于SQL商店和密钥/值存储的足够层,那么理想情况下,您可以与问题隔离,并可以支持特定浏览器上的适当实现。如果您的数据模型和访问模式与最低的共同点(即AK/V商店)不符合,那么在此就几乎可以解决您的问题。

如果您可以使用任何一个商店,请在一个不错的访问层上工作,并从该方向解决问题。

请注意,仅仅因为您的后端有AK/V商店,并不意味着您只需要将数据作为AK/V模型建模。本质上,AK/V商店都在后端。如果您没有疯狂的数据,则可以做很多事情。有了大量数据,您可能必须跳过的篮球可能会花费您的性能,而您可能看不到少量数据。一切都取决于。

您的数据库是否超出了密钥/价值存储?如果没有,我找到了许多用于本地浏览器数据库抽象的JavaScript软件包。一个这样的软件包就是Jstore:

http://code.google.com/p/jquery-jstore/

我最近用它来添加本地密钥/值存储。它有充分的文献记载,集成时间可以忽略不计 - 它通过其API支持了一系列存储后端,包括Flash Local Storage。

CouchDB是一个很好的解决方案 - 对于与您的问题不完全一致的问题。查看 Couchone Mobile. 。如果您在规范方面具有一定的灵活性,则不是严格的“ Web应用程序”,但它可能会提供您可以运行的数据库基础。

我的建议是 去索引, ,因为有一个 indexDB polyfill 可用的。

所有支持WebSQL的浏览器都可以支持 indexDB API 这边走。反过来,很难实施,因此,如果您想达到所有了解某些DB API的浏览器,则indexDB是当今的最佳选择。


注意:即使这个问题是旧的,它仍然很重要,因此我认为这个问题的答案值得更新。对不起,只有链接解决方案,所以我只添加了通常持久目的地的链接:W3C和GitHub

有了您对iOS的Safari的要求,除了WebSQL,别无选择。 WebSQL在其他移动浏览器(例如Opera和BlackBerry)中得到了支持。我认为即使他们具有索引eddb,他们也不会删除WebSQL支持。它们是互补的。

另一方面,在浏览器存储战争中,索引dexeddb永远赢得了胜利。 IE和FF只有索引。具有讽刺意味的事实是,FF在SQLITE的顶部实现了索引DB。

我想说的是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);
  });
});

关于此代码的有趣之处在于不涉及序列化。因此,它非常快。

以下示例说明了友谊图查询。 friendship 对象存储只有一个列出的索引字段 friend_list. 。它使用People Object存储键作为离线主键。 people 对象存储有许多属性,其中包括 location 场地。查询是要找到认识的朋友列表 meother_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 使用排序的混合算法查找匹配键,但在这里显示Naive Nested-Loop Join算法。因此,表连接是可能的,但是您必须编码加入算法。但是,诸如Zigzag合并之类的较新算法比SQLite的速度要快,因为所有输入均已排序,光标可以在良好的情况下进步,更重要的是,加入过程可以利用数据库中不在数据库中的外部知识。使用SQL,加入操作是不透明的。

除此之外,索引DB可以使用流媒体和映射/减少处理等技术。

我在2016年回答这个问题(在您问这个问题后5年)以及有关该问题的一切 WebSQL的贬值仍然存在. 。另一方面,IndexedDB, 享受所有主要浏览器供应商的支持.

因此,对于任何可能在这里发现自己做出相同决定的人,请与索引。

但是,正如这里其他人所暗示的那样,这样的决定不一定要做出。可以简单地选择(或制作)库,该库利用客户端计算机上可用的数据库。

焙烤食品 与这里已经有几种方式建议的图书馆不同。最相关的是,它允许使用的存储类型被明确指定,进而允许开发人员将其他因素(例如绩效特征)引入决策过程。

有了它,对数据库类型的任何支持进行存储操作都是...

...指定两个数据库类型的适当操作选项和等效配置:

//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){}
});

它的简单界面和无与伦比的存储设施支持是出于缺乏对某些存储设施特定配置的支持的代价。例如,它不支持使用多列主键在WebSQL表中的存储操作传导。

因此,如果您大量使用这些类型的功能,则可能需要在其他地方查看。

哦,为了完全透明,烤面包是您的真正维护:)。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top