我的任务似乎相当简单:使用IndexedDB在客户端上实现服务器端数据库,以复制曾经从服务器获取的所有数据。这使得任务变得困难的问题有:
- 服务器端数据库是关系型的,而IndexedDB是(或多或少地)面向对象的
- 没有直观的方法来同步客户端和服务器端数据库
- 没有直观的方法在IndexedDB中实现在服务器上使用外键和JOINs来实现的关系
现在,我有一个想法,但我真的很害怕开始实施。我考虑为服务器数据库中的每个表创建一个对象存储,并手动编写不同对象存储中的关系对象。在我的应用程序中(简而言之,管理大学课程),我将有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": { /* 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实现了所有功能,它可以正常工作,并且没有任何不一致性的机会。