外部输入一字段去查数据库中该字段是否已经存在?

场景:
项目中导入excel表,在处理excel表的过程中,身份证这个字段是需要唯一的,所以在处理excel的时候,需要对这个字段进行数据库中进行查重,看是否存在。但是项目中的这张表有近90万条记录

我想了半天都没有一个效率特别高的办法:
方法一: for循环里面查

for(...){
    // for循环里面查
    select * from user where idCard = ? limit 1
}

但是这样效率会很低,因为每次都要去连接数据库,再查,效率太低,淘汰

方法二:全部查出放内存中,然后内存中for循环比较
但是由于数据量太庞大,放在内存中很不现实

方法三:使用in,先将excel表中的身份证收集起来,然后拼接字符串

select * from user where idcard in (?, ?, ?, .....) limit 1;

但是这样有一个问题,就是in 后面括号中的身份证数量太多了,就算给idCard加了索引也没有用,
还是走全表扫描,效率依旧很低。

有大佬知道有什么比价高效快速的方式解决这个问题吗?想了很久了还是没有特别好的方法。

阅读 5.3k
4 个回答

每条记录存一个身份证号,一个主键id,约么30B的数据,100万条也就30M左右。

excel数据量也很大的话,肯定是放内存中比较最快,弄个内存数据库就是。

首先,应用和数据库建立好连接之后,连接可以重复使用,不用每次都要去连接数据库;
然后,既然身份证这个字段是需要唯一,那么可以为其建立唯一索引,查询的时候,效率并不会低下;
最后,这种判断字段是否存在的情况,不需要(也不应该)返回全部数据,可以这样:

SELECT EXISTS (
            SELECT 1
            FROM your_table_name
            WHERE id_card = ?
            LIMIT 1)

返回的值可使用 boolean 接收,存在返回 true,不存在返回 false

如果是需要插入数据库的话,我觉得可以给身份证号字段加上唯一性约束,然后插入的时候不判重,当插入报了唯一性错误的时候,记录这些出错的记录就行了。
如果不是插入的话,可以借助redis来实现,提前将已有的身份证号数据在redis中存一份,后续先取redis的数据进行查重处理,还可以借助布隆过滤器

身份证号字段建立唯一索引,mysql有个ON DUPLICATE KEY UPDATE语句,批量插入更新

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题