具有服务器和本地副本的记录的数据库设计

时间:2012-08-14 07:50:01

标签: sql ios sqlite database-design

我正在构建一个iOS应用程序,用于(创建,编辑)与服务器数据库同步的记录(在sqlite中)。如果应用程序中的记录已从服务器下载然后在本地修改,我正在制作副本,因为我希望能够恢复到服务器版本。因此,对于给定的记录ID,我有时可以有两个副本(服务器,本地)。我在设计数据库布局方面寻求帮助。

最初,我使用了两个表 - 一个用于存储服务器记录(通过同步到达),另一个用于存储本地修改/本地创建(尚未同步)的记录。我发现这种方法很麻烦,因为(a)我需要进行聚合搜索(选择优先考虑本地修改副本的记录),(b)我需要将数据从一个表移动到另一个表,这听起来不像一个好的做法,(c)模式非常复杂(数百列)并且难以保持两个表模式同步。

然后我将所有内容合并到一个表中,添加状态列(服务器/本地)。这似乎很好,直到我意识到过滤重复记录(存在服务器和本地副本的那些记录)的复杂程度。计算,搜索,选择所需的10行复杂查询(由于sqlite的限制) - 请参阅我的其他问题herehere

我正在考虑将所有内容保存在一个表中,但放弃状态列,并创建一个单独的表来跟踪状态,每个记录一行,如下所示:

数据:

id    recordID  name                                 col2   col3   ...
1     1001      Server record, not changed locally   xxxx   xxxx   ...
2     1002      Server record changed locally        xxxx   xxxx   ...
3     1002      Server record changed locally        xxxx   yyyy   ...
4     1003      Record created locally               xxxx   xxxx   ...
5     1004      Server record changed locally        xxxx   xxxx   ...
6     1004      Server record changed locally        xxxx   yyyy   ...

状态跟踪:

id    recordID  server  local
1     1001      1
2     1002      2       3
3     1003              4
4     1004      5       6

聚合上述信息以显示将意味着显示本地记录(如果有)或其他服务器记录 - 在这种情况下,数据行1,3,4和6.在这种情况下,我的查询将更简单(只是与案件的联合)。

这是最好的方法,还是我应该使用更好的设计?

1 个答案:

答案 0 :(得分:1)

我将摆脱本地/服务器状态字段并引入时间戳/版本字段,一旦双方中的一方改变记录,该字段将设置为当前日期。因此,您始终知道哪些行是最新记录(具有最高时间戳的记录)。为了恢复旧版本功能,我考虑提供退回/转发记录的一个版本的选项。如果用户选择了一个旧版本来恢复,我将使用当前时间戳保存该版本的新副本。

您可以通过在协议上传输全部或部分(未知时间戳)记录来实现轻松同步。考虑在客户端和服务器端转储给定表的时间戳列表,比较增量上的列表并为另一方准备插入语句。瞧,同步完成。您唯一需要考虑的是您不更新行,而是创建带有新时间戳的新版本。

这是数据仓库系统中的最佳实践。 (没有更新哲学)

如果您发现每条记录有大量版本,如果有N个较新版本,您可能会定期丢弃最旧的记录。