成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

數據庫表字段為何默認為 NOT NULL?

數據庫 其他數據庫
假設有一張表,只有一個字段允許為 NULL,其他字段都是 NOT NULL。當存儲一條記錄時,如果這個可空字段的值為 NULL,那么就需要在 NULL 值列表中進行標記,并且在記錄頭部占用一個額外的字節作為標志位。隨著記錄數量的增加,這種額外的存儲空間占用也會逐漸累積。

目前大部分的開發現狀來說,我們都會把字段全部設置成 NOT NULL 并且給默認值的形式。

最近在 Review 代碼時候,仍然偶爾發現數據庫字段很多沒有設置 NOT NULL,為什么要設置成 NOT NULL 呢?

來自「高性能MySQL」中有這樣一段話:

盡量避免NULL
很多表都包含可為NULL(空值)的列,即使應用程序并不需要保存NULL也是如此,這是因為可為NULL是列的默認屬性。通常情況下最好指定列為NOT NULL,除非真的需要存儲NULL值。
如果查詢中包含可為NULL的列,對MySql來說更難優化,因為可為NULL的列使得索引、索引統計和值比較都更復雜。可為NULL的列會使用更多的存儲空間,在MySql里也需要特殊處理。當可為NULL的列被索引時,每個索引記錄需要一個額外的字節,在MyISAM里甚至還可能導致固定大小的索引(例如只有一個整數列的索引)變成可變大小的索引。
通常把可為NULL的列改為NOT NULL帶來的性能提升比較小,所以(調優時)沒有必要首先在現有schema中查找并修改掉這種情況,除非確定這會導致問題。但是,如果計劃在列上建索引,就應該盡量避免設計成可為NULL的列。
當然也有例外,例如值得一提的是,InnoDB使用單獨的位(bit)存儲NULL值,所以對于稀疏數據有很好的空間效率。但這一點不適用于MyISAM。

本文主要對表字段為 NOT NULL 情況的應用影響匯總。

一、NOT NULL 的性能優勢

數據庫表字段設置為 NOT NULL 在性能方面具有諸多優勢。

(1)查詢優化是一個重要方面

當一列被標記為 NOT NULL 時,數據庫系統可以使用這個信息來優化查詢。因為系統知道這一列的值永遠不會為空,所以在執行查詢時可以忽略 NULL 值,從而提高查詢性能。例如,在一個包含數百萬條記錄的大型數據庫中,如果某列被設置為 NOT NULL,那么在查詢這一列的值時,數據庫系統可以直接忽略所有的 NULL 值,極大地提高了查詢速度。

(2)NOT NULL 可以減少存儲空間占用

NULL 列需要更多的存儲空間,因為需要一個額外字節作為判斷是否為 NULL 的標志位。如果把一些可填可不填的字段設置為 NOT NULL,就可以節省這些額外的存儲空間。例如,假設有一個包含大量記錄的表,其中有多個可填可不填的字段,如果這些字段都設置為 NOT NULL,那么隨著記錄數量的增加,節省的存儲空間會非常可觀。

(3)索引效率也會得到提升

索引含有空值的列很難進行查詢優化,而且對表索引時不會存儲 NULL 值。所以如果索引的字段可以為 NULL 值,索引的效率會下降,因為它們使得索引、索引的統計信息以及比較運算更加復雜。應該用 0、一個特殊的值或者一個空串代替 NULL 值。

綜上所述,數據庫表字段設置為 NOT NULL 在性能方面具有顯著優勢,可以提高查詢速度、減少存儲空間占用和提升索引效率。

二、對開發的友好性

(1)簡化代碼邏輯

數據庫表字段設置為 NOT NULL,可以極大地簡化開發人員的代碼邏輯。

在實際開發中,如果字段允許為 NULL,那么開發人員在處理這些字段時,需要進行大量的空值判斷。

例如,在 Java 語言中,如果實體類的某個字段允許為 NULL,那么在使用這個字段進行操作時,開發人員需要不斷地進行空指針檢查,以避免出現空指針異常。這不僅增加了代碼的復雜度,還降低了代碼的可讀性和可維護性。

(2)提高數據一致性

NOT NULL 約束能夠在數據庫層面強制實施數據一致性約束,從而減少數據質量問題。

當數據庫表中的某一列被設置為 NOT NULL 時,這意味著這一列的每一行都必須有值。這樣可以確保數據的完整性和一致性,避免出現數據不完整或不一致的情況。

