Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/database/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 同步客户端服务器数据库_Sql_Database_Design Patterns_Client Server_Data Synchronization - Fatal编程技术网

Sql 同步客户端服务器数据库

Sql 同步客户端服务器数据库,sql,database,design-patterns,client-server,data-synchronization,Sql,Database,Design Patterns,Client Server,Data Synchronization,我正在寻找一些通用策略,用于将中央服务器上的数据与不总是在线的客户端应用程序同步 在我的例子中,我有一个带有sqlite数据库的android手机应用程序和一个带有MySQL数据库的PHP web应用程序 用户将能够在电话应用程序和web应用程序上添加和编辑信息。我需要确保,即使手机无法立即与服务器通信,一个地方所做的更改也会反映在任何地方 我不关心如何将数据从手机传输到服务器,反之亦然。我之所以提到我的特殊技术,只是因为我不能使用MySQL的复制功能 我知道客户机-服务器数据同步问题已经存在很

我正在寻找一些通用策略,用于将中央服务器上的数据与不总是在线的客户端应用程序同步

在我的例子中,我有一个带有sqlite数据库的android手机应用程序和一个带有MySQL数据库的PHP web应用程序

用户将能够在电话应用程序和web应用程序上添加和编辑信息。我需要确保,即使手机无法立即与服务器通信,一个地方所做的更改也会反映在任何地方

我不关心如何将数据从手机传输到服务器,反之亦然。我之所以提到我的特殊技术,只是因为我不能使用MySQL的复制功能


我知道客户机-服务器数据同步问题已经存在很长很长时间了,我希望获得有关处理该问题的模式的信息(文章、书籍、建议等)。我想了解处理同步的一般策略,以比较优势、劣势和权衡。

您首先要确定的是一个一般策略,即在发生冲突的更改时,哪一方被认为是权威的

例如:假设服务器上的记录125在1月5日晚上10点被更改,而其中一部手机上的记录被更改,那么让我们在1月5日晚上11点将其称为客户端A。 最后一次同步是在1月3日。然后用户在1月8日重新连接

确定需要更改的内容很容易,因为客户端和服务器都知道上次同步的日期,所以创建或更新的任何内容都需要核对,请参阅下文了解更多信息,因为上次同步需要核对

因此,假设唯一更改的记录是125。 您可以决定两个版本中的一个自动获胜并覆盖另一个版本,或者您需要支持协调阶段,用户可以在该阶段决定哪个版本的服务器或客户端是正确的,覆盖另一个版本

这个决定非常重要,你必须权衡客户的角色。特别是当客户机和服务器之间存在潜在冲突,而且不同的客户机可以更改相同的记录时

[假设第二个客户端B可以修改125,则尚未同步的客户端B可能会提供同一记录的另一个版本,从而使以前的冲突解决变得毫无意义]

关于上面创建或更新的点。。。如果某个记录源于某个客户机,并且假设这在您的问题域中是有意义的,那么如何正确地识别该记录? 假设你的应用程序管理一个商业联系人列表。如果客户端A说您必须添加一个新创建的John Smith,而服务器有一个昨天由客户端D创建的John Smith。。。你是否因为不能确定他们不是不同的人而创建了两个记录?您是否也会要求用户协调此冲突

客户是否拥有数据子集的所有权?即,如果客户B被设置为区域5的数据管理机构,客户A是否可以修改/创建区域5的记录?这将使一些冲突的解决变得更容易,但可能对您的情况不可行

总而言之,主要问题是:

考虑到分离的客户端在创建新记录之前可能尚未访问服务器,如何定义标识。 以前的情况,无论解决方案多么复杂,都可能导致数据重复,因此您必须预见如何定期解决这些问题,以及如何通知客户他们认为的记录675实际上已与记录543合并/被记录543取代 决定是否由fiat解决冲突,例如,如果服务器版本自上次同步后已更新或通过手动干预,则服务器版本始终优于客户端版本 在菲亚特的情况下,尤其是如果您决定客户机优先,您还必须注意如何处理其他尚未同步的客户机,这些客户机可能会有更多的更改。 为了简化描述,前面的项目没有考虑数据的粒度。我只想说,与其像我的例子那样在记录级别进行推理,不如在字段级别记录更改。或者一次处理一组记录,例如个人记录+地址记录+联系人记录,将其聚合视为一种元记录。 参考书目:

当然,更多关于这一点,关于

作者

奥莱利狩猎之旅

安史斋藤惠普实验室和MARC SHAPIRO微软研究有限公司——ACM计算调查,第五卷,第N期,2005年3月

亚历山大·特拉德、尤尔根·纳格勒·伊莱因、弗兰克·卡格尔和迈克尔·韦伯。2008通过重用SyncML实现循环数据同步。第九届移动数据管理国际会议记录MDM'08。华盛顿IEEE计算机协会 美国华盛顿特区安顿,165-172。DOI=10.1109/MDM.2008.10

林,F.,林,N.,和黄,R.2002。移动XML数据的高效同步。2002年11月4日至9日,美国弗吉尼亚州麦克莱恩第十一届信息和知识管理国际会议记录。CIKM'02。ACM,纽约,纽约,153-160。DOI=

Cunha,p.R.和Maibaum,T.S.1981。资源与公平;抽象数据类型+同步-面向消息编程的方法。1981年3月9日至12日,美国加利福尼亚州圣地亚哥第五届国际软件工程会议记录。软件工程国际会议。IEEE出版社,新泽西州皮斯卡塔韦,263-272

