日日操夜夜添-日日操影院-日日草夜夜操-日日干干-精品一区二区三区波多野结衣-精品一区二区三区高清免费不卡

公告:魔扣目錄網為廣大站長提供免費收錄網站服務,提交前請做好本站友鏈:【 網站目錄:http://www.ylptlb.cn 】, 免友鏈快審服務(50元/站),

點擊這里在線咨詢客服
新站提交
  • 網站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會員:747

之前ElasticSearch系列文章中提到了如何處理空值,若為Null則會直接報錯,因為在ElasticSearch中當字段值為null時、空數組、null值數組時,會將其視為該字段沒有值,最終還是需要使用exists或者null_value來處理空值

大多數ElasticSearch的數據都來自于各類數據庫,這里暫且只針對于MySQL,各個開源軟件中都默認兼容各種Null值,空數組等等

若從根源上截斷就可以省很多事,直到現在很多開發小伙伴還是堅韌不拔的給字段的默認值還是Null

本期就來聊一聊為什么不建議給字段的默認值設置為Null

本期環境為:MySQL8.0.26

為什么不建議給MySQL設置Null值?

 

null

一、案例數據

創建表user

CREATE TABLE `user` (
 `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
 `name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL,
 `age` tinyint(4) unsigned NOT NULL,
 PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci

添加數據,共計10條數據,有兩條數據的name值為Null

INSERT INTO `user` (`name`, `age`) VALUES ('kaka', 26);
INSERT INTO `user` (`name`, `age`) VALUES ('niuniu', 26);
INSERT INTO `user` (`name`, `age`) VALUES ('yangyang', 26);
INSERT INTO `user` (`name`, `age`) VALUES ('dandan', 26);
INSERT INTO `user` (`name`, `age`) VALUES ('liuliu', 26);
INSERT INTO `user` (`name`, `age`) VALUES ('yanyan', 26);
INSERT INTO `user` (`name`, `age`) VALUES ('leilie', 26);
INSERT INTO `user` (`name`, `age`) VALUES ('yao', 26);
INSERT INTO `user` (`name`, `age`) VALUES (NULL, 26);
INSERT INTO `user` (`name`, `age`) VALUES (NULL, 26);

一、count數據丟失

在這期 MySQL統計總數就用count,別花里胡哨的《死磕MySQL系列 十》 文章中,已經對count的使用說的非常明白了。

那借著這個案例,來分析一下為什么數據會丟失,先看結果

select count(*) as num1 ,count(name) as num2 from user;
為什么不建議給MySQL設置Null值?

 

使用count字段名時出現了數據丟失,很明顯是因為主鍵ID9、10這兩條記錄的name值為空造成的。

為什么會出現這種情況?

當count除了主鍵字段外,會有兩種情況:

一種是字段為null,執行時,判斷到有可能是null,但還要把值取出來再判斷下,不是null的進行累加

另一種是字段為not null,執行時,逐行從記錄里邊讀出這個字段,判斷不是null,才進行累加

此時,咱們遇到的問題是name字段的值存在了null值,所以會走第一種情況,不進行統計null值

為什么建議大家都使用count(*)?

MySQL對于count做了專門的優化,跟字段不同的是并不是把所有帶了*的值取出來,而是指定了count(*)肯定不是null,只需要按行累加即可

MySQL團隊對count(*)做了什么優化?

MySQL系列文章至今已經更新了第十八期了,你有沒有猜到原因呢?

現在你應該知道主鍵索引結構中葉子節點存儲的是整行數據,而普通索引葉子節點存儲的是主鍵ID

那對于普通索引來說肯定會比主鍵索引小,因為對于MySQL來說,不管遍歷哪個索引結果都一樣,所以優化器會主動去找到那顆最小的樹進行遍歷。

在邏輯正確的前提下,盡量減少訪問數據量,是數據庫系統設計通用法則之一。

最后給大家留一個問題,為什么Innodb存儲引擎不跟Myisam存儲一樣存儲一個count值呢?

如果不知道的話,可以看上文提到的count文章

二、為distinct打抱不平

在開發工作中使用Distinct進行去重的場景十分的少,大多數情況都是使用group by完成的

select distinct name from user;

可以看到此時的數據依然是正確的,對Null值做了去重的操作

為什么不建議給MySQL設置Null值?

 

為什么要說這個,因為咔咔在其它的平臺上看到過有人這么使用count(distinct name,mobile),然后說是統計出來的數據不準確。

這種用法依然是count(字段)的用法,distinct本身是會對Null進行去重,去重后依然是需要判斷name的值不為null時,才會進行累計。

所以,不要把鍋甩給distinct

三、使用表達式數據丟失

在一些值為null時,使用表達式會造成數據的不一致,接下來一起看下

select * from user where name != 'kaka';
為什么不建議給MySQL設置Null值?

 

表達式造成數據丟失

這跟我們的預期結果不大一致,預期是想返回id2~10的數據

當然,這個問題也不是無解,MySQL同樣也提供了方法

要解決這個問題,只能再加一個條件就是把字段值為null的再單獨處理一下

為什么不建議給MySQL設置Null值?

 

isnull

四、空指針問題

如果一個列存在null值,使用MySQL的聚合函數后返回結果是null,而并非是0,就會造成程序執行時的指針異常

CREATE TABLE user_order (
 id INT PRIMARY KEY auto_increment,
 num int
) ENGINE='innodb';
insert into user_order(num) values(3),(6),(6),(NULL);

創建用戶訂單數量表,并插入4條數據,接下來演示一下產生的問題

select sum(num) from goods where id>4;
為什么不建議給MySQL設置Null值?

 

聚合函數產生的問題

可以看到當字段為null時,使用聚合函數返回值就是null,并非是0,那么這個問題要怎么處理呢?

同樣MySQL也給大家提供了對應函數,就是ifnull

select ifnull(sum(num), 0) from goods where id>4;
為什么不建議給MySQL設置Null值?

 

在這里插入圖片描述

五、這是在難為誰?

當一個字段的值存在null值,若要進行null值查詢時,必須要使用isnull或者ifnull進行匹配查詢,又或者使用is null,is not null。

而常用的表達式就不能再進行使用了,有工作經驗的還好的,要是新人的話會很難受。

接下來看幾個新人經常犯的錯誤

錯誤一

對存在null值的字段使用表達式進行過濾,正確用法應該是is null 或者 is not null

select * from user where name<>null;
為什么不建議給MySQL設置Null值?

 

在這里插入圖片描述

錯誤二

依然是使用表達式,同樣可以使用isnull

為什么不建議給MySQL設置Null值?

 

在這里插入圖片描述

六、總結

說了這么多也都感覺到了字段設置為null的麻煩之處,不過幸好的是MySQL對使用is null、isnull()等依然可以使用上索引。

咔咔目前所在的公司存在大量字段默認值就是null,于是代碼中就大量存儲ifnull、is null、is not null等代碼。

一般字段數值類型的默認值就給成0,字符串的給個空也行,千萬不要給null了哈!

文章來自
https://www.cnblogs.com/fkaka/p/16227471.html

分享到:
標簽:Null
用戶無頭像

網友整理

注冊時間:

網站:5 個   小程序:0 個  文章:12 篇

  • 51998

    網站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會員

趕快注冊賬號,推廣您的網站吧!
最新入駐小程序

數獨大挑戰2018-06-03

數獨一種數學游戲,玩家需要根據9

答題星2018-06-03

您可以通過答題星輕松地創建試卷

全階人生考試2018-06-03

各種考試題,題庫,初中,高中,大學四六

運動步數有氧達人2018-06-03

記錄運動步數,積累氧氣值。還可偷

每日養生app2018-06-03

每日養生,天天健康

體育訓練成績評定2018-06-03

通用課目體育訓練成績評定