字节面试被问到“手机号存储选 Int 还是 String”!
最近,一位粉丝告诉我,他在面试字节时,被问到了一道存储手机号的问题:用 int
还是 string
,用 varchar
还是 char
?
这道题虽然看似简单,但其实是面试官隐形考察业务扩展性、数据容错性和全面思维的关键。
结果,他的回答让面试官脸色凝重,最后没通过。
所以,今天我也来跟大家聊聊这个问题,带大家一起来理清思路,教你如何在面试时留下深刻印象。
-01-
用 Int
存储存在哪些问题?
1 int
存不下 11 位的手机号?
首先,我们都知道手机号是 11 位数字,比如 13728199213
。
但如果用 int
类型,它的范围只有 2,147,483,647,远远无法存下 13728199213
。因此,根本不适合存储手机号。
要存得下,需要用 64 位
的 Long
类型,或者数据库中的 bigInt
。但是,直接用 Long
存真的没有问题吗?
2 数据完整性问题:前导零丢失
例如手机号 01324567890
,用 Long
存储时,前导零就丢失了,变成了 1324567890
,这严重影响数据的完整性。
再者,手机号可能包含国家代码如 +86
,或者有分隔符如 137-2819-9213
,这些都无法直接存入整数类型中。
3 查询问题:模糊查询成本高
假设你要查找 137
开头的手机号,如果用 BigInt
(Long
类型),你需要先将它转为字符串,再进行模糊查询。这会大大增加查询的复杂度和性能损耗。
-02-
选用 String
存储手机号
用 String
存手机号的好处
保真:数字、符号、前导零都能完整存储。
灵活:支持模糊查询、国际号码,且未来扩展无忧。
省心:无需担心溢出或格式转换问题。
String
的存储示例
CREATE TABLE user_table (
id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '用户ID',
phone_number VARCHAR(20) NOT NULL COMMENT '手机号',
PRIMARY KEY (id),
UNIQUE KEY idx_phone (phone_number)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='用户表';
-03-
面试官的隐藏考察点
这道题不仅是对技术的考察,更考察你在设计数据库时的全面性思考,尤其是如何考虑
业务扩展性和数据容错性。
1 为什么 VARCHAR(20)
而不是 VARCHAR(11)
?
我们知道,手机号通常是11位,但为何用 VARCHAR(20)
作为字段长度,而不是 VARCHAR(11)
?
业务扩展性: 不仅仅是手机号
假设未来你需要支持:
国际号码(如
+8613822223333
,14位)带国家码的号码(如
008613822223333
,15位)分机号(如
13822223333#123
)
如果用 VARCHAR(11)
,这些情况都会导致存储错误。而 VARCHAR(20)
可以轻松兼容各种国际化需求,支持更长的号码和格式,避免后期修改表结构。
数据容错性: 用户输入的不可控性
用户输入的手机号可能带有空格、符号(如 138 2222 3333
或 137-2222-3333
)。如果字段长度过小,直接存储会导致数据截断,反而不利于清洗。
2 直接用 VARCHAR(11)
?
设计妥协:如果强制使用
VARCHAR(11)
,你需要在代码层进行严格过滤,增加了复杂度和错误的可能性。
3 存储成本的考量:
VARCHAR(11)
最大占用 11 字节,VARCHAR(20)
最大占用 20 字节,两者差异不大,并且与BIGINT
对比,总体差距可忽略不计。
-04-
日常开发避坑
1 字段长度设计过小
如果你硬要用 VARCHAR(11)
存纯手机号,碰到国际号、分机号等情况会直接崩盘。使用 VARCHAR(20)
更为灵活。
2 字符集与排序规则选择不当
如果使用 utf8
字符集,无法存储 Emoji 或特殊符号。如果需要兼容所有 Unicode 字符,utf8mb4
是更优选择。
3 索引设计不当
在手机号字段上没有加上唯一索引,可能导致重复数据。记得加上唯一索引,避免数据重复问题。
ALTER TABLE user_table ADD UNIQUE INDEX idx_phone (phone);
4 数据清洗与校验缺失
用户输入的手机号可能有空格、横杠等符号。建议入库前进行统一清洗,并使用正则校验格式。
String regex="^+?\\d{8,20}$"; // 允许带 + 号的 8~20 位数字
5 隐私与安全
明文存储手机号会泄露用户隐私。务必使用加密存储,并在显示时进行脱敏处理。
SELECT AES_ENCRYPT(phone_number, 'encryption_key') FROM user_table;
总结:思考全局,精确落地
用
String
存手机号的优点:保真、灵活、省心。VARCHAR(20)
优于VARCHAR(11)
:为未来扩展留余地,避免格式问题。面试官看重的:业务扩展性、数据容错性、存储成本等综合考虑,体现你的全局思维。
面试时,如果你能展现出如此全面的思维,面试官肯定会对你刮目相看。别忘了,回答问题不仅是给出“对”的答案,更是展现你的思维深度与业务敏感度!