背景:最近在整一个Android项目,涉及到同一个账号在多端数据库数据同步的问题,其中利用阿里云OSS文件存储作为云存储,再提供一个访问权限管理服务器,然后就没有然后了。
思考过程:要尽可能的减少同步数据传输的大小,即只同步最后一次同步后修改的数据。如果有服务器真是太爽了,可以指哪打哪,但没办法,只能想各种弥补的办法。
方案一:同步整个数据库文件
大致思路:当需要对数据库中的数据进行修改时,首先对比本地数据库的版本和云端数据库版本,如果本地的版本高于服务器上的版本,则把本地的数据库同步到云上;如果本地数据库版本低于云端版本,则把云端数据库同步到本地;在服务器上加入正在修改数据库标识,使得其它应用端不能同时修改;修改本地数据库和数据库版本;把数据库同步到云端。很傻X的做法……
方案二:数据库分片备份
大致思路:是针对方案一的改进,基本上就是减少了同步数据的大小,因为只需要同步你修改的那些片,其它可以不变,但在极端情况下又会和方案一一样,所以可行性仍是不够。
方案三:分类以文件的方式备份数据
大致思路:是对方案二的进一步改进,即对每一种数据的每一条记录进行存储,比如有学生和教师两个表,就有学生和教师两种类别,而学生一的记录为1,学生二的记录为2,当需要修改学生一的数据时,只要同步1文件即可。虽然看似可以解决问题,但导致的文件数非常多,过于细碎,不易管理,整体数据大小不易控制等问题,也不建议采纳。
方案四:备份sql语句
大致思路:即每次修改数据库的数据时,把完全格式化后的sql语句存储到另一个数据库B中表中,同步时(可以根据需求设定周期),先下载最后一次同步之后的所有sql文件,然后依次执行其中的sql语句,然后把B中的所有记录依次放入一个文件中,把文件上传到云上即可。所以每次同步到云上的文件中(本地有修改数据库数据才会同步)的sql语句是>=1条。
流程:申请读权限->同步本地最后一次同步之后的所有sql文件->保持读权限->依次执行同步文件中的sql语句->把本地数据库B中表中的sql语句记录放入一个新的patch文件中(文件名是时间+文件的MD5)->释放读权限->申请写权限->上传patch文件->释放写权限。
PS:其中可以定期的整理sql文件,比如在A时间点,把A时间点之前的sql文件依次执行,生成数据库文件为last.db文件。当A时间点之后有新的客户端同步数据库数据时,可以通过同步last.db加A时间点时候的sql文件方式。
最终方案的优点:
1. 可以很好的保存整个数据库存储的历史
2. 同步数据的大小也尽可能的减少
最终方案的缺点:
1. 当A同步数据到云端时,更新了记录1,而B同时在本地删除了记录1,当B同步数据时,就会在执行更新数据1时发生错误
2. 轮询的同步方式
PS:
小弟第一次写博客,还望各位看官多多包涵,其中有错误和不足的地方还望多多指教,多谢!