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

一、面试现场:一道看似简单却暗藏杀机的题

“20亿手机号,你选int还是string存储?”

这是字节跳动一面的一道真题。一位星球粉丝面试时被问到,支支吾吾答了几句,面试官面色凝重,最后挂了。

说实话,这道题的表面是在考数据类型选择,实际上是在考三个工程思维:业务扩展性、数据容错性、思考问题全面性

下面聊聊我的思路。

二、核心问题:为什么Int/Long都不靠谱

1、Int直接出局

手机号是11位数字,比如13728199213

Java的int是32位,最大值2^31-1 = 2,147,483,647,约21亿。11位手机号最小也是10000000000(100亿),直接溢出。

结论:Int存手机号,从数学上就不成立。

2、Long的隐藏陷阱

那用64位的Long(对应MySQL的BIGINT)总行了吧?

坑一:前导零丢失

比如手机号01324567890,用Long存会变成1324567890。数据完整性直接被破坏。

更麻烦的是,Java不允许前导0的Long整数,编译都过不了:

Long phoneNumber = 01324567890L; // 编译报错

坑二:格式兼容性差

实际业务中,手机号可能带国家代码+86,或者带连字符137-2819-9213。这些Long都存不了。

坑三:查询效率暴跌

要查137开头的号码?用BIGINT得先转字符串再模糊匹配,索引直接失效。

结论:数值型存储破坏数据完整性,String是唯一选择。

三、进阶考察:为什么用VARCHAR(20)而不是VARCHAR(11)

好,确定用String了。面试官紧接着会问:手机号11位,为什么不用VARCHAR(11),而用VARCHAR(20)

这是秀肌肉的时刻。

1、业务扩展性思维

VARCHAR(11)只能存纯11位数字,但业务会变:

  • 国际号码+8613822223333(14位)
  • 带国家码008613822223333(15位)
  • 分机号13822223333#123(超11位)
  • 座机号010-62223333(含横杠)

字段长度提前留余地,避免频繁改表。这是架构师的基本嗅觉。

2、数据容错性思维

用户输入不可控:

  • 带空格:138 2222 3333
  • 带横杠:138-2222-3333

如果强制用VARCHAR(11),得在代码层严格过滤,增加复杂度。留缓冲空间,入库后清洗,更务实。

3、存储成本权衡

有人担心VARCHAR(20)浪费空间。算笔账:

  • VARCHAR(11):最大11字节
  • VARCHAR(20):最大20字节
  • 20亿条数据相差:约18GB

对比BIGINT的16GB,这点成本换取灵活性,完全可接受。

面试官期待的答案公式:

合理长度 = 基础需求 + 国际扩展 + 容错缓冲

4、极端场景补充

如果手机号纯数字且第一位不是0,理论上可以用BIGINT。但加个注释:这是极端场景,生产环境永远不要赌这个假设。

体现思考问题全面性

四、生产环境避坑清单

设计手机号存储,还有这些坑:

1、字符集陷阱

utf8字符集,无法存储emoji或特殊符号。必须用utf8mb4 + utf8mb4_unicode_ci

2、索引设计不当

一定要加唯一索引防重复:

ALTER TABLE user ADD UNIQUE INDEX idx_phone (phone);

3、数据清洗缺失

入库前统一清洗:移除空格、横杠,只保留+和数字。正则校验:^+?\d{8,20}$

4、安全合规忽视

  • 加密存储:AES加密,别明文存
  • 脱敏显示:查询返回138****3333

5、风控校验

严格版(11位纯数字):

"^1(3[0-9]|4[579]|5[0-35-9]|6[2567]|7[0-8]|8[0-9]|9[0-35-9])\d{8}$"

宽松版(允许国际码):

"^(\+\d{1,3})?1(3\d|4[579]|5[0-35-9]|6[2567]|7[0-8]|8\d|9[0-35-9])\d{8}$"

五、总结

这道题考的不是技术选型,而是工程思维

  1. 业务扩展性:字段设计为变化留余地
  2. 数据容错性:接受输入不确定性
  3. 思考问题全面性:成本、场景、极端情况都考虑到

下次设计字段时,多问一句:未来会不会变?

给TA打赏
共{{data.count}}人
人已打赏
Java算法

字符串中数字子串的求和

2022-8-28 21:43:25

Java

Java高级开发工程师

2022-5-5 21:33:19

0 条回复 A文章作者 M管理员
    暂无讨论,说说你的看法吧
个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索