例如,在一個電商系統中,如果用戶表中的用戶名、郵箱等關鍵信息字段被設置為 NOT NULL,那么在用戶注冊和登錄時,系統可以確保這些關鍵信息都被正確地填寫,從而提高數據的質量和可靠性。此外,NOT NULL 約束還可以防止開發人員在插入或更新數據時出現錯誤。

三、應用注意事項

為了更好的描述應用注意事項,我們初始化原始數據,一個只有1列的表,很簡單:

圖片圖片

3.1 聚合函數

常見的聚合函數有 count、min、max、avg 以及 sum,這些聚合函數在遇到 NULL 值時,處理方式各不相同:

  • max、min、avg 和 sum 函數對 NULL 值采取的處理方式是直接忽略

圖片圖片

  • count 函數處理 NULL 值則需要分情況進行討論

count () 返回的是所有記錄的總和,含有 NULL 值的記錄不會被忽略,也會被計算在內;

count (column_name) 如果這個列名中含有一個值為 NULL,則該條記錄會被忽略,此時的返回值為 count ()-1

圖片圖片

3.2 與其他值運算規則

在數據庫中,NULL 和其他任何值進行運算的結果都是 NULL,會給數據處理帶來了很大的不確定性:

  • 當進行加法運算時,如果其中一個值為 NULL,那么結果也為 NULL
  • 在進行乘法、除法等其他運算時,只要有一個操作數為 NULL,結果就會是 NULL

這種特性使得在處理包含可能為 NULL 值的字段時,需要特別小心,否則很容易得到錯誤的結果。

假設我們有一個數據庫表,其中包含兩個字段 A 和 B,A 字段的值可能為 NULL,B 字段的值為固定值。當我們嘗試進行 A+B 的運算時,如果 A 的值為 NULL,那么結果也會是 NULL,而不是我們期望的 B 的值。

圖片圖片

3.3 對 distinct、group by、order by 的影響

在數據庫操作中,對于 distinct 和 group by 來說,所有的 NULL 值都會被視為相等。這意味著如果在進行數據去重或者分組操作時,含有 NULL 值的記錄會被歸為一類。

圖片圖片

對于 order by 來說,升序時 NULL 會排在最前。這是因為在排序過程中,數據庫系統將 NULL 視為一個特殊的值,按照特定的規則進行排序。

圖片圖片

當使用 distinct 對這個字段進行去重操作時,所有的 NULL 值會被視為同一個值,只顯示一次。同樣,在使用 group by 進行分組操作時,NULL 值的記錄會被分到同一組中。

圖片圖片

四、其他影響問題

4.1 索引問題

圖片圖片

索引列中存在大量 NULL 值可能會導致索引失效,影響查詢性能。因此,將數據庫表字段設置為 NOT NULL 可以減少這種情況的發生,提高索引的有效性和查詢性能。

(1)索引使用準確性

在網上有很多說法認為 NULL 不能使用索引,然而這種說法并不完全準確。實際上,索引列中存在 NULL 值并不意味著完全不能使用索引,只是會使數據庫的優化器在選擇索引時變得更加復雜。

查詢條件針對的是索引列中的非 NULL 值,數據庫可以使用索引進行快速查找。但是,如果查詢條件涉及到 NULL 值的判斷,如 IS NULL 或 IS NOT NULL,優化器可能需要考慮更多的因素來決定是否使用索引以及如何使用索引。

因為 NULL 值在數據庫中被視為未知的狀態,與其他具體的值不同,所以在處理包含 NULL 值的索引列時,優化器需要評估各種情況,包括索引的選擇性、數據的分布等,以確定最佳的查詢執行計劃。這就可能導致在某些情況下,優化器選擇不使用索引,而采用全表掃描等其他方式來執行查詢。

(2)索引失效情況

如果索引列上存在大量的 NULL 值,數據庫可能會認為使用索引并不能顯著提高查詢性能,因此選擇不使用索引。

假設一個表,其中某個索引列上有很多 NULL 值。當進行查詢時,如果查詢條件涉及到這個索引列,數據庫可能會發現使用索引進行查找并不能有效地減少需要掃描的數據量,因為大量的 NULL 值使得索引的選擇性降低。在這種情況下,數據庫可能會選擇進行全表掃描,而不是使用索引。

此外,當索引列上的 NULL 值過多時,還可能影響索引的統計信息。數據庫通常會根據索引的統計信息來評估查詢的執行計劃,如果統計信息不準確,可能會導致優化器做出錯誤的決策。

4.2 存儲空間考慮

數據庫中的一行記錄在最終磁盤文件中是以行的方式來存儲的,對于 InnoDB 來說,有 4 種行存儲格式:REDUNDANT、COMPACT、DYNAMIC 和 COMPRESSED。

