福哥答案2021-01-06:

[答案来自此链接:](https://www.zhihu.com/question/438078173)
首先提出假设:
考虑一下这几个问题:
手机号码都是数字吗?
都是中国的手机号码吗?
会按照手机号等值查询吗?
会按照手机号范围查询吗?
需要手机号列唯一约束吗?
最简单情况(中国手机号,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 的验证。
***
[评论](https://user.qzone.qq.com/3182319461/blog/1609888565)

2021-01-06:mysql中,我存十亿个手机号码,考虑存储空间和查询效率,用什么类型的字段去存?的更多相关文章

  1. Mysql 中Left/Right join on后面and和where条件查询的差异-Mysql SQL运算符是有优先级

    一.Mysql中Left/Right join on后面and和where条件查询的差异 1.建两张测试表,一张商户定义表.一张商户操作状态明细表 1)商户定义表 CREATE TABLE hope. ...

  2. 【mysql】mysql中单列索引、联合索引、Join联表查询建立索引 和 EXPLAIN的分析使用

    2.创建联合索引,从坐到右分别为:userid.openId.name   2. #### --------------  多表联合查询 update 2019/03/13  ------------ ...

  3. MySQL中日期与字符串相互转换,并进行日期比较查询

    技术交流群:233513714 1.日期无需转换查询(日期在数据库中的类型为字符串) select * from day where dateTime > '2016-03-15' 2.使用da ...

  4. MySQL中SQL语句2

    上一片介绍了一些基本的SQL的增删改查,这一片会介绍一些进阶的SQL语句使用. MySQL中的视图 视图是什么?当我们总是查询几张表的某个字段时,可以创建一张虚拟表,把这几个字段写入这个虚拟的表,这样 ...

  5. 我的MYSQL学习心得(十六) 优化

    我的MYSQL学习心得(十六) 优化 我的MYSQL学习心得(一) 简单语法 我的MYSQL学习心得(二) 数据类型宽度 我的MYSQL学习心得(三) 查看字段长度 我的MYSQL学习心得(四) 数据 ...

  6. mysql中的sql

    变量 用户变量: 在用户变量前加@ 系统变量: 在系统变量前加@@ 运算符 算术运算符有: +(加), -(减), * (乘), / (除) 和% (求模) 五中运算 位运算符有: & (位于 ...

  7. MySQL 中的临时表

    在使用 explain 解析一个 sql 时,有时我们会发现在 extra 列上显示 using temporary ,这表示这条语句用到了临时表,那么临时表究竟是什么?它又会对 sql 的性能产生什 ...

  8. MySQL中的数据类型以及完整性约束

    数据类型 数据库mysql中也是分很多数据类型的,最常用的就是:数字类型.字符类型.日期类型.枚举与集合类型 一.数字类型: 默认都是有符号的,即正负号,若想无符号,在创建表时加unsigned.指定 ...

  9. Mysql中索引的 创建,查看,删除,修改

    创建索引 MySQL创建索引的语法如下: ? 1 2 3 CREATE [UNIQUE|FULLTEXT|SPATIAL] INDEX index_name [USING index_type] ON ...

  10. mysql中SQL执行过程详解与用于预处理语句的SQL语法

    mysql中SQL执行过程详解 客户端发送一条查询给服务器: 服务器先检查查询缓存,如果命中了缓存,则立刻返回存储在缓存中的结果.否则进入下一阶段. 服务器段进行SQL解析.预处理,在优化器生成对应的 ...

随机推荐

  1. docker安装配置gitlab时的常用命令整理

    1.下载安装dockerapt install docker.io2.服务启动service docker start 3.拉取gitlabdocker pull beginor/gitlab-ce: ...

  2. Spring全家桶

    常用框架的知识点汇总,如图: 一.5个常用的spring框架 ▌1.spring framework 也就是我们经常说的spring框架,包括了ioc依赖注入,Context上下文.bean管理.sp ...

  3. MySQL视频学习 1-18小节

    地址:https://www.bilibili.com/video/av39807944/?p=16 1-15:撘环境.建表.数据类型(https://www.runoob.com/mysql/mys ...

  4. 关于不同平台、环境下64位int型的输入输出方式(转)

    C语言 64位int 定义方式: Linux: long long         Windows:__int64 C语言 64位int 输出方式: Linux: "%lld"   ...

  5. MySQL学习(一)大纲

    1.逻辑架构 参考博客:https://blog.csdn.net/fuzhongmin05/article/details/70904190 最上层为客户端层,并非mysql独有,诸如:连接处理.授 ...

  6. 使用sync.Once实现高效的单例模式

    1. 简介 本文介绍使用sync.Once来实现单例模式,包括单例模式的定义,以及使用sync.Once实现单例模式的示例,同时也比较了其他单例模式的实现.最后以一个开源框架中使用sync.Once实 ...

  7. Mybatisplus标准数据层CRUD功能

    package com.itheima; import com.itheima.dao.UserDao; import com.itheima.domain.User; import org.juni ...

  8. springboot---多环境启动命令格式

    一.多环境命令启动 maven插件中首先clean,再package打包,(修改字符集为UTF-8) 使用cmd命令java -jar s(Tab键自动补全)  -spring.profiles.ac ...

  9. 免费1年服务器,部署个ChatGPT专属网页版

    作者:小傅哥 博客:https://bugstack.cn 沉淀.分享.成长,让自己和他人都能有所收获! 白皮袄个免费1年服务器,部署个ChatGPT专属网页版! api.openai.com por ...

  10. vue中的v-model 与 .sync

    <input v-model="parentData"> //等同于 <input :value="parentData" @input=&q ...