92先比较,再更新,速度极快

Posted 小雷FansUnion

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了92先比较,再更新,速度极快相关的知识,希望对你有一定的参考价值。

一、问题

一个系统,经常需要和上下游同步数据,比如账务dts从crm同步客户数据,新dts从老dts同步用户数据,ehr需要把xx数据写进redis。

二、常见的办法

1、数据库之间的同步

先删除所有数据,再保存所有数据;整体作为一个事务。

问题:速度很慢。如果表的id被其它业务关联了,也不方便。

更好的办法:先从系统的数据库表,查询存在的数据;和需要同步查询的数据作比较, 判断哪些是新增的、哪些是删除的、哪些是修改的。

即:先比较再更新。

2、向es写数据

最差的办法:删除所有数据,重建索引。xx就这么干过?

一般的办法:直接调用es的接口,为所有数据,重建索引。大概有个index方法,传入数据。

更好的办法:先从es查询数据,和数据库的数据做比较,如果变化了,才有必要更新es的数据。

三、初步分析

1、系统的数据变化,通常没有那么多,那么频繁

2、数据库、es的修改删除等操作,尤其是带了事务,会非常慢;而查询是极快的

3、频繁操作数据库,不但自己的系统慢,可能还影响到系统内的相关模块的db访问速度,影响到数据库相关的其它系统服务。

四、代码示例

import java.util.List;

import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.stereotype.Service;

import com.google.common.collect.Lists;

@Service

public class AuthUserService extends MpServiceImpl<AuthUserMapper, AuthUser>

    @Autowired

    private OldAuthUserMapper oldAuthUserMapper;

    // 返回变化的

    public Integer sync()

        Wrapper<OldAuthUser> queryWrapper = Wrappers.query();

        List<OldAuthUser> oldList = oldAuthUserMapper.selectList(queryWrapper);

        AuthUser query = new AuthUser();

        query.setIsDeleted(YnEnum.NO.getCode());

        List<AuthUser> dbList = super.list(query);

        Map<Integer, AuthUser> dbUserMap = ListKit.listToMap(dbList, AuthUser::getOldId);

        List<AuthUser> changedList = Lists.newArrayList();

        for (OldAuthUser oldAuthUser : oldList)

            try 

                one(dbUserMap, changedList, oldAuthUser);

             catch (Exception e)

                log.error("AuthUserService sync error", e);

            

        

        return changedList.size();

    

    private void one(Map<Integer, AuthUser> dbUserMap, List<AuthUser> newList, OldAuthUser oldAuthUser)

        Integer oldId = oldAuthUser.getId();

        AuthUser dbUser = dbUserMap.get(oldId);

        if (dbUser != null)

            boolean changed = changed(oldAuthUser, dbUser);

            if (changed)

                AuthUser newDbUser = newDbUser(oldAuthUser, dbUser);

                newList.add(newDbUser);

                super.updateById(newDbUser);

            

         else 

            AuthUser saveDbUser = saveDbUser(oldAuthUser);

            newList.add(saveDbUser);

            super.save(saveDbUser);

        

    

    private AuthUser newDbUser(OldAuthUser oldAuthUser, AuthUser dbUser)

        AuthUser newDbUser = BeanKit.build(oldAuthUser, AuthUser.class);

        newDbUser.setId(dbUser.getId());

        newDbUser.setUpdateTime(DateKit.now());

        return newDbUser;

    

    private static boolean changed(OldAuthUser oldAuthUser, AuthUser dbUser)

        // str

        if (StringKit.notEquals(oldAuthUser.getUsername(), dbUser.getUsername()))

            return true;

        

        if (StringKit.notEquals(oldAuthUser.getPassword(), dbUser.getPassword()))

            return true;

        

        if (StringKit.notEquals(oldAuthUser.getLastName(), dbUser.getLastName()))

            return true;

        

        if (StringKit.notEquals(oldAuthUser.getFirstName(), dbUser.getFirstName()))

            return true;

        

        if (StringKit.notEquals(oldAuthUser.getEmail(), dbUser.getEmail()))

            return true;

        

        // int

        if (EqualsKit.notEquals(oldAuthUser.getIsActive(), dbUser.getIsActive()))

            return true;

        

        if (EqualsKit.notEquals(oldAuthUser.getIsStaff(), dbUser.getIsStaff()))

            return true;

        

        if (EqualsKit.notEquals(oldAuthUser.getIsSuperuser(), dbUser.getIsSuperuser()))

            return true;

        

        // date

        if (EqualsKit.notEquals(oldAuthUser.getDateJoined(), dbUser.getDateJoined()))

            return true;

        

        if (EqualsKit.notEquals(oldAuthUser.getLastLogin(), dbUser.getLastLogin()))

            return true;

        

        return false;

    

    private AuthUser saveDbUser(OldAuthUser oldAuthUser)

        AuthUser authUser = BeanKit.build(oldAuthUser, AuthUser.class);

        authUser.setId(null);

        authUser.setOldId(oldAuthUser.getId());

        authUser.setCreateTime(DateKit.now());

        authUser.setUpdateTime(DateKit.now());

        authUser.setIsDeleted(YnEnum.NO.getCode());

        return authUser;

    

     

以上是关于92先比较,再更新,速度极快的主要内容,如果未能解决你的问题,请参考以下文章

oracle数据库插入的速度快还是更新的速度快啊

JavaScript注意的地方

Ubuntu16.04 换阿里源

Python

后台代码更新语句要先查询再更新吗?

Python哈希表的例子:dictset