【问题标题】:Wrapper functions for IndexedDBIndexedDB 的包装函数
【发布时间】:2017-09-13 11:09:28
【问题描述】:

我需要为 iPad/平板电脑设备构建一个离线 HTML5 Web 应用程序,用户可以在其中从服务器下载数据集(数据表)并将其存储在设备上。然后,用户可以断开与服务器的连接并在设备上本地查看/编辑数据。这适用于在没有蜂窝网络覆盖且需要收集/更新数据的偏远地区锻炼的人。当他们回到办公室时,他们可以将数据同步/上传回服务器。它需要 HTML5 的原因是它与平台无关,即只要它具有支持 HTML5 的现代网络浏览器,它就可以在 iOS、Android 等上运行。

现在我已经使用 HTML5 本地存储(用于数据)和 HTML5 离线应用程序缓存(用于 pages/css/js/images)构建了系统,并且它适用于小型数据集(我可以查看,离线时编辑和保存,在线时加载/同步)。现在我需要扩展到 10,000 行数据。它可以工作,但速度很慢,并且在英特尔四核 8GB 机器上加载时会挂起浏览器 10 秒。

所以我一直在研究一些比本地存储更好的替代方案:

1) WebSQL:将能够使用 SQL 语言查询数据并进行连接等。问题是它现在已被弃用,不再受支持,所以我不想花时间为它构建东西。

2) IndexedDB:使用对象存储(从技术上讲,我已经使用本地存储 API 存储对象并使用 JSON 存储)。可能更快,因为它使用带有 SQL lite 后端的索引。有很多样板代码可以完成简单的任务,例如创建数据库、添加数据库、读取数据库、迭代数据库。我只想做一个简单的查询,比如select(xyc, abc).where(abc = 123).limit(20),但必须编写大量的 JavaScript 代码来完成它。如何编写自己的代码在表之间进行连接,任何地方的示例?

我找到了一个jQuery plugin,它可能会让生活变得更简单。周围是否有其他库或其他库可以减轻使用 IndexedDB 的痛苦?

非常感谢!

【问题讨论】:

  • 我相信 WebSQL 已经被 IndexedDB 抛弃了...
  • 注意 WebSQL,Apple 5.0.1 不再保留 WebSQL 数据。换句话说,这将削弱您应用程序的本地数据库。 Phonegap 有一个解决方法。 issues.apache.org/jira/browse/CB-330

标签: javascript jquery local-storage indexeddb web-storage


【解决方案1】:

我有一个支持 IndexedDB 和 WebSql 的开源 web database wrapper

版本迁移是在感觉之后处理的。以下代码迁移(或初始化)到版本 2。

schema_ver2 = {
    version: 2,
    size: 2 * 1024 * 1024, // 2 MB
    stores: [{
        name: 'ydn_obj',
        keyPath: 'id.value',
        indexes: [{
            name: 'age',
            type: 'INTEGER'  // type is require for WebSql
        }]
    }]
}
db = new ydn.db.Storage('db name', schema_ver2)

Query 非常灵活和强大。例如:

q = db.query('customer').when('age', '>=', 18 , '<', 25).where('sex', '=', 'FEMALE')
young_girls = q.fetch(10, 2); // limit and offset

如果年龄被索引,则再次使用更有效的键范围查询:

q = db.query('customer', 'age').bound(18, 25, true).where('sex', '=', 'FEMALE')

还支持transaction

p123 = db.tkey('player', 123);
db.runInTransaction(function() {
   p123.get().success(function(p123_obj) {
        p123_obj.health += 10;
        p123.put(p123_obj);
   });
}, [p123]);

【讨论】:

    【解决方案2】:

    试试linq2indexeddb。它有你想要的查询接口+indexeddb shim for websql,也支持WebSQL API。

    【讨论】:

      【解决方案3】:

      您考虑过 [Lawnchair][1] 吗?它从底层存储中提供了一个很好的抽象,还有用于查询、聚合和分页数据的插件。以查询为例:

        // basic searching
          this.where('record.name === "brian"', 'console.log(records)') 
          this.where('record.name != ?', username, 'console.log(records)')
      
          // sorting results
          this.where('name === "brian"').asc('active', 'console.log(records)')
      

      我能看到的唯一潜在缺点是它似乎无法处理迁移,并且通用似乎没有创建索引等的方法。

      关于连接,IndexedDB 被设计为面向文档(无 SQL)存储而不是关系数据库,但鉴于这是一种常见情况,似乎有两种选择:

      1) 游标遍历数据项 2)如果上面的速度太慢,您还可以创建一个专用的键值对象存储,然后可以使用它在相关存储中进行索引查找。根据您的加入要求数量,这可能是一件苦差事。

      【讨论】:

      • 谢谢@Sidebp 我已经看过了。它似乎默认支持本地存储。而我更喜欢默认情况下使用 WebSQL,因为它要快得多,但我认为没有更改适配器顺序的选项。 WebSQL 可以在 2 秒内查询 200,000 行。 IndexedDB 需要 15 秒。本地存储在大约 10,000 行后挂起。
      【解决方案4】:

      我认为 JsStore 会为你工作。

      假设您的查询在 sql 中看起来像这样 -

      select * from table_name where column1='abc' limit 20

      JsStore - 会是

      var Connection = new JsStore.Instance("YourDbName");
      Connection.select({
          From: "table_name"
          Where: {
              Column1: 'abc',
          },
          Limit:20,
          OnSuccess:function (results){
              console.log(results);
          },
          OnError:function (error) {
              console.log(error);
          }
      });
      

      因此您可以使用JsStore 编写类似sql 的查询。

      【讨论】:

        猜你喜欢
        • 2013-01-09
        • 2019-12-02
        • 2014-05-18
        • 1970-01-01
        • 2021-02-27
        • 2021-01-07
        • 1970-01-01
        • 1970-01-01
        • 2013-05-23
        相关资源
        最近更新 更多