InnoDB 的默認行存儲格式是 COMPACT,存儲格式如下所示,虛線部分代表可能不一定會存在。

圖片圖片

(1)存儲格式詳解

  1. 變長字段長度列表:有多個字段則以逆序存儲,存儲格式是 16 進制,如果沒有變長字段就不需要這一部分了。
  2. NULL 值列表:用來存儲我們記錄中值為 NULL 的情況,如果存在多個 NULL 值那么也是逆序存儲,并且必須是 8bit 的整數倍,如果不夠 8bit,則高位補 0。1 代表是 NULL,0 代表不是 NULL。如果都是 NOT NULL 那么這個就不存在了。
  3. ROW_ID:一行記錄的唯一標志,沒有指定主鍵的時候自動生成的 ROW_ID 作為主鍵。
  4. TRX_ID:事務 ID。
  5. ROLL_PRT:回滾指針。
  6. 每列的值。

(2)NOT NULL 對存儲空間的影響

如果存在允許為 NULL 的列,就會多占用一個字節的標志位空間。

假設有一張表,只有一個字段允許為 NULL,其他字段都是 NOT NULL。當存儲一條記錄時,如果這個可空字段的值為 NULL,那么就需要在 NULL 值列表中進行標記,并且在記錄頭部占用一個額外的字節作為標志位。隨著記錄數量的增加,這種額外的存儲空間占用也會逐漸累積。

然而,如果將所有字段都設置為 NOT NULL,就不會有 NULL 值列表和標志位的占用。例如,插入一條數據,所有字段都有確定的值,存儲格式更加緊湊,不會有額外的空間浪費。

綜上所述,將數據庫表字段設置為 NOT NULL 可以減少存儲空間的占用,使數據庫的存儲更加高效。特別是在處理大量數據時,這種節省空間的效果會更加明顯。

責任編輯:武曉燕 來源: 架構精進之路
相關推薦

2023-11-13 15:03:49

MySQL數據庫

2010-05-31 15:23:02

MySQL數據庫NUL

2023-08-30 09:00:00

向量數據庫大語言模型

2011-05-26 14:18:49

Oracle數據庫字段屬性

2021-07-30 06:58:28

數據庫分布式映射

2018-07-30 10:34:14

時間序列數據庫

2009-06-19 16:47:22

數據庫表字段J2EE應用

2010-05-05 14:13:52

Oracle數據

2011-09-27 13:41:09

數據庫

2020-10-12 14:37:38

數據庫HiveSpark

2023-05-10 16:15:58

javaScript算法開發

2017-12-01 05:40:56

數據庫中間件join

2022-11-02 08:00:00

數據庫多區域應用程序云平臺

2011-09-27 10:44:07

NewSQL云計算

2018-07-25 18:40:06

數據庫MySQL多字段過濾

2010-04-23 14:32:01

Oracle數據庫

2019-08-28 07:11:00

Oracle數據庫LOB

2019-10-29 05:00:11

Redis數據庫集群

2011-07-11 10:42:23

SQL數據庫橫向數據縱向字段

2011-08-22 11:12:45

SQL Server 更改賬戶默認數據庫
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 黄色在线播放视频 | 久久久亚洲综合 | 国产精品视频免费观看 | 国产在线中文字幕 | 日韩精品一区二区三区中文字幕 | 国产色网 | 国内在线视频 | 国产精品久久久久久久久久久久午夜片 | 91一区二区在线观看 | 免费国产一区二区 | 日韩高清一区二区 | 亚洲精品日日夜夜 | 亚洲福利在线观看 | 精品国产一区二区三区性色av | 中文字幕在线观看一区二区 | 黄色大片在线免费观看 | 成人一区二区三区在线观看 | 日韩精品在线看 | 国产精品久久久久久久久久久久 | 一级毛片视频在线 | 国产一区二区三区在线看 | 91麻豆产精品久久久久久 | 国产成人精品免费视频大全最热 | 91在线免费观看 | 成人在线免费观看av | 女人毛片a毛片久久人人 | 三级视频网站 | 老司机午夜性大片 | 欧美亚洲国产成人 | 久久国产精品-国产精品 | 国产一区二区三区久久久久久久久 | 久久精品女人天堂av | 武道仙尊动漫在线观看 | 欧美午夜精品久久久久久浪潮 | 亚洲永久入口 | 欧美h版| 中文av网站 | 毛片a区| 玖玖操 | 成人久久网 | 日韩一区三区 |