【MySQL】如何快速检索邮箱号以及身份证?

本文涉及的产品
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,高可用系列 2核4GB
简介: 【MySQL】如何快速检索邮箱号以及身份证?

前言

无论是公司的项目还是自己的项目,我们都使用到了邮箱这一功能,并且在一些场景下,我们会要求查询指定邮箱号。比如向该邮箱号发送电子邮件,以及使用该邮箱绑定用户信息等,但是邮箱号本身无规律,如果直接查询那么基本都得走全表,这对于我们这种千万上亿级用户的库来说全表肯定是不可能的,所以我们需要一个方法去解决这个问题。

普通索引与前缀索引

我们能想到的最快的优化方式就是为邮箱这个字段创建一个索引。

两种方式,一种是直接创建一个普通的索引,另一种方式是创建一个前缀索引。

普通索引我们知道就会直接把这个字段的值作为我们的索引段,而前缀索引则是以当前字段的值的前x位组成索引段,这意味着可以节省一定的空间。

比如我们的邮箱号为 123456789@qq.com,那么我们使用普通索引则这个索引的内容为:

索引段:123456789@qq.com 数据段:主键id

而如果我们使用前缀索引,并且长度为5则索引的内容为:

索引段:12345 数据段:主键id

这两个索引的区别不仅仅在于长度,还在于前者是完整的,后者是模糊的。

这意味着前者查询到之后可以直接返回到结果集,然后继续向下查询直到数据不匹配,

而后者查询到之后,还需要进行一次回表并且判断邮箱号是否匹配,如果不匹配,那么就继续查找下一条记录。

并且由于使用的是前缀来进行查找,那么同样的前缀但是真正满足我们要查询的数据的行数可能特别少,会增加我们扫描的次数。

也就是,我们使用前缀索引,占用的空间更少了,但是可能会增加额外的扫描次数。

所以,合理的制定前缀的长度是非常重要的,因为这意味着合理的空间占用并且更少的扫描次数。

那么我们再创建索引的时候,更关注的就是前缀的区分度,越高的区分度,意味着重复的键值越少。所以我们可以尝试通过统计索引上有多少个不同的值来判断要使用多长的前缀。

如何制订前缀长度?

那么如何判断前缀长度是否合理?

我使用如下的sql语句先进行一次email这个字段上有多少个不同的值的检索

select count(distinct email) as L from sys_user;

然后,依次选取不同长度的前缀来看这个值,比如我们要看一下 4~7 个字节的前缀索引,可以用这个语句:

select count(distinct left(email,4)) as L4,
    count(distinct left(email,5)) as L5,
        count(distinct left(email,6)) as L6,
            count(distinct left(email,7))  as L7
                from sys_user;

当然,使用前缀索引很可能会损失区分度,所以你需要预先设定一个可以接受的损失比例,比如 5%。然后,在返回的 L4~L7 中,找出不小于 L * 95% 的值,假设这里 L6、L7 都满足,你就可以选择前缀长度为 6。

对覆盖索引的影响

前缀索引不仅仅有可能影响扫描的行数,还会导致覆盖索引也一起失效。

比如如果我们直接创建一个普通索引,查询语句为:

select id,email from user where email = ‘xxxx’

那么对于这条语句,由于索引直接包含了完整的email,并且其数据段就是id,那么可以直接走覆盖索引,可以少一次回表查询。

而如果你创建的是前缀索引,那么即使是一样的查询条件,他也得回表再判断一次数据。

并且即使你把前缀的长度设定为和当前email一样的长度,他也依旧会回表,因为他不能确定是否完全截断了所有的数据。

其他方法

对于检索邮箱号,我们基本的解决方法就是前缀索引了,那么如果我们要检索的是前缀区分度更小的身份证号呢,因为我们知道对于同意省份地区的人,他们的前缀是相同的,比较不同的可能就是生日以及最后4位。

所以对于身份证号,我们可以使用倒序+前缀的方式。

也就是插入身份证号之后先使用reverse方法吧身份证号倒叙,然后取倒叙的前4位作为前缀。

第二种方法是使用crc32函数,我们可以对身份证号取crc32函数得到一个几乎不会重复的hash值,之后查询的时候我们以这个hash值作为索引来查询,当然,为了确保查询正确,我们还需要再后面补上and条件来精确的判断一次身份证,当然由于有了crc32这个hash字段作为索引,所以查询的范围一下子就小了很多了。


相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
6月前
|
关系型数据库 MySQL
Mysql基础第七天,检索数据
Mysql基础第七天,检索数据
49 0
Mysql基础第七天,检索数据
|
6月前
|
SQL 关系型数据库 MySQL
MySQL根据身份证获取省份 年龄 性别
MySQL根据身份证获取省份 年龄 性别
127 0
|
6月前
|
存储 关系型数据库 MySQL
解锁高效检索技能:掌握MySQL索引数据结构的精髓
解锁高效检索技能:掌握MySQL索引数据结构的精髓
|
4月前
|
关系型数据库 MySQL
MySQL 保姆级教程(三):排序检索数据
MySQL 保姆级教程(三):排序检索数据
|
4月前
|
关系型数据库 MySQL 数据库
MySQL 保姆级教程(二):使用 MySQL 检索数据
MySQL 保姆级教程(二):使用 MySQL 检索数据
|
存储 NoSQL 关系型数据库
深入探索地理空间查询:如何优雅地在MySQL、PostgreSQL及Redis中实现精准的地理数据存储与检索技巧
深入探索地理空间查询:如何优雅地在MySQL、PostgreSQL及Redis中实现精准的地理数据存储与检索技巧
2051 0
|
6月前
|
存储 机器学习/深度学习 关系型数据库
为什么Elasticsearch/Lucene检索可以比MySQL快?
为什么Elasticsearch/Lucene检索可以比MySQL快?
130 2
|
6月前
|
关系型数据库 MySQL
Mysql基础第八天,排序检索数据
Mysql基础第八天,排序检索数据
44 1
|
JSON 关系型数据库 MySQL
MySQL全文搜索与JSON支持:高效检索与灵活数据处理
本文深入探讨了MySQL数据库中的全文搜索与JSON支持,通过详细的代码示例,阐述了全文搜索的原理、全文索引的创建,以及JSON数据类型的使用与操作。全文搜索在数据库中的重要性日益凸显,MySQL提供了全文索引来实现高效的文本数据检索,通过MATCH AGAINST语句,可以轻松地进行全文搜索操作。此外,MySQL的JSON支持为半结构化数据的存储和查询提供了灵活的解决方案,您可以存储JSON对象、数组等数据,并使用JSON函数来查询和修改数据。
974 0
|
SQL 关系型数据库 MySQL
【MySQL】一文带你了解检索数据(二)
【MySQL】一文带你了解检索数据(二)
108 0