mysql 手机号 字段_2021-01-06:mysql中,我存十亿个手机号码,考虑存储空间和查询效率,用什么类型的字段去存?...
福哥答案2021-01-06:
[答案來自此鏈接:](https://www.zhihu.com/question/438078173)
首先提出假設:
考慮一下這幾個問題:
手機號碼都是數字嗎?
都是中國的手機號碼嗎?
會按照手機號等值查詢嗎?
會按照手機號范圍查詢嗎?
需要手機號列唯一約束嗎?
最簡單情況(中國手機號,11位數字)就用數值類型bigint存儲即可,建索引。
考慮三種類型,BigInt,Char,Varchar
這幾種類型在 InnoDB 引擎下默認行格式的存儲方式為:
1.對于 bigint 類型,如果不為 NULL,則占用8字節,首位為符號位,剩余位存儲數字,數字范圍是 -2^63 ~ 2^63 - 1 = -9223372036854775808 ~ 9223372036854775807。如果為 NULL,則不占用任何存儲空間。
2.對于定長字段,不需要存長度信息直接存儲數據即可,如果不足設定的長度則補充。對于 char 類型,補充 0x20, 對應的就是空格。
3.數據開頭有可變長度字段長度列表,所以 varchar 只需要保存實際的數據即可,不需要填充額外的數據。正是由于這個特性,對于可變長度字段的更新,一般都是將老記錄標記為刪除,在記錄末尾添加新的一條記錄填充更新后的記錄。這樣提高了更新速度,但是增加了存儲碎片。
由于手機號不更新,并且不同國家的手機號長度不同,并且可能有特殊字符,字符類型在默認的編碼和排序規則下進行范圍匹配也能滿足我們的需求,所以為了節省空間,使用 varchar 類型。
分區
這個數據量比較大了,需要用分區。phone 可以作為分區鍵,可以按照范圍分區,也可以按照 hash 分區。
這樣查詢某個手機號是否存在這種業務就能更快,因為一張表被劃分成了很多張小表。并且如果涉及多張小表 MySQL 還可以多線程并發查,效率提升很多。如果考慮獲取某一號碼段的所有手機號,那最好還是按照范圍分區,可以使邏輯查詢范圍更小。但是 hash 分區數據可能比范圍分區更加均衡。
注意,對于 HASH 分區個數最好是 2^n。因為對于 2^n 取余相當于對 2^n - 1 取與運算,增加了查詢時的計算分區的效率.
進一步優化
對于查詢某個手機號是否存在,可以在數據庫上層加一層布隆過濾器,提高效率。
同時為了提高準確性,可以通過號碼號段,不同號段使用不同的布隆過濾器。在插入數據庫的同時,放入布隆過濾器中。如果布隆過濾器中檢測不存在,則肯定不存在。為了減少布隆過濾器的誤判概率,可以使用更多的布隆過濾器,同時設置交叉范圍,例如一個 13000000000~13200000000 用布隆過濾器 A,13100000000~13300000000 用布隆過濾器 B, 13211111111就要經過布隆過濾器 A 和 布隆過濾器 B 的驗證。
***
[評論](https://user.qzone.qq.com/3182319461/blog/1609888565)
總結
以上是生活随笔為你收集整理的mysql 手机号 字段_2021-01-06:mysql中,我存十亿个手机号码,考虑存储空间和查询效率,用什么类型的字段去存?...的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: mysql 修改表id值_修改数据库中表
- 下一篇: mysql专区_MySQL-技术专区-详