最后三个来自ACM数字图书馆,不知道您是否是会员,也不知道您是否可以通过其他渠道获得这些信息

从网站:

使用SQL Server CE和SQL RDA创建应用程序Bill Wagner 2004年5月19日设计桌面和移动PC应用程序的最佳实践-Windows/.NET 从arxiv.org:

-本文描述了一个JSON CRDT实现—无冲突复制数据类型—CRDTs—是一系列支持并发修改并保证此类并发更新收敛的数据结构。
我建议您在每个表中都有一个timestamp列,每次插入或更新时,都要更新每个受影响行的timestamp值。然后,遍历所有表,检查时间戳是否比目标数据库中的时间戳新。如果是较新的,则检查是否必须插入或更新

观察1:注意物理删除,因为行是从源数据库中删除的,您必须在服务器数据库中执行同样的操作。您可以解决这个问题,避免物理删除或在带有时间戳的表中记录每次删除。类似这样的内容:DeletedRows=id、table_name、pk_column、pk_column_value、timestamp,因此,您必须读取DeletedRows表的所有新行,并使用table_name、pk_column和pk_column_value在服务器上执行删除


观察2:注意FK,因为在与另一个表相关的表中插入数据可能会失败。您应该在数据同步之前停用每个FK。

如果有人正在处理类似的设计问题,并且需要跨多个Android设备同步更改,我建议检查GCM

我正在研究一个解决方案,其中在一个客户端上所做的更改必须传播到其他客户端。我刚刚实现了一个概念验证实现服务器&客户机,它的工作非常出色

基本上,每个客户机都向服务器发送增量更改。例如,资源id ABCD1234已从值100更改为99

服务器根据其数据库验证这些增量更改,或者批准更改客户端处于同步状态并更新其数据库,或者拒绝更改客户端处于不同步状态

如果服务器批准了更改,则服务器会通知其他客户端(通过GCM发送增量更改的客户端除外),并发送包含相同增量更改的多播消息。客户端处理此消息并更新其数据库

很酷的是,这些变化几乎是瞬间传播的!!!如果这些设备在线。我不需要在这些客户机上实现任何轮询机制

请记住,如果设备脱机时间过长,且GCM队列中等待传递的消息超过100条,GCM将丢弃这些消息,并在设备重新联机时发送一条特殊消息。在这种情况下,客户端必须与服务器进行完全同步


另外,请检查以开始使用CGM客户端实现。

这回答了使用Xamarin框架的开发人员的问题,请参阅

使用xamarin框架实现这一点的一个非常简单的方法是使用Azure的离线数据同步,因为它允许按需从服务器推拉数据。读操作在本地完成,写操作按需推送;如果网络连接中断,写入操作将排队,直到连接恢复,然后执行

实施相当简单:

1在azure portal中创建移动应用程序您可以在此处免费试用

2将您的客户端连接到移动应用程序。

3设置本地存储库的代码:

const string path = "localrepository.db";

//Create our azure mobile app client
this.MobileService = new MobileServiceClient("the api address as setup on Mobile app services in azure");

//setup our local sqlite store and initialize a table
var repository = new MobileServiceSQLiteStore(path);

// initialize a Foo table
store.DefineTable<Foo>();

// init repository synchronisation
await this.MobileService.SyncContext.InitializeAsync(repository);
var fooTable = this.MobileService.GetSyncTable<Foo>();

我建议你也看看。它是一个可用于android系统的SQLite复制库。您可以使用它来同步客户端和服务器数据库,我还建议在服务器上为每个客户端设置单独的数据库。尝试将所有用户的数据保存在一个mysql数据库中并不总是最好的主意。特别是如果用户数据将快速增长。

让我们称之为CUDR同步问题,我不喜欢CRUD-因为创建/更新/删除是写入,应该成对进行

这个问题也可以从“先写在线”或“先写在线”的角度来看待。脱机写入方法存在问题 由于唯一标识符冲突,以及同一事务的多个网络调用增加了风险或成本

我个人认为“在线写作优先”的方法更容易管理,因此它将是唯一的真相来源——其他一切都是同步的。在线写入方法将要求不允许用户先离线写入-他们将通过在线写入获得ok响应来离线写入

他可能会先离线阅读,一旦网络可用,就从在线获取数据,更新本地数据库,然后更新用户界面


避免唯一标识符冲突的一种方法是使用由sqlite生成的唯一用户id+表名或表id+行id的组合。。。然后使用同步布尔标志列。。但注册仍然必须先在线完成,以获得唯一的id,所有其他id都将在该id上生成。。。这里的问题也将是如果时钟不同步-上面提到的人…

谢谢你的回答。我很有兴趣阅读常用/可能的解决方案的优缺点,以及与您概述的问题的比较。我想您已经查阅了Wikipedia及其链接的内容,对吗?+1这是一篇关于这个问题的非常重要的文章。一个缺失点:同步删除记录。我倾向于将删除看作是更新的特例,特别是因为在这种情况下,我倾向于使用逻辑删除而不是物理删除。所以对我来说,在主服务器或从服务器端删除意味着特殊的布尔值被删除标志被翻转得比其他任何东西都多。谢谢。我又添加了一个链接到另一篇文章dr.dobbs,如果我能找到其他内容,我将更新参考书目。时钟必须同步。此外,离线写入方法在应用程序卸载时会出现问题,所有未在线上传的数据将被删除
await this.MobileService.SyncContext.PushAsync();
await this.saleItemsTable.PullAsync("allFoos", fooTable.CreateQuery());