2011年开发iOS/Android HTML5离线存储解决方案

74
  • 已弃用,不再支持。
  • IndexedDB:

    • 支持大量数据并具有关系性和查询功能。
    • 可以使用复合键索引来提高查询性能。
    • 它是HTML5中的标准规范之一,适用于跨多个平台。

    Cons:

    • 需要一些学习成本,特别是对于没有使用过NoSQL数据库的人来说。
    • 它的语法可能会感到陌生。
  • 符合要求。
  • 查询250,000行数据快速(1-2秒)。
  • 可以创建复杂的查询、连接等。
  • 受Safari、Android和Opera支持,因此可以在iOS和Android设备上使用。
  • 缺点:

    • 自2010年11月起已被弃用。
    • 存在跨目录攻击的安全漏洞。不是一个真正的问题,因为我们不会使用共享托管。

    IndexedDB:

    与本地存储类似的键/值对象存储,但具有索引。

    缺点:

    • 查询200,000行数据运行缓慢(15-18秒)。
    • 无法运行复杂查询。
    • 无法与其他表进行连接。
    • 不受主要手机或平板设备(如iPad / Android)支持。
    • 标准不完整。

    这只留下了实现已弃用的Web SQL方法的选项,这可能只能再使用一年左右。IndexedDB和本地存储目前无法使用。

    我不确定Mozilla和Microsoft如何使Web SQL数据库标准过时,以及为什么W3C允许它发生。据说它们在桌面浏览器市场上占有77%的份额。在高级移动设备上,Mozilla和Microsoft几乎没有影响力,因为Safari、Opera和Android占据了90%以上的市场份额。Mozilla和Microsoft如何能够决定在离线存储最有可能使用的移动市场中应该使用哪种标准毫无意义。

    在关于为什么他们要选择IndexedDB的Mozilla的评论中,主要是关于“开发人员美学”的问题,他们不喜欢在JavaScript中运行SQL的想法。我不相信这个观点。

    1. 目前提出的标准较差,是一种非常基本的NoSQL实现,速度慢且不支持数据库中人们需要的高级功能。建立数据库并获取数据需要大量样板代码,但他们声称人们将编写一些很好的抽象库来提供更高级的功能。截至2011年10月,这些库还没有任何进展。

    2. 他们已经废弃了现有的Web SQL标准,而这个标准实际上是已经在主要的移动/平板浏览器中实现的。然而,他们的“新”的和“更好”的标准在主要的移动浏览器中并不可用。

    3. 作为开发者,未来3-5年我们应该使用什么,才能在IndexedDB规范可能被标准化、具有更多功能、在主要的移动/平板浏览器中得到实现并有一些不错的库可以使事情更容易的时候使用?

    4. W3C应该保持Web SQL Database标准与IndexedDB标准同时推进并修复其中的问题。它已经支持主要的移动平台,并且运行得相当稳定。Mozilla和Microsoft作为占据桌面浏览器份额最多的两家公司居然能够让这一标准被废弃,这是相当可疑的,可能被视为企图阻碍移动Web平台的进步,直到它们能够追赶并提供针对iOS/Safari和Android的竞争解决方案。

      总之,有没有人能够为我的问题提供一种在手机/平板设备上适用于iOS/Android的解决方案?也许是一个漂亮的包装API,可以在后台使用多个数据库实现,并具有查询功能,让您选择哪个数据库具有优先权。我看到了像lawnchair之类的东西,但我很确定它只能默认使用本地存储并回退到其他存储方式。我想我更愿意使用Web SQL(默认情况下)而不是较慢的选项。

      非常感谢任何解决方案的帮助,谢谢!


    5
    写得很好的文章!这是一种情况,原生应用程序在原生与 Web 应用程序之争中毫不费力地获胜——但我知道你不想听到这个。在这种情况下,根据我的了解,Web SQL 是最佳选择——我还会强制用户下载与他们要去的位置相关的行,而不是整个数据库——如果考虑到他们可能需要在连接极差的地方更新,更不用说通过 1/5 大小(不确定您的数据库规模)的数据库进行搜索时速度的提升了。 - amcc
    2
    他们不能“只是修复WebSQL中的问题”,因为标准进展到W3C推荐状态的要求之一是存在“独立且可互操作的实现”。由于规范基本上是“做SQLite所做的事情”,这永远不会发生。 - robertc
    2
    嘿,你刚刚描述了我的期末项目 :) 在我看来,如果你需要离线和良好的性能,有两个选择:1. 使用本地存储并将数据削减到绝对基础。或者2. 构建一个本地应用程序(具有可扩展的UI?),然后将其克隆到其他平台(你已经在第一个平台中设置了规格,因此再次为其他平台开发它会更快)。缺点是你将不得不维护多个版本。 - Michael Olesen
    2
    因为以前他们要求我们拥有的是W3C建议书,而没有任何浏览器实际实现。所有三个浏览器都在使用SQLite。并没有一个SQLite规范,这就是它不是一个良好标准基础的原因之一。 - robertc
    1
    @robertc 你说没有规范是什么意思?它基于 SQL92 标准,只是有一些小的省略。我找到了看起来像规范的这个页面。此外,SQLite 网站上的所有其他文档都有效地构成了规范,不是吗?它还需要什么才能成为有效的规范呢? - zuallauz
    显示剩余7条评论
    7个回答

    18

    我建议查看JayData库,它的确有创建面向移动设备的存储无关数据访问层的确切目的。JayData通过JavaScript Language Query (JSLQ)和JavaScript CRUD支持提供一个抽象层,并使您可以使用不同的离线和在线数据存储类型以完全相同的方式工作。JayData支持处理复杂实体和本地或远程实体关系。

    撰写本文时,JayData支持以下存储或协议:webSQL(sqLite)/IndexedDB/OData/YQL/FBQL。

    JayData的提供程序回退功能可以轻松解决不同系统提供不同存储引擎的特定问题:它将在向消费者代码提供相同API的同时使用它能找到的任何存储层。

    至于WebSQL在2012年被弃用的问题:撰写本文时,WebSQL仍然拥有95%的设备覆盖率,包括三星智能电视和亚马逊Kindle。查看Kindle使用JayData执行WebSQL单元测试


    我同意,JavaScript语言查询支持和提供程序模型使JayData库成为HTML5离线存储解决方案的好选择。 - user1252287
    1
    我很乐意将您的答案作为被接受的答案,因为它听起来正是所需的,但是您是否有大型数据库(例如250,000行)的性能基准?我很想看看它是否可以使用IndexedDB和WebSQL底层存储(取决于设备)处理那么多行,然后计算执行基本的“where”类型查询以根据某些条件查找其中一行所需的时间。 - zuallauz
    2
    @zuallauz,我刚刚做了这样一个基准测试。在使用 Android Nexus 2 上的 WebSQL 中获取 250K 项中的 5-10 项花费了我 60 毫秒,在 Windows Phone 的 Lumia 920 上只需要 25 毫秒(IndexedDB 明显更快)。 - Peter Aron Zentai
    我使用带有索引支持的专业版,并且查询字段利用了该索引。如果没有索引,可能会导致性能大大降低。 - Peter Aron Zentai
    1
    @zuallauz,您说得非常正确,我们会考虑。总的来说,IndexedDB 在所有方面都比 WebSQL 快得多,除了在复杂的多字段查询方面。然而,在插入数据时,WebSQL 可能会比较慢。写操作的事务打开可能会很昂贵(60-120ms)。 - Peter Aron Zentai
    显示剩余2条评论

    13

    我建议你尝试使用CouchBase Lite。它是一个几乎完整的CouchDB实现,可在Android和iOS上运行。

    iOS版

    Android版

    如果你将应用程序包装在类似于PhoneGap的东西中,你可以为两个平台创建本地HTML 5应用程序,并且只需要进行少量的Android/iOS特定编程来实现CouchDB。

    优点:

    • 快速的视图引擎,可查询跨多行数据。
    • 内置简单而强大的复制支持。

    缺点:

    • 键值存储-需要一些时间来适应。

    谢谢,听起来可能可行,但是我认为你需要一个Mac系统来开发并生成相应的密钥等等?我们没有任何Mac电脑。 - zuallauz
    CouchDB很有趣,但我并不认为它的索引(“视图”)更新模型是惰性的(由查询或批处理触发),真正起作用。我见过的大多数应用程序都假定一旦添加了一些数据,就可以高效地查询它,而大多数其他NoSQL数据库则将更多的工作推入写事务中,以便读取事务更快。 - RichVel
    根据我的经验,在移动设备上视图更新从未成为问题。话虽如此,使用CouchDB或TouchDB的最大原因之一是它们具有超强大而简单易用的复制功能。 - rwilliams
    1
    我开始研究CouchDB用于移动设备的复制,但我并不想将服务器数据库暴露给移动设备,也不想在服务器上使用CouchDB来进行复制。因此,我现在正在研究一种名为Simperium的数据同步云服务,详情请见https://simperium.com/和[tag:simperium]。 - RichVel

    6

    我在寻找自己项目的解决方案时进行了更多的研究。看起来这个库非常有前途:http://nparashuram.com/IndexedDBShim/

    它允许使用IndexedDB API,并在幕后使用WebSQL。

    它的测试在最近的iPad、iPhone 5和Android 4.2.2上通过。

    希望这能帮助到某些人。


    虽然来晚了,但我也推荐使用indexeddbshim.js。它可以很好地在Cordova/PhoneGap环境中运行,并为IOS和Android提供单一解决方案。 - Douglas Timms

    2
    我建议您使用Corona。它是一个私有平台,用于跨移动应用程序,支持SQLite。
    优点:
    - 它易于使用,并且对SQLite有很大的支持,无需在Html5存储中进行奇怪的操作。
    缺点:
    - 如果您想在Android市场或iOS市场中使用它,您必须付费。
    以下是他们对此的描述:
    Corona在所有平台上都包括对SQLite数据库的支持。这基于iPhone上内置的sqlite支持和Android上编译的SQLite版本。请注意,这将增加Android二进制文件的大小约为300K。
    SQLite可在所有Android、iPhone和iPad版本以及Corona模拟器中使用...

    2

    我看到过像草椅这样的东西,但我很确定它仅默认使用本地存储并回退到其他选项。我认为我更希望它默认使用Web SQL,然后再选择较慢的选项。

    这是可配置的,每个存储引擎的“适配器”都是独立的,您可以将适配器传递给Lawnchair构造函数,或者在创建库时通过按不同方式连接JavaScript文件来更改其回退到其他存储选项的顺序。例如,对于indexed-db,然后回退到sqlite,再回退到gears sqlite:

    git clone https://github.com/brianleroux/lawnchair.git  
    cd lawnchair  
    cat src/Lawnchair.js src/adapters/indexed-db.js src/adapters/webkit-sqlite.js src/adapters/gears-sqlite.js > my_lawnchair.js
    

    当然,正如其他答案所建议的那样,您可以使用PhoneGap等工具将HTML5包装成本地应用程序,然后您将有很多选择,但如果您想坚持Web标准,那么在我们广泛采用IndexedDB之前,这可能是一个不错的选择。

    1

    值得一看的开源库https://bitbucket.org/ytkyaw/ydn-db/wiki/Home

    JavaScript数据库模块,支持Indexeddb、WebDatabase(WebSQL)和WebStorage(localStorage)存储机制,支持版本迁移、高级查询和事务。

    作为NoSQL库,联接是手动的,但并非不可能。该库已经内置了关键联接算法。


    如果我的代码需要执行SQL查询以检索并排序一些数据,但我的设备正在运行IndexedDB,那么您的库能否将该SQL查询转换为从IndexedDB数据库获取数据的查询? - zuallauz
    我的库中对SQL的支持非常基础。请在这里查看它所能做的内容:http://dev.yathit.com/ydn-db/sql-query.html - Kyaw Tun

    1
    为何不用JavaScript编写一个简单的存储引擎(涵盖“基于标准”部分)?显然您并不需要非常复杂的东西,因此让它工作起来应该不需要太多的努力。
    我会这样做:
    • 将所有内容存储在BSON或类似的二进制格式中。
    • 解析文件并创建索引,并在启动时进行读取。
    • 使用JavaScript查询并从大型文件中读取(离线)Web应用程序。
    • 将更新对象单独存储。
    如果数据库足够简单,则此解决方案仅可行。但是我认为它可能有效 - JavaScript对移动设备的支持很好。
    参考here,这里有一个JavaScript中的Btree+实现,可以获得灵感。
    要读取本地文件,您需要文件API,它可以用于访问本地文件。它在大多数现代浏览器中都得到支持,甚至包括Safari 6。但我无法确定当前的iPhone浏览器是否支持此API。

    JavaScript在手机上如何访问设备的文件系统进行读写操作? - zuallauz
    1
    好的观点。显然,文件API并不像看起来那么远,但我的答案可能过于乐观了。CouchBase看起来更为可靠。 - alexfernandez

    网页内容由stack overflow 提供, 点击上面的
    可以查看英文原文,
    原文链接