你提出的问题不是几段就能回答的,或者简单的回答。不过,这是我的尝试...
首先,您采用的方法存在许多困难:
- 客户端必须始终连接到网络才能创建数据并从服务器接收密钥。
- 如果您确实创建了不同的存储(localstorage 和 REST),则所有需要数据的应用程序代码都必须在两个存储中查找。这显着增加了应用程序每个部分的复杂性。
- 创建行后,如果要创建子行,必须等待服务器返回主键,才能在子行中将其作为外键引用。对于任何中等复杂的数据结构,这都会成为一个沉重的负担。
- 当服务器宕机时,所有客户端都无法创建数据。
这是我的方法。它使用SequelSphereDB,但大多数概念可以在其他客户端数据管理系统中重用。
第一:使用 UUID 作为主键。
大多数客户端数据管理系统应该提供一种生成通用唯一 ID 的方式。SequelSphere 只使用一个 SQL 函数:UUID()。将 UUID 作为每一行的主键允许在任何时候在任何客户端上生成主键,而无需联系服务器,并且仍然保证 ID 是唯一的。因此,这也允许应用程序在“离线”模式下工作,在运行时不需要连接到服务器。这也可以防止停机的服务器使所有客户端停机。
第二:使用一组镜像服务器的表。
这比其他任何事情都更需要简单性。这也是接下来两个基本原则的要求。
第三:对于小型数据集的向下同步,最好从服务器完全刷新客户端数据。
只要有可能,从服务器对客户端上的数据执行完全刷新。这是一个更简单的范例,并导致更少的内部数据完整性问题。主要缺点是传输中的数据大小。
第四:对于大型数据集的向下同步,执行“事务”更新
这是我的方法变得更复杂的地方。如果数据集太大,并且只需要同步更改的行,则必须找到一种根据“事务”同步它们的方法。即:按照它们在服务器上执行的顺序插入/更新/删除,以提供一个简单的脚本来在客户端执行相同的操作。
最好在服务器上有一个表格,记录要同步到设备的事务。如果这是不可能的,那么通常可以使用行上的时间戳将订单记录在服务器上,并让客户端请求自特定时间戳以来的所有更改。大负面:您将需要通过“逻辑”删除或通过在自己的表中跟踪它们来跟踪已删除的行。即便如此,将复杂性隔离到服务器比将其分散到所有客户端更可取。
第五:对于向上同步,使用“事务”更新
这就是SequelSphereDB真正闪耀的地方:它将跟踪对表执行的所有插入、更新和删除,然后在同步时将它们提供给您。它甚至会在浏览器重新启动时执行此操作,因为它将信息保存在 localstorage/indexeddb 中。它甚至可以适当地处理提交和回滚。客户端应用程序可以像往常一样与数据交互,而无需考虑记录更改,然后使用 SequelSphereDB 的“更改跟踪器”在同步时重播更改。
如果您不使用SequelSphere(您应该使用),则在客户端上保留一个单独的表来记录客户端执行的所有插入、更新和删除操作。每当客户端应用程序插入/更新/删除行时,在“事务”表中制作一份副本。在向上同步时间,发送那些。在服务器上,只需以相同的顺序执行相同的步骤即可复制客户端上的数据。
还很重要:始终在从服务器完全刷新客户端表之前执行向上同步。:)
结论
我建议在尽可能多的地方追求简单而不是复杂。使用 UUID 作为主键对此非常有帮助。使用某种“更改跟踪器”也非常有用。使用诸如 SequelSphereDB 之类的工具来为您跟踪更改是最有帮助的,但对于这种方法不是必需的。
完整披露:我与 SequelSphere 公司密切相关,但该产品对于实施上述方法确实不是必需的。