日日操夜夜添-日日操影院-日日草夜夜操-日日干干-精品一区二区三区波多野结衣-精品一区二区三区高清免费不卡

公告:魔扣目錄網為廣大站長提供免費收錄網站服務,提交前請做好本站友鏈:【 網站目錄:http://www.ylptlb.cn 】, 免友鏈快審服務(50元/站),

點擊這里在線咨詢客服
新站提交
  • 網站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會員:747

前言

前陣子項目因業務需要,要對接兄弟部門的用戶數據,因為兄弟部門并不提供增量用戶數據接口,每次只能從兄弟部門那邊同步全量用戶數據。全量的用戶數據大概有幾萬條。因為是全量數據,因此我們這邊要做數據比對(注: 用戶username是唯一),如果同步過來的數據,我們這邊沒有,就要做插入操作,如果我們這邊已經有,就要做更新操作。本文就來聊聊當數據量相對大時,如何進行對比

比對邏輯

因用戶username是唯一的,因此我們可以利用用戶username來進行比對匹配

比對實現

1、方案一:兩層嵌套循環比對

即: 將接口的全量數據和我們數據庫的全量數據進行循環比對

示例

  @Override
    public void compareAndSave(List<User> users, List<MockUser> mockUsers) {
        List<User> addUsers = new ArrayList<>();
        List<User> updateUsers = new ArrayList<>();
        for (MockUser mockUser : mockUsers) {
            for (User user : users) {
                if(mockUser.getUsername().equals(user.getUsername())){
                    int id = user.getId();
                    BeanUtils.copyProperties(mockUser,user);
                    user.setId(id);
                    updateUsers.add(user);
                }else{
                    User newUser = new User();
                    BeanUtils.copyProperties(mockUser,newUser);
                    addUsers.add(newUser);
                }
            }
        }

    }

用這種方法,我在測試環境壓了30萬條數據,比對數據等了大概20分鐘后,直接OOM

2、方案二:使用布隆過濾器

即: 比對開始前,先將我們這邊的數據壓入布隆過濾器,然后通過布隆過濾器來判定接口數據

示例

  @Override
    public void compareAndSave(List<User> users,List<MockUser> mockUsers){
        List<User> addUsers = new ArrayList<>();
        List<User> updateUsers = new ArrayList<>();
        BloomFilter<String> bloomFilter = getUserNameBloomFilter(users);
        for (MockUser mockUser : mockUsers) {
            boolean isExist = bloomFilter.mightContain(mockUser.getUsername());
            //更新
            if(isExist){
               User user = originUserMap.get(mockUser.getUsername());
               int id = user.getId();
               BeanUtils.copyProperties(mockUser,user);
               user.setId(id);
               updateUsers.add(user);
            }else{
                User user = new User();
                BeanUtils.copyProperties(mockUser,user);
                addUsers.add(user);
            }
        }

    }


用這種方法,我在測試環境壓了30萬條數據,比對耗時1秒左右

3、方案三:使用list + map比對

即:比對開始前,先將我們這邊數據存放到map中,map的key為username,value為用戶數據,然后遍歷接口數據,進行比對

示例

  @Override
    public void compareAndSave(List<User> users, List<MockUser> mockUsers) {
        Map<String,User> originUserMap = getOriginUserMap(users);
        List<User> addUsers = new ArrayList<>();
        List<User> updateUsers = new ArrayList<>();
        for (MockUser mockUser : mockUsers) {
             if(originUserMap.containsKey(mockUser.getUsername())){
                 User user = originUserMap.get(mockUser.getUsername());
                 int id = user.getId();
                 BeanUtils.copyProperties(mockUser,user);
                 user.setId(id);
                 updateUsers.add(user);
             }else{
                 User user = new User();
                 BeanUtils.copyProperties(mockUser,user);
                 addUsers.add(user);
             }
        }
    }

用這種方法,我在測試環境壓了30萬條數據,比對耗時350毫秒左右

總結

這三種方案,兩層循環效率是最低,而且隨著數據量增大會有OOM的風險。采用布隆過濾器,存在誤判的風險,為了降低誤判風險,只能降低誤判率,可以通過參數指定,但這也增加判斷時間。用map可以說是效率最好,他本質是將時間復雜度從O(n2)降低到O(n)。不過這種方案可能也不是最優方案,事后和朋友討論下,他說可以用啥雙向指針啥,因為我在算法這方面沒有深入研究,因此本文就沒演示了

demo鏈接

https://github.com/lyb-geek/springboot-learning/tree/master/springboot-comparedata

分享到:
標簽:數據
用戶無頭像

網友整理

注冊時間:

網站:5 個   小程序:0 個  文章:12 篇

  • 51998

    網站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會員

趕快注冊賬號,推廣您的網站吧!
最新入駐小程序

數獨大挑戰2018-06-03

數獨一種數學游戲,玩家需要根據9

答題星2018-06-03

您可以通過答題星輕松地創建試卷

全階人生考試2018-06-03

各種考試題,題庫,初中,高中,大學四六

運動步數有氧達人2018-06-03

記錄運動步數,積累氧氣值。還可偷

每日養生app2018-06-03

每日養生,天天健康

體育訓練成績評定2018-06-03

通用課目體育訓練成績評定