20亿手机号存储选择int还是string

在20亿规模场景下,手机号应使用字符串而非整型存储,并优先选择VARCHAR(20)以兼顾数据保真、国际化兼容、查询灵活性与业务扩展性。

post

Vitah Lin

1 min read
0

/

面试题

20 亿手机号存储,选 int 还是 stringvarchar 还是 char?为什么?

思路

  • 20 亿数据,用 Int 存储存在哪些问题?
  • 面试官的隐藏考察点
  • 日常开发避坑点

用 Int 或者 BigInt 有哪些问题

我们都知道手机号,是 11 位的数字,比如 13728199213 .

在 Java 中,int 是 32 位,最大值为 2^31 - 1 = 2,147,483,647。约等于 2×10⁹。显然,如果用 int,根本存不下 11 位的手机号码

要想存得下,得用 64 位的 Long 类型,也就是对应数据库的 bigInt

例如手机号 01324567890,用 Long 存会变成 1324567890,直接破坏数据完整性。 并且,有时候,有些手机号可能包含国家代码如 (+86),或者有些时候,是有连字符的,比如 137-2819-9213 . 这些原因都导致不能用整型类型存储。

比如,你要查找,手机号是 137 开头的手机号号码,如果用 BigInt (Long 类型)需先转字符串再模糊匹配,效率暴跌。

用 string 的好处

  • 保真:数字、符号、前导零全能存,原样保留。
  • 灵活:支持模糊查询、国际号码,扩展无忧。
  • 省心:无需担心溢出或格式转换问题。

为什么用 VARCHAR(20) 而不是 VARCHAR(11)?

因为我们都知道,手机号是 11 位的,为什么不直接用 VARCHAR(11) 呢?

如果你日常开发中,就有思考数据容错性习惯的话,就会想到:

  • 如果遇到国际号码:+8613822223333(14 位)
  • 带国家码的号码:008613822223333(15 位)
  • 分机号:13822223333 #123 (超 11 位)

这些场景,都会导致 VARCHAR(11) 报错崩盘。

其次就是业务扩展性思考:VARCHAR(11)只能存纯 11 位数字,假设未来业务需要:

  • 支持座机号(如 010-62223333,含横杠)
  • 支持虚拟号(如 17012341234-5678)
  • 支持其他登录方式(如邮箱+手机号混合存储)

因此,字段长度和类型需提前为业务变化留余地,避免频繁改表。这就是日常开发中的,业务扩展性思维思考。

还有数据容错性思考

  • 输入不可控性:用户可能输入带空格/符号的号码(如 138 2222 3333),直接存原始值更方便清洗。
  • 设计妥协:若强制用 VARCHAR(11),需在代码层严格过滤非数字字符,增加复杂度。

还有思考问题全面性,比如存储成本思考

  • VARCHAR(11):最大占 11 字节(utf 8 mb 4 下 1 字符占 4 字节,但数字和+号只占 1 字节)
  • VARCHAR(20):最大占 20 字节
  • 20 亿数据相差仅约 18 GB(和用 BIGINT 的 16 GB 对比,总成本仍可接受)。

Don't miss these

0
TCP发送缓冲区

·2 min read

#Network/Linux
0
字节序

·2 min read

#Network/C/Linux