如何高效安全的将资源同步到本地数据库
背景
? ? ? ?現(xiàn)在軟件開發(fā)很多是多系統(tǒng)多模塊,經(jīng)常會遇到要將設(shè)備、人員、區(qū)域等資源同步到本系統(tǒng)數(shù)據(jù)庫保存一份。資源同步常用的方案為全量同步和增量同步結(jié)合的方式,全量同步一般情況下為項(xiàng)目啟動時(shí)和每天定時(shí)任務(wù)去同步所需資源,增量同步一般利用mq去接收資源的變更(增刪改)通知然后修改到本地?cái)?shù)據(jù)庫。這里介紹下如何進(jìn)行高效安全的全量同步。
全量同步
準(zhǔn)備工作:
? ? ? ?假設(shè)要同步的表為region表,關(guān)鍵字段為(id, name, create_time, update_time),其他如(name, type, code)等根據(jù)業(yè)務(wù)而不同。另外創(chuàng)建一張region_temp表字段同region表。
調(diào)用其他系統(tǒng)的分頁接口獲取全量的region資源數(shù)據(jù),并批量插入到region_temp表。
? ? ? ?region_temp表中已有最近同步的全量資源數(shù)據(jù),但是,我們最終的目的是全量更新region表,針對以下場景分別闡述如何更新region表:
? ? ? ?該SQL做的是將新增的數(shù)據(jù)插入到region表中。該SQL將region_temp表與region表左聯(lián)接,左聯(lián)接的結(jié)果再通過region表的id為空條件過濾記錄,region_temp的數(shù)據(jù)較新,因此region_temp中存在而region中不存在的id必然是需要新增到region中的記錄。
? ? ? ?該SQL做的是將修改的數(shù)據(jù)修改到region表,其中,r.update_time < t.update_time的條件考慮到在做凌晨全量同步的過程中,可能發(fā)生了單條記錄的更新操作(增量同步已經(jīng)更新過了),因此,region表的update_time比region_temp表的update_time時(shí)間要早的記錄才需要做批量的update操作,其余的以當(dāng)前region表的記錄為準(zhǔn)。
? ? ? ?該SQL做的是刪除region表需要?jiǎng)h除的記錄。該SQL將region_temp表與region表右聯(lián)接,右聯(lián)接的結(jié)果再通過region_temp表的id為空條件過濾記錄,region_temp中不存在而region中存在的id,便是需要?jiǎng)h除的記錄。若是同步期間新增的記錄,那么,再引入a.create_time <= ${sync_time},即小于等于觸發(fā)同步操作的時(shí)間。
被篩選出來的需要?jiǎng)h除的記錄可以通過spring的event模型發(fā)送內(nèi)部消息,通知其它模塊刪除了region表某條記錄。
偽代碼:
//先清空臨時(shí)表再批量插入同步過來的數(shù)據(jù)baseMapper.deleteTemplateAll();baseMapper.insertBatch(regionList);//執(zhí)行更新baseMapper.insertNew();baseMapper.updateChange();baseMapper.updateDelete();? ? ? ?以上首先將數(shù)據(jù)保存到本地region_temp表,最后再在數(shù)據(jù)庫層面進(jìn)行region表的全量更新(不僅減少了和數(shù)據(jù)庫傳輸?shù)拈_銷,而且更加高效)。若過程中出現(xiàn)獲取全量資源失敗,也不影響region表的正常crud,同時(shí)兼顧到刪除的變更通知。另外,http全量獲取資源的接口返回值中也不需要帶上is_delete的軟刪除字段便可完成同步。
總結(jié)
以上是生活随笔為你收集整理的如何高效安全的将资源同步到本地数据库的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: java8中stream最实用总结和调试
- 下一篇: postgreSQL的索引