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

这个问题,说实话是那种看起来简单,其实越想越拧巴的典型代表——“面试官:20亿手机号存储选 int 还是 string?varchar 还是 char?为什么?”

先别急着答,咱慢慢捋一捋。要不然分分钟被面试官带沟里。

首先,很多同学第一反应是:“手机号不就是数字么?int不香吗?”兄弟,想想咱平时手机号写着写着就得加个区号,国际号啥的,甚至有些国家的手机号前面有“+”,你这int存个“+”试试?直接寄。

再来,int 的最大值是 2^31 - 1,也就是 2147483647,手机号动不动就是 11 位数,一些国家甚至更长(比如印度13位),你用int存简直是请Bug来跳舞。不信你试试这段代码:

public class PhoneTest {
    public static void main(String[] args) {
        int phone = 13812345678; // 编译直接报错:整数太大
        System.out.println(phone);
    }
}

👆你看,连Java编译器都不让你犯这个错。

那用 long 行不行?行是行,但你得注意几个点:

  • long 最大值是 2^63-1,能装得下手机号。

  • 但你要是跨国业务、搞啥国际化,就不够用了,手机号可能带国家码、前缀符号(+)啥的,那你这玩意儿还能叫号码?

讲真,我在一个金融项目里踩过坑,客户手机号有“+86”、“+44”,存long的话只能先strip(去掉符号和前缀),结果后来有个需求要显示原始手机号,一堆数据直接没法还原...最后我们一怒之下,全转string了。

说到string,那varchar和char怎么选?

这俩的区别是老生常谈了:

  • char(N):定长,不足补空格;

  • varchar(N):变长,实际占多少就存多少。

你可能会说,手机号都是11位的,char不是更好?我劝你别太天真...

虽然手机号长度表面上看似固定,但:

  • 未来不确定,比如有些国家扩展到了12位;

  • 有些业务系统手机号会带前缀,存的是“+8613812345678”,你char(11)够用吗?

  • 用char会不会浪费空间?当然会,如果你按char(20)来定义,那实际用11位,空着9位,每条记录浪费9字节,20亿条记录就是180G,谁来背这口大锅?

varchar就灵活多了,真正用多少存多少,字段长度设成20甚至30都不怕,多余的不占空间。现在的存储系统处理varchar也没以前那么慢,别被“char快”这个老黄历洗脑了,那都是老掉牙的理论了。

我之前做CRM系统优化时,客户数据里有手机号、邮箱、微信ID,我们一开始偷懒用char(50)统一搞定,结果数据库膨胀得像吃了膨化剂...后来改成varchar,容量直接缩了三分之一,查询速度还提升了(索引页小了,缓存更快了)。

还有一个很重要的点:你是不是要对手机号建索引?如果建索引,varchar和char在B-Tree结构上的存储方式就影响很大了。char会多占空间,影响索引层级深度,导致查询IO变多。

那你说用string/varchar,那性能会不会差?以前可能是,但现在数据库的优化做得越来越好了,字符串的性能瓶颈没那么大了,反而因为灵活性和可扩展性成了首选。

讲真,现在谁还在用char存手机号,十有八九是祖传数据库结构没敢改。

当然了,也不是说string就是银弹。要是你做的是那种极端优化场景,比如电信级别的C级应用,手机号作为主键高频操作,每秒几百万TPS,那你可能要考虑“压缩存储”、“phone number normalization”等骚操作,甚至把手机号转成hash做存储,那就是另外一套玩法了。

不过多数业务场景,varchar完全够用了,简单可靠,迁移扩展也方便。

总结一下哈,选型我个人是这么认为的👇:

  • int/long:不靠谱,除非你只做中国本地且只存纯数字,还得小心前导0被吃掉;

  • char:能不用就别用,浪费空间还不灵活;

  • varchar:推荐首选,灵活,兼容性强,未来扩展也不慌。

最后扯一嘴题外话,很多面试官问这个问题,其实根本不在乎你说的是int还是string,他是想看看你对存储结构、扩展性、性能的综合理解。所以回答时千万别上来就说“我选int,因为int效率高”,这会让人觉得你经验太少、考虑问题太表面。

面试不是答标准答案,而是看你能不能从实际业务出发,做出有依据的技术决策。

说到底嘛,技术选型这事儿,没有绝对的对和错,只有是否适合场景。别为了“省几个字节”搞得数据还原不了,那就真成笑话了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值