将一个或多个数据库与主数据库同步 - 外键

时间:2010-03-03 14:41:27

标签: database synchronization google-gears

我正在使用Google Gears来离线使用应用程序(我知道Gears已被弃用)。我面临的问题是与服务器上的数据库同步。

具体问题是主键或更确切地说是外键。将信息发送到服务器时,我可以轻松忽略主键,并生成新的主键。但那我怎么知道这些关系是什么。

我考虑过一个解决方案,打赌我需要为每个客户保存所有的pk。将多个客户端与一个服务器db同步的最佳方法是什么。

修改
我一直在考虑它,我猜seqential主键不是最好的解决方案,但还有其他可能性吗?由于可能发生的碰撞,基于时间似乎不正确。

GUID浮现在脑海中,是一个选择吗?看起来在javascript中生成GUID并不容易。

我可以使用自然键或复合键执行某些操作。在我考虑它时,这看起来是最好的解决方案。我可以期待任何问题吗?

4 个答案:

答案 0 :(得分:3)

这不是一个完整的答案,但至少可以为你提供一些想法......

您提出的问题(以及您尝试解决的问题)并非特定于Google Gears,并且对于其他解决方案仍然有效,例如HTML 5或基于系统或Flash /空气。


在几个月前的最后一次ZendCon期间有一个关于该主题的演示文稿 - 这些幻灯片可以在幻灯片中找到: Planning for Synchronization with Browser-Local Databases


通过幻灯片,你会看到关于可能会想到的几种可能性的注释(有些确实出现在你的脑海中或其他答案中)

  • 使用GUID
  • 复合键
  • 主键池(即预先保留一系列键)

当然,对于每一个,都有优点......和缺点 - 我不会复制粘贴它们:看一下幻灯片; - )


现在,在您的情况下,哪种解决方案最好?很难说,实际上 - 你越早思考同步,它就越好/越容易:当应用程序仍然处于设计阶段时,将东西添加到应用程序中要简单得多^^


首先,确定是否:

可能很有趣
  • 您的应用程序通常已连接,并且很少发生断开连接
  • 或者,如果您的应用程序通常已断开连接,并且仅偶尔连接一次。

然后,你要同步什么?

  • 数据?
    • 喜欢“这是该用户发出的所有命令的列表
    • 当每个已断开连接的设备上复制了这些数据时 - 每个设备都可以修改它
    • 在这种情况下,如果一个用户删除一行,另一个用户添加一行,如何知道哪一个拥有“ true ”数据?
  • 或对这些数据采取的行动?
    • 喜欢“我在该用户发出的命令列表中添加一个条目
    • 在这种情况下,如果一个用户删除了一行,而另一个用户添加了一行,则很容易同步,因为您只需要将这两个操作同步到您的中央数据库
    • 但实现起来并不容易,特别是对于大型应用程序/系统:每次执行操作时,都必须记录它!


还有一个我们通常不会想到的特定问题 - 直到它发生:特别是如果您的同步过程可能需要一些时间(如果您有大量数据,如果您不经常同步,。 ..)如果同步在尚未完成时停止怎么办?

例如,如果:

  • 火车上的用户可以使用某些3G卡访问网络
  • 同步开始
  • 有隧道 - 连接丢失。

在大多数情况下,半同步数据可能不太好......

所以,你必须找到解决这个问题的方法:在大多数情况下,同步必须是原子的!

答案 1 :(得分:0)

我想出了以下解决方案:

每个客户端都从服务器获取一个唯一的ID。无处不在引用主键,我使用具有客户端ID和自动增量字段的复合键。

这样,组合是独一无二的,并且易于实现。唯一剩下的就是确保每个客户都获得一个唯一的ID。

我刚发现一个缺点:SQLite不支持复合主键的自动增量,所以我必须自己处理id。

答案 2 :(得分:0)

我会使用与您最新答案类似的设置。但是,为了解决您的自动增量问题,我将在主数据库中使用单个自动增量代理键,然后同时存储客户端主键和客户端ID。这样您就不会丢失或更改流程中的任何数据,而且您还会跟踪数据最初来自哪个客户端。

请务必在客户端Pk,客户端ID上设置唯一索引,以便从任何子表启用引用完整性。

答案 3 :(得分:0)

客户端在断开连接时可以创建多少个对象是否有合理的限制? 我能看到的一个可能性就是创造一种“本地序列”。

当您的客户端连接到中央服务器时,它会获得一个数字ID,比如一个7位数字(服务器将其生成为序列)。

实际的PK创建为如下字符串:895051 | 000094或895051 | 005694其中第一部分是从服务器发送的7位数字,第二部分是由客户端管理的“本地”序列。 / p>

一旦与中心同步,您就可以获得一个新的7位数字并重新启动本地序列。总而言之,这与你提出的建议没有什么不同。它只是使实际的PK完全独立于客户端身份。

另一个好处是,如果你有一个客户端从未连接到服务器的场景,它可以在本地使用000000 | 000094,需要服务器上的新号码并在发送回服务器之前更新其侧面的密钥同步(如果你有很多FK约束,这很棘手,并且不可行)。