mysql 存电话号码应该用哪个字段_2021-01-06:mysql中,我存十亿个手机号码,考虑存储空间和查询效率,用什么类型的字段去存?...

针对十亿个中国手机号码的存储和查询优化,建议使用bigint类型存储,建立索引。考虑空间节省,可选择varchar类型,但更新可能会导致碎片。数据量大时,建议采用分区,如按范围或哈希分区,提高查询效率。布隆过滤器可进一步提升查询效率,减少误判,通过号码号段分配多个布隆过滤器以增强准确性。
摘要由CSDN通过智能技术生成

福哥答案2021-01-06:

答案来自此链接:

首先提出假设:

考虑一下这几个问题:

手机号码都是数字吗?

都是中国的手机号码吗?

会按照手机号等值查询吗?

会按照手机号范围查询吗?

需要手机号列唯一约束吗?

最简单情况(中国手机号,11位数字)就用数值类型bigint存储即可,建索引。

考虑三种类型,BigInt,Char,Varchar

这几种类型在 InnoDB 引擎下默认行格式的存储方式为:

1.对于 bigint 类型,如果不为 NULL,则占用8字节,首位为符号位,剩余位存储数字,数字范围是 -2^63 ~ 2^63 - 1 = -9223372036854775808 ~ 9223372036854775807。如果为 NULL,则不占用任何存储空间。

2.对于定长字段,不需要存长度信息直接存储数据即可,如果不足设定的长度则补充。对于 char 类型,补充 0x20, 对应的就是空格。

3.数据开头有可变长度字段长度列表,所以 varchar 只需要保存实际的数据即可,不需要填充额外的数据。正是由于这个特性,对于可变长度字段的更新,一般都是将老记录标记为删除,在记录末尾添加新的一条记录填充更新后的记录。这样提高了更新速度,但是增加了存储碎片。

由于手机号不更新,并且不同国家的手机号长度不同,并且可能有特殊字符,字符类型在默认的编码和排序规则下进行范围匹配也能满足我们的需求,所以为了节省空间,使用 varchar 类型。

分区

这个数据量比较大了,需要用分区。phone 可以作为分区键,可以按照范围分区,也可以按照 hash 分区。

这样查询某个手机号是否存在这种业务就能更快,因为一张表被划分成了很多张小表。并且如果涉及多张小表 MySQL 还可以多线程并发查,效率提升很多。如果考虑获取某一号码段的所有手机号,那最好还是按照范围分区,可以使逻辑查询范围更小。但是 hash 分区数据可能比范围分区更加均衡。

注意,对于 HASH 分区个数最好是 2^n。因为对于 2^n 取余相当于对 2^n - 1 取与运算,增加了查询时的计算分区的效率.

进一步优化

对于查询某个手机号是否存在,可以在数据库上层加一层布隆过滤器,提高效率。

同时为了提高准确性,可以通过号码号段,不同号段使用不同的布隆过滤器。在插入数据库的同时,放入布隆过滤器中。如果布隆过滤器中检测不存在,则肯定不存在。为了减少布隆过滤器的误判概率,可以使用更多的布隆过滤器,同时设置交叉范围,例如一个 13000000000~13200000000 用布隆过滤器 A,13100000000~13300000000 用布隆过滤器 B, 13211111111就要经过布隆过滤器 A 和 布隆过滤器 B 的验证。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值