Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

可否为batch_insert增加 insert if not exists 逻辑? #2

Closed
id4alex opened this issue Mar 20, 2017 · 4 comments
Closed

可否为batch_insert增加 insert if not exists 逻辑? #2

id4alex opened this issue Mar 20, 2017 · 4 comments

Comments

@id4alex
Copy link

id4alex commented Mar 20, 2017

因为很多时候有 insert if not exists 批量插入的需求, 是一个很实用功能.

本来这个repo[https://github.com/beihaifeiwu/dolphin] 已经完成了这个功能,但是觉得他的其他功能写的没你的好, 所以恳请您的repo里面添加这项功能.

@itfsw
Copy link
Owner

itfsw commented Mar 22, 2017

你好,我Github邮箱好像出问题了,一直没有收到这个issue,我看了下https://github.com/beihaifeiwu/dolphin上最新的代码逻辑,其实他已经没有再采用insert if not exists 这种逻辑,因为这要求数据库链接配置需开启allowmultiqueries=true批量执行sql,而且代码逻辑上其实是先执行了一个带条件update然后是带条件插入,这个效率不是很高。
所以我还是考虑按最新的实现上使用mysql “on duplicate key update” 语法来增加这种存在即更新的逻辑,当然如果需要继续采用类似upsertByExample这种和MongoDB类似逻辑,我也会添加支持,但默认不开启,需要的话在插件property配置中增加<property name="allowMultiQueries" value="true"/>来开启支持,但不建议使用。

@itfsw
Copy link
Owner

itfsw commented Mar 22, 2017

新版本已出,考虑下你提的需求,可能并不是真的需要类似MongoDB类似upsertByExample这种情况。大多数情况下应该还是根据主键来进行存在即更新操作,所以UpsertPlugin依然只采用MySQL的on duplicate key update 进行实现。
至于upsertByExample实现延后有好的方法时继续跟进。

@id4alex
Copy link
Author

id4alex commented Apr 1, 2017

感谢你的更新. 抱歉我没有说太清楚.

通常会有一些爬虫的功能,一次性获取几百条记录回来,有的记录通常总量在几千万条量级. 通常的逻辑都是每条记录在java中做查询存在就更新,不存在就插入 这样的操作(通常需要2* list.size() 的 jdbc操作数). 我就想着把这部分的功能往下移到mybatis里面通过一次jdbc操作,完成批量操作,效率会有所提升.

生成的批量sql应该下面这样的一个批量sql去一次执行.
update xxx where if not exists(select xxx where id=id1);
insert xxx where if not exists(select xxx where id=id1);
update xxx where if not exists(select xxx where id=id2);
insert xxx where if not exists(select xxx where id=id2);
update xxx where if not exists(select xxx where id=id3);
insert xxx where if not exists(select xxx where id=id3);

但是通常表结构设计longid 自增作为物理主键, xxxx_hashid(例如user_hashid)作为逻辑主键, 一般我会根据hashid去做判断这条记录存在与否,而不是自增ID(longid) .在这样的情况下我们可能就需要多传递一个field_name(xxxx_hashid) 作为 参数进来.

update xxx where if not exists(select xxx where xxx_hashid=id1);
insert xxx where if not exists(select xxx where xxx_hashid=id1);
update xxx where if not exists(select xxx where xxx_hashid=id2);
insert xxx where if not exists(select xxx where xxx_hashid=id2);
update xxx where if not exists(select xxx where xxx_hashid=id3);
insert xxx where if not exists(select xxx where xxx_hashid=id3);

以上是我的一些想法, 不知道我有没有表述清楚, 先提前谢了!

@itfsw
Copy link
Owner

itfsw commented Apr 28, 2017

新快照版本已出,增加插件属性设置为<property name="allowMultiQueries" value="true"/>情况下支持upsertByExample,upsertByExampleSelective操作,但强力建议不要使用(需保证团队没有使用statement提交sql,否则会存在sql注入风险)。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants