自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

字節(jié)一面:20億手機(jī)號存儲選int還是string?varchar還是char?為什么?

開發(fā) 前端
在Java中,int是 32位,最大值為 2^31 - 1 = 2,147,483,647。約等于 2×10?。顯然,如果用int,根本存不下 11位的手機(jī)號碼。 要想存得下,得用64位的Long類型,也就是對應(yīng)數(shù)據(jù)庫的bigInt。

前言

大家好,我是田螺。

最近一位星球粉絲說,他去面試了字節(jié),問了這么一道題,20億手機(jī)號存儲,選int還是string?varchar還是char?為什么?

他支支吾吾回答了幾句,好像看起來,面試官面色凝重,對他不是很滿意,果然最好還是掛了。。。

本文跟大家聊聊我的思路。

  • 20億數(shù)據(jù),用Int存儲存在哪些問題?
  • 面試官的隱藏考察點
  • 日常開發(fā)避坑點

1. 20億數(shù)據(jù),用Int或者BigInt能有在哪些問題?

1.1 int存得下11位數(shù)字嘛?

首先,我們都知道手機(jī)號,是11位的數(shù)字,比如13728199213.

在Java中,int是 32位,最大值為 2^31 - 1 = 2,147,483,647。約等于 2×10?。顯然,如果用int,根本存不下 11位的手機(jī)號碼。

要想存得下,得用64位的Long類型,也就是對應(yīng)數(shù)據(jù)庫的bigInt。

1.2 數(shù)據(jù)完整性

例如手機(jī)號01324567890,用Long存會變成1324567890,直接破壞數(shù)據(jù)完整性。

Long phoneNumber =01324567890L; //編譯報錯,Java不允許前導(dǎo)0的Long整數(shù)

并且,有時候,有些手機(jī)號可能包含國家代碼如(+86),或者有些時候,是有連字符的,比如137-2819-9213. 這些原因都導(dǎo)致不能用整型類型存儲。

1.3 查詢麻煩

比如,你要查找,手機(jī)號是137開頭的手機(jī)號號碼,如果用BigInt(Long類型)需先轉(zhuǎn)字符串再模糊匹配,效率暴跌。

2. 用String有哪些好處

  • 保真:數(shù)字、符號、前導(dǎo)零全能存,原樣保留。
  • 靈活:支持模糊查詢、國際號碼,擴(kuò)展無憂。
  • 省心:無需擔(dān)心溢出或格式轉(zhuǎn)換問題。
CREATE TABLE user_tab (
  id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '用戶ID',
  phone_number VARCHAR(20) NOT NULL COMMENT '手機(jī)號',
  PRIMARY KEY (id),
  UNIQUE KEY idx_phone (phone_number)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='用戶表';

2. 面試官的隱藏考察點

面試的時候,面試官主要考察候選人的一些業(yè)務(wù)擴(kuò)展性、數(shù)據(jù)容錯性、思考問題全面性等能力。我們先通過:為什么用 VARCHAR(20) 而不是 VARCHAR(11),來給面試官秀一波肌肉~~

2.1 為什么用 VARCHAR(20) 而不是 VARCHAR(11)

我們就拿手機(jī)號來說,為什么更建議用 VARCHAR(20),而不是VARCHAR(11)呢?

因為我們都知道,手機(jī)號是11位的,為什么不直接用VARCHAR(11)呢?

如果你日常開發(fā)中,就有思考數(shù)據(jù)容錯性習(xí)慣的話,就會想到:

  • 如果遇到國際號碼:+8613822223333(14位)
  • 帶國家碼的號碼:008613822223333(15位)
  • 分機(jī)號:13822223333#123(超11位)

這些場景,都會導(dǎo)致VARCHAR(11)報錯崩盤。

其次就是業(yè)務(wù)擴(kuò)展性思考:VARCHAR(11)只能存純11位數(shù)字,假設(shè)未來業(yè)務(wù)需要:

  • 支持座機(jī)號(如010-62223333,含橫杠)
  • 支持虛擬號(如17012341234-5678)
  • 支持其他登錄方式(如郵箱+手機(jī)號混合存儲)

因此,字段長度和類型需提前為業(yè)務(wù)變化留余地,避免頻繁改表。這就是日常開發(fā)中的,業(yè)務(wù)擴(kuò)展性思維思考。

還有數(shù)據(jù)容錯性思考,

  • 輸入不可控性:用戶可能輸入帶空格/符號的號碼(如138 2222 3333),直接存原始值更方便清洗。
  • 設(shè)計妥協(xié):若強(qiáng)制用VARCHAR(11),需在代碼層嚴(yán)格過濾非數(shù)字字符,增加復(fù)雜度。

還有思考問題全面性,比如存儲成本思考。

  • VARCHAR(11):最大占 11字節(jié)(utf8mb4下1字符占4字節(jié),但數(shù)字和+號只占1字節(jié))
  • VARCHAR(20):最大占 20字節(jié)
  • 20億數(shù)據(jù)相差僅約 18GB(和用BIGINT的16GB對比,總成本仍可接受)。

所以面試官期待的答案公式

合理長度 = 基礎(chǔ)需求 + 國際擴(kuò)展 + 容錯緩沖

當(dāng)然,這個不是固定答案,主要還是面試的時候,你回答面試官的思路和表達(dá),最好體現(xiàn)你有這幾個方面的思考:業(yè)務(wù)擴(kuò)展性、數(shù)據(jù)容錯性、思考問題全面性。

2.2 極端場景

如果手機(jī)號是純數(shù)字,并且第一位不是0的話,可以用BIGINT的,但是永遠(yuǎn)不要使用INT。通過這些極端場景的舉例,也體現(xiàn)你思考問題全面性的一個能力。

3. 日常開發(fā)避坑點

設(shè)計手機(jī)號存儲的時候,有哪些需要避的坑的。

主要有這幾個吧:

3.1 字段長度設(shè)計過小

用 VARCHAR(11) 只存純數(shù)字,遇到 +8613822223333(14位)直接截斷。

用 VARCHAR(20) 兼容國際號、分機(jī)號(如 13822223333#123)。'

3.2 字符集和排序規(guī)則

使用 utf8 字符集,無法存儲 emoji 或特殊符號

用 utf8mb4 + utf8mb4_unicode_ci,兼容所有 Unicode 字符(如 + * #)。

3.3 索引設(shè)計不當(dāng)

未對手機(jī)號加唯一索引,導(dǎo)致重復(fù)數(shù)據(jù)。

添加 UNIQUE 約束:ALTER TABLE user ADD UNIQUE INDEX idx_phone (phone);

3.4 數(shù)據(jù)清洗與校驗缺失

用戶輸入 138-2222-3333 或 138 222 23333,直接存儲導(dǎo)致格式混亂。

  • 入庫前統(tǒng)一清洗:移除空格、橫杠等符號,只保留 + 和數(shù)字。
  • 正則校驗:例如 ^+?\d{8,20}$(允許帶 + 號的 8~20 位數(shù)字)。

3.5 忽視隱私與安全

明文存儲手機(jī)號,泄露用戶隱私。

  • 加密存儲:使用 AES 加密或數(shù)據(jù)庫內(nèi)置加密函數(shù)。
  • 脫敏顯示:查詢結(jié)果返回 138****3333。

3.5 風(fēng)控校驗

// 嚴(yán)格校驗(11位純數(shù)字,無國際碼)
String regex = "^1(3[0-9]|4[579]|5[0-35-9]|6[2567]|7[0-8]|8[0-9]|9[0-35-9])\\d{8}$";

// 寬松校驗(允許帶國際碼,如+86 13812345678)
String looseRegex = "^(\\+\\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}$";

責(zé)任編輯:武曉燕 來源: 撿田螺的小男孩
相關(guān)推薦

2024-11-26 08:52:34

SQL優(yōu)化Kafka

2021-10-01 00:02:54

CHAR VARCHARMYSQL

2024-10-30 16:12:14

2022-03-30 10:10:17

字節(jié)碼??臻g

2021-05-08 08:55:54

CPUIBMIntel

2022-11-30 17:13:05

MySQLDynamic存儲

2022-08-13 12:07:14

URLHTTP加密

2024-09-19 08:51:01

HTTP解密截取

2022-10-10 08:13:16

遞歸通用代碼

2019-07-29 15:08:34

RedisHashString

2021-04-05 14:22:47

Facebook數(shù)據(jù)泄露攻擊

2022-05-10 22:00:41

UDPTCP協(xié)議

2024-09-04 15:17:23

2022-01-05 21:54:51

網(wǎng)絡(luò)分層系統(tǒng)

2021-02-05 10:58:28

數(shù)據(jù)存儲架構(gòu)

2021-09-18 05:37:34

手機(jī)號一證通查微信

2015-02-11 10:37:58

騰訊ROM

2024-08-06 10:16:52

Java AgentJava

2024-08-29 08:30:10

2022-08-18 17:44:25

HTTPS協(xié)議漏洞
點贊
收藏

51CTO技術(shù)棧公眾號