场景
客户端A不定时地把本地数据同步到server上,然后另一个客户端B(app)从server把数据同步下来,汇总展示
客户端A数据结构
原始的数据(来自客户端A),每条都有create_time和modify_time,用于表示这条记录的创建时间和修改时间。同时系统里还有latest_backup_time字段,用来表示上次备份的时间。客户端每次备份,都会以这3个字段作为条件,找出需要备份的数据,上传到server
服务端数据结构
由于历史遗留问题,服务端收到备份数据之后,没有做其他的处理,而是直接写入数据库
客户端B同步逻辑
客户端B有latest_sync_time字段,用于表示最后一次从server同步的时间。这个字段是每次同步之后,服务端确定并返回的,客户端把这个时间戳记下来。请求同步时,再带上这个时间戳。然后服务端就以create_time,modify_time,latest_sync_time这3个字段作为条件,找出需要下发的数据,返回客户端B
查询哪些数据需要下发的逻辑是:
这个方案的关键是,如何确定latest_sync_time。由于create_time和modify_time都是客户端A的本地时间,服务端也没有字段表示服务端入库的时间,所以服务端返回latest_sync_time到客户端B的时候,不能用服务器接收到同步请求的时间,而要用本次查询到的数据中,最后的create_time或modify_time
其他方案
上面这个方案主要在确定latest_sync_time的时候比较麻烦。根源在于服务端入库的时候,没有把入库的服务端时间保存下来。如果在服务端有sync_time,那么比较起来就很容易,只要找到sync_time在latest_sync_time和now之间的数据就可以了。这些数据就是从上次同步到当前时刻的新数据,然后只要把当前的时间,放在响应里一起返回客户端,客户端刷新latest_sync_time就行了
另外,上面这个方案把判断insert和update的逻辑也放在了服务端。其实服务端也可以把满足的数据直接发回客户端B,然后在客户端判断id是否存在,就可以确定该数据是新增的,还是需要update的
这个方案感觉会更简单,而且由于sync_time是由服务端控制的,也可以避免由于客户端A修改本地系统时间引起的逻辑错误,应该是一个更优的方案。但是由于现在server里已经存在没有记录sync_time的历史数据,迁移起来比较麻烦,而且这种方案也需要改动server现有的备份逻辑,所以最后还是决定采用第一种方案。新开发的系统,建议采用第二种方案
一种客户端同步server数据的方案