任何人都有关于如何实现一个同时使用localStorage和REST远程存储的数据持久化层的想法或参考:
特定客户端的数据存储在localStorage中(使用ember-data indexedDB适配器)。本地存储的数据与远程服务器同步(使用ember-data RESTadapter)。
服务器从客户端收集所有数据。使用mathematical sets表示法:
Server = Client1 ∪ Client2 ∪ ... ∪ ClientN
一般来说,任何记录对于某个客户端可能不是唯一的:
ClientX ∩ ClientY ≠ 0, ∀ X,Y ∈ [1,N]
以下是一些场景:
- 客户端创建记录。无法在客户端设置记录的ID,因为它可能与存储在服务器上的记录冲突。因此,新创建的记录需要提交到服务器->接收id ->在localStorage中创建记录。
- 服务器上的记录被更新,因此localStorage和服务器中的数据不同步。只有服务器知道这一点,因此架构需要实现推送架构(?)
你会使用两个存储(一个用于localStorage,一个用于REST)并在它们之间同步,还是使用混合indexedDB/REST适配器并在适配器中编写同步代码?
你能看到任何方法来避免实现推(Web套接字,.)?
2条答案
按热度按时间iqih9akk1#
你提出的问题不是几段话就能回答的,或者简单地回答。然而,这是我的尝试...
首先,你们所采取的方法有一些困难:
1.客户端必须始终处于网络连接状态,以创建数据并从服务器接收密钥。
1.如果你做了不同的存储(localstorage和REST),所有需要数据的应用程序代码都必须在两个存储中查找。这大大增加了应用程序每个部分的复杂性。
1.创建行后,如果要创建子行,则必须等待服务器返回主键,然后才能在子行中将其作为外键引用。对于任何适度复杂的数据结构,这都是一个沉重的负担。
1.当服务器关闭时,所有客户端都无法创建数据。
这是我的方法。它使用SequelSphereDB,但大多数概念可以在其他客户端数据管理系统中重用。
FIRST:主键使用UUID。
大多数客户端数据管理系统都应该提供一种生成通用唯一ID的方法。SequelSphere只需要一个SQL函数:UUID()。将UUID作为每一行的主键允许在任何时间在任何客户端上生成主键,而不必联系服务器,并且仍然保证ID是唯一的。因此,这也允许应用程序在“离线”模式下工作,在运行时不需要连接到服务器。这也可以防止服务器宕机导致所有客户端宕机。
第二:使用一组表来镜像服务器的表。
这更多的是对简单性的要求。这也是对接下来的两个基本原则的要求。
第三:对于小数据集的向下同步,最好从服务器端完全刷新客户端数据。
尽可能从服务器执行客户端上数据的完全刷新。这是一个更简单的范例,导致更少的内部数据完整性问题。主要缺点是传输中的数据量。
第四:对于大数据集的向下同步,执行“transmitting”更新
这就是我的方法变得有点复杂的地方。如果数据集太大,并且只需要同步更改的行,那么您必须找到一种方法来根据“transactions”同步它们。也就是说:按照在服务器上执行的顺序执行插入/更新/删除,以提供在客户端上执行相同操作的简单脚本。
最好在服务器上有一个表,记录要同步到设备的事务。如果这是不可能的,那么订单通常可以使用行上的时间戳记录在服务器上,并让客户端请求自特定时间戳以来的所有更改。大负:您需要通过“逻辑”删除或通过在它们自己的表中跟踪它们来跟踪已删除的行。即使如此,将复杂性隔离到服务器也比将其分散到所有客户端更可取。
第五:向上同步使用transmitting更新
这就是SequelSphereDB真正闪耀的地方:它将为您跟踪对表执行的所有插入、更新和删除操作,然后在同步时将它们提供给您。它甚至在浏览器重新启动时也这样做,因为它将信息持久化在localstorage/indexeddb中。它甚至可以适当地处理提交和回滚。客户端应用程序可以像往常一样与数据交互,而不必给予考虑记录更改,然后使用SequelSphereDB的“更改跟踪器”在同步时重放更改。
如果您没有使用SequelSphere(您应该使用),那么在客户端上保留一个单独的表来记录客户端执行的所有插入、更新和删除。每当客户端应用程序插入/更新/删除行时,在“transaction”表中复制行。在向上同步的时候,发送这些。在服务器上,只需按照相同的顺序执行相同的步骤,即可复制客户机上的数据。
另一重要事项:在从服务器完全刷新客户端表之前,始终执行向上同步。:)
结论
我建议在尽可能多的地方追求简单而不是复杂。使用UUID作为主键对此非常有帮助。使用某种“变化跟踪器”也很有用。使用SequelSphereDB这样的工具来跟踪更改是最有帮助的,但对于这种方法来说不是必需的。
完整披露:我与SequelSphere公司关系密切,但该产品实际上并不是实现上述方法所必需的。
cu6pst1q2#
我不知道你的要求是什么,但它不是真实的,直到它击中“真理之源”的数据库。
通过这种方式,您只需编写一个访问本地数据库的中间层,它会处理其他所有事情。您不必为主键使用GUID,SQL Server足够智能,可以为您处理此问题,但这仍然不是一个坏主意。在我们的一个应用程序中,我们在数据库外部公开了一个标识符来标识实体,但在内部使用了一个bigint。这是两全其美的。
祝你好运