面试官问,为什么建议MySQL列属性尽量用 NOT NULL ?
點擊上方“朱小廝的博客”,選擇“設(shè)為星標”
回復”1024“獲取獨家整理的學習資料
寫這篇文章,來自一個小伙伴的提問,他在二面的過程中被問到,由于他簡歷中寫道有 MySQL 調(diào)優(yōu)經(jīng)驗,但這個問題沒有回答好,二面被刷了。
其實我們剛學習 C 語言的時候,就接觸過 NULL,比如下面這句代碼。
int *p = NULL;
它實際上表示將指針指向一塊不被使用的內(nèi)存地址,一般會在宏中定義好。
那么我們常用的 Java 語言,同樣也用到 null,表示一個空引用,如果你不小心引用了,那么就會拋出 NullPointerException,就像昨天 Reddit 上面很火的一張圖。
其實很早之前 guava 就提供了 Optional 容器類來處理 null,其目的便是避免猝不及防的空指針。后來 java8 直接引入了 Optional,功能一樣,用法上稍稍有點變化。其實還有很多開源框架,比如 Spring,common lang3等,也提供了處理空的工具類,如。
StringUtils.isBlank();? ?
CollectionUtils.isEmpty();
那么在 MySQL 中,NULL 表示不知道的數(shù)據(jù)。
我們在設(shè)計表的時候,經(jīng)常會有老司機這么告訴我們。
字段盡可能用NOT NULL,而不是NULL,除非特殊情況。
這句話到底有沒有錯?
可以負責任的告訴你這句話沒有錯,也不是以訛傳訛,這句話首次出現(xiàn)在 MySQL 官網(wǎng)。
如果你讀過《高性能 MySQL》這本書,你應(yīng)該會看到這么一段,在 4.1 節(jié)提到。
由此看來,把 NULL 改成 NOT NULL 對索引的性能并沒有明顯的提升。避免使用 NULL 的目的,是便于代碼的可讀性和可維護性。同時也便于避免下文即將出現(xiàn)的一些稀奇古怪的錯誤。
好了,下面咱們通過實驗來看看,使用 NULL 會出現(xiàn)那些稀奇古怪的錯誤呢?
跟我一樣在本地建兩個表 t1,t2;其中一個表 name 字段允許為空,另一個表 name 字段不允許為空,分別對 name 字段建立索引,SQL 語句如下
1、NOT IN、!= 等負向條件查詢在有 NULL 值的情況下返回非空行的結(jié)果集
比如上例中的 t2,我執(zhí)行如下 SQL 語句
SELECT * from t2 where name != '張三'
你本打算返回 id 為 2 的那行數(shù)據(jù),然而什么都沒有。
又比如這條 SQL 語句
select * from t2 where name not in (select name from t2 where id!=1)
也返回了空結(jié)果集。
2、使用 concat 函數(shù)拼接時,首先要對各個字段進行非 NULL 判斷,否則只要任何一個字段為空都會造成拼接的結(jié)果為 NULL
比如下面這條 SQL 語句
SELECT CONCAT("1",NULL)
3、當用count函數(shù)進行統(tǒng)計時,NULL 列不會計入統(tǒng)計
SELECT count(name) from t2
4、查詢空行數(shù)據(jù),用 is NULL
SELECT * FROM t2 where name is NULL
5、NULL 列需要更多的存儲空間,一般需要一個額外的字節(jié)作為判斷是否為 NULL 的標志位。
如果你仔細觀察 t1 和 t2 表的 key_len,會發(fā)現(xiàn) t2 比 t1 多了一個字節(jié)。
explain SELECT * from t2 where name = '張三'
explain SELECT * from t1 where name = '張三'
key_len 的長度一般跟這三個因素有關(guān),分別是數(shù)據(jù)類型,字符編碼,是否為 NULL。
因此,t2 比 t1 多出的這一個字節(jié),用于作為判斷是否為 NULL 的標志位了。
馬蛋,原來一切都在書中。如果面試的哪位同學多讀幾篇《高性能 MySQL》這本書,那個崗位就是他的了,但沒有那么多如果...
在此,建議大家多看官方文檔,多讀點好書,多關(guān)注一些良心的原創(chuàng)技術(shù)自媒體,不要看那些無憑無據(jù)的文章,反而會以訛傳訛,貽害無窮。
想知道更多?掃描下面的二維碼關(guān)注我
相關(guān)推薦:
《科普 | 明星公司之Netflix》
《看我如何作死 | 將CPU、IO打爆》
《看我如何作死 | 網(wǎng)絡(luò)延遲、丟包、中斷一個都沒落下》
《7102-2019年技術(shù)文全套整理,建議收藏》
《看我如何假死!》
《總結(jié)緩存使用過程中的幾種策略以及優(yōu)缺點組合分析》
加技術(shù)群入口(備注:技術(shù)):>>>Learn More<<
免費資料入口(備注:1024):>>>Learn More<<
免費星球入口(有需要的+):
點個"在看"唄^_^
總結(jié)
以上是生活随笔為你收集整理的面试官问,为什么建议MySQL列属性尽量用 NOT NULL ?的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 秒懂 QPS、TPS、PV、UV、GMV
- 下一篇: 加入知识星球(永久免费)