我正在写一篇关于 Web 应用程序的离线能力的论文。我的任务是通过具有服务器端关系数据库和客户端和服务器之间的 Ajax/JSON 流量的 Web 应用程序来展示离线存储的可能性。我的第一个实现使用了 localStorage 的方法,将每个 Ajax 响应保存为值,并将请求 URL 作为键。该应用程序运行良好。然而,在下一步中,我想(即论文要求)使用客户端数据库实现更高级的版本。由于服务器维护一个关系数据库,Web SQL 数据库将是直观的选择。但是,正如我们所知,该标准已被弃用,我不想使用未来不确定的技术。因此,我想使用 IndexedDB 来实现客户端数据库逻辑。很遗憾,
我的任务似乎相当简单: 使用 IndexedDB 在客户端实现服务器端数据库,以复制曾经从服务器获取的所有数据。使这变得不那么简单的问题是:
- 服务器端数据库是关系型的,IndexedDB (或多或少)是面向对象的
- 没有直观的方法来同步客户端和服务器端数据库
- 没有直观的方法来实现 IndexedDB 中使用服务器上的外键和 JOIN 实现的关系
现在,我有一个概念,我真的很害怕开始实施。我考虑为服务器数据库中的每个表创建一个对象存储,并手动对不同对象存储中的关系对象进行编程。在我的应用程序中,简而言之,它管理一所大学的课程,我有 7 个对象存储。
我想通过一个来自服务器的 JSON 响应示例来展示我的想法(/* 这些是注释 */):
{ "course": { /* course object */
"id":1,
"lecturer": { "id":"1", /* lecturer object with many attributes */ },
"semester": { "id":"1", /* semester object with many attributes */ },
/* more references and attributes */
}}
使用 IndexedDB 存储数据的算法会将应用于对象存储的每个对象存储在适当的对象存储中,并用对这些对象的引用替换这些对象。例如,上面的课程对象在对象存储“课程”中如下所示:
{ "course": { /* course object */
"id":1,
"lecturer":
{ "reference": { /* reference to the lecturer in the object store 'lecturer' */
"objectstore":"lecturer",
"id":"1" }
},
"semester":
{ "reference": { /* reference to the semester in the object store 'semester' */
"objectstore":"semester",
"id":"1" }
}
/* more references and attributes */
}}
然后使用 IndexedDB 检索数据的算法将执行以下操作(我模糊地想到了一个递归模式):
Retrieve the course object with id=1 from the object store 'course'
For each reference object in the retrieved course object, do
Retrieve the object with id=reference.id from the object store reference.objectstore
Replace the reference object with the retrieved object
很明显,这种实现会非常麻烦,尤其是由于 IndexedDB 的异步特性。它还会导致对数据库的许多不同事务只是为了检索课程对象,并且性能会受到很大影响(我真的不知道 IndexedDB 事务的性能如何)。
我怎样才能做得更好,更简单?
我已经看过这些代表类似问题的线程:link1,link2。我在这些中看不到任何更简单的解决方案。此外,由于几个原因,我宁愿避免使用 IndexedDB 包装器框架。
我还可以想象,对于我的问题,我完全走错了 IndexedDB 的轨道。
编辑:
我最终采用我的方法将引用存储在 IndexedDB 中的对象本身中。在具有大量引用的大量数据的情况下,这可能会导致一些性能问题。然而,如果巧妙地使用,在大多数情况下可以避免大量的迭代和数据库命中,并且不需要将复杂的数据库模式存储在内存或 IndexedDB 本身中。
一般来说,我必须说,我的印象是我在某种程度上误解了 IndexedDB 作为无模式数据库的动态和直接的想法。但无论如何,我用 JavaScript 实现了所有东西,它工作正常,没有任何不一致的机会。