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

MySQL 的 NULL 值是怎么存放的?

數(shù)據(jù)庫 MySQL
InnoDB是一個將數(shù)據(jù)存儲到磁盤上的存儲引擎,所以就算我們關(guān)閉、重啟服務(wù)器,數(shù)據(jù)還是存在的。而在真正處理數(shù)據(jù)的時候是在內(nèi)存中進(jìn)行的,所以需要把磁盤中的內(nèi)容加載到內(nèi)存中。

InnoDB頁

InnoDB是一個將數(shù)據(jù)存儲到磁盤上的存儲引擎,所以就算我們關(guān)閉、重啟服務(wù)器,數(shù)據(jù)還是存在的。而在真正處理數(shù)據(jù)的時候是在內(nèi)存中進(jìn)行的,所以需要把磁盤中的內(nèi)容加載到內(nèi)存中。

我們知道讀寫磁盤是很慢的。當(dāng)我們想從表里獲取數(shù)據(jù)的時候,InnoDB會一條一條的從磁盤中讀出來嗎?不會的!因為那樣太慢了。它采取的方式是:將數(shù)據(jù)劃分為若干頁,以頁做為磁盤和內(nèi)存交互的基本單位。InnoDB中頁的大小一般為16KB。

在服務(wù)器運行的過程中不可以修改頁的大小,只能在初始化數(shù)據(jù)目錄的時候指定。

InnoDB 行格式

行格式有哪些

行格式(row_format):一條數(shù)據(jù)記錄在磁盤上的存儲結(jié)構(gòu)。

InnoDB 提供了 4 種行格式,分別是 Redundant、Compact、Dynamic和 Compressed 行格式。

我們可以在創(chuàng)建表或者修改表的語句中指定所使用的行格式

create table 'table info ..' row_format = '行格式名稱'
alter table 'table name' row_format = '行格式名稱'
  • Redundant:是很古老的行格式了, MySQL 5.0 版本之前用的行格式,現(xiàn)在基本沒人用了。
  • Compact:由于 Redundant 不是一種緊湊的行格式,所以 MySQL 5.0 之后引入了 Compact 行記錄存儲方式,Compact 是一種緊湊的行格式,設(shè)計的初衷就是為了讓一個數(shù)據(jù)頁中可以存放更多的行記錄,從 MySQL 5.1 版本之后,行格式默認(rèn)設(shè)置成 Compact。
  • Dynamic 和 Compressed 兩個都是緊湊的行格式,它們的行格式都和 Compact 差不多,因為都是基于 Compact 改進(jìn)一點東西。從 MySQL5.7 版本之后,默認(rèn)使用 Dynamic 行格式。

Redundant 行格式因為現(xiàn)在基本沒人用了,重點介紹 Compact 行格式,因為 Dynamic 和 Compressed 這兩個行格式跟 Compact 非常像。

Compact 格式

話不多說,直接看圖

記錄額外的信息

這部分信息是服務(wù)器為了更好的管理記錄而不得不額外添加的一些信息,這些額外信息分為三個部分,分別是:變長字段長度列表、NULL值列表和記錄頭信息。

變長字段長度列表

在mysql中有一些變長的數(shù)據(jù)類型,比如varchar( )、varbinary( )、text類型、blob類型,我們把使用這個變長類型的列成為變長字段。

所以,在存儲數(shù)據(jù)的時候,也要把數(shù)據(jù)占用的大小存起來,存到「變長字段長度列表」里面,讀取數(shù)據(jù)的時候才能根據(jù)這個「變長字段長度列表」去讀取對應(yīng)長度的數(shù)據(jù)。

這些變長字段的真實數(shù)據(jù)占用的字節(jié)數(shù)會按照列的順序逆序存放(后面會說為什么要這么設(shè)計)。

為了展示具體是怎么保存「變長字段的真實數(shù)據(jù)占用的字節(jié)數(shù)」,我們先創(chuàng)建這樣一張表,字符集是 ascii(所以每一個字符占用的 1 字節(jié)),行格式是 Compact,student 表中 name 和 dream_school 字段是變長字段:

CREATE TABLE `student` (
  `id` int(11) NOT NULL,
  `name` VARCHAR(20) DEFAULT NULL,
  `dream_school` VARCHAR(20) DEFAULT NULL,
  `age` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB DEFAULT CHARACTER SET = ascii ROW_FORMAT = COMPACT;

我們插入三條記錄

我們看看這三條記錄的行格式中的 變長字段長度列表 是怎樣存儲的。

先來看第一條記錄:

  • name 列的值為 1,真實數(shù)據(jù)占用的字節(jié)數(shù)是 1 字節(jié),十六進(jìn)制 0x01;
  • dream_school 列的值為 qinghua,真實數(shù)據(jù)占用的字節(jié)數(shù)是 7 字節(jié),十六進(jìn)制 0x07;
  • age 列和 id 列不是變長字段,這里不用管。

再來看第二條

  • name 列的值為 1,真實數(shù)據(jù)占用的字節(jié)數(shù)是 2 字節(jié),十六進(jìn)制 0x02;
  • dream_school 列的值為 beida,真實數(shù)據(jù)占用的字節(jié)數(shù)是 5 字節(jié),十六進(jìn)制 0x05;

第三條記錄

第三條記錄 dream_school 列的值是 NULL,NULL 是不會存放在行格式中記錄的真實數(shù)據(jù)部分里的。

null值列表一條記錄中的某些列可能存儲 NULL 值,如果把這些 NULL 值都放到記錄的 真實數(shù)據(jù)中存儲會很占地方,所以 OMPACT 行格式把一條記錄中值為 NULL 的列統(tǒng)一管理起來,存儲到 NULL 值列表中.

處理過程:

  • 首先統(tǒng)計表中允許存儲 NULL 的列有哪些,主鍵列以及使用 NOT NULL 修飾的列都是不可以存儲 NULL 值的,所以在統(tǒng)計的時候不會把這些列算進(jìn)去。
  • 如果表中沒有允許存儲 NULL 的列,則 NULL 值列表也就不存在了,否則將每個允許存儲 NULL 的列對應(yīng)一個 進(jìn)制位,二進(jìn)制位按照列的順序逆序排列。二進(jìn)制位表示的意義如下
  • 進(jìn)制位的值為1時,代表該列的值為NULL。
  • 迸制位的值為0時,代表該列的值不為NULL。
  • 另外,NULL 值列表必須用整數(shù)個字節(jié)的位表示(1字節(jié)8位),如果使用的二進(jìn)制位個數(shù)不足整數(shù)個字節(jié),則在字節(jié)的高位補 0。

先來看第一條記錄

第一條記錄所有列都有值,不存在 NULL 值,用二進(jìn)制來表示是這樣的:

第二條記錄

接下來看第二條記錄,第二條記錄 age 列是 NULL 值,用二進(jìn)制來表示是這樣的:

第三條記錄

第三條記錄 dream_school 列 和 age 列是 NULL 值,用二進(jìn)制來表示是這樣的:

記錄頭信息

記錄頭信息由固定5個字節(jié)組成,用于描述記錄的一些屬性,這里的屬性比較多,我們就列舉幾個相對來說重要點的。

  • deleted_flag :標(biāo)識此條數(shù)據(jù)是否被刪除。從這里可以知道,我們執(zhí)行 detele 刪除記錄的時候,并不會真正的刪除記錄,只是將這個記錄的 delete_mask 標(biāo)記為 1。
  • next_record:下一條記錄的位置。所以我們可以知道,記錄與記錄之間是通過鏈表組織的。在前面我也提到了,指向的是下一條記錄的「記錄頭信息」和「真實數(shù)據(jù)」之間的位置,這樣的好處是向左讀就是記錄頭信息,向右讀就是真實數(shù)據(jù),比較方便。
  • record_type:表示當(dāng)前記錄的類型,0表示普通記錄,1表示B+樹非葉子節(jié)點記錄,2表示最小記錄,3表示最大記錄

記錄真實數(shù)據(jù)

記錄真實數(shù)據(jù)除了記錄我們自定義的列的數(shù)據(jù)外,Mysql還會為每個記錄默認(rèn)添加一些列(隱藏列)

  • row_id:當(dāng)我們創(chuàng)建表的時候沒有指定主鍵,也沒有唯一約束的列,innodb 就會自動的為這些記錄添加row_id隱藏字段,占用6個字節(jié)。不是必須會有的。
  • trx_id:事務(wù)ID,這個列是必須的,占用6個字節(jié)。表示數(shù)據(jù)是有哪個事務(wù)生產(chǎn)的。
  • roll_pointer:回滾指針,表示當(dāng)前記錄上一個版本的指針,這個列也是必需的,占用 7 個字節(jié)。

MVCC機制就是依賴 trx_id 和 roll_pointer 來實現(xiàn)的。

行溢出后,MySQL 是怎么處理的?

MySQL 中磁盤和內(nèi)存交互的基本單位是頁,一個頁的大小一般是 16KB,也就是 16384字節(jié),而一個 varchar(n) 類型的列最多可以存儲 65532字節(jié),一些大對象如 TEXT、BLOB 可能存儲更多的數(shù)據(jù),這時一個頁可能就存不了一條記錄。這個時候就會發(fā)生行溢出,多的數(shù)據(jù)就會存到另外的「溢出頁」中。

如果一個數(shù)據(jù)頁存不了一條記錄,InnoDB 存儲引擎會自動將溢出的數(shù)據(jù)存放到「溢出頁」中。在一般情況下,InnoDB 的數(shù)據(jù)都是存放在 「數(shù)據(jù)頁」中。但是當(dāng)發(fā)生行溢出時,溢出的數(shù)據(jù)會存放到「溢出頁」中。

當(dāng)發(fā)生行溢出時,在記錄的真實數(shù)據(jù)處只會保存該列的一部分?jǐn)?shù)據(jù),而把剩余的數(shù)據(jù)放在「溢出頁」中,然后真實數(shù)據(jù)處用 20 字節(jié)存儲指向溢出頁的地址,從而可以找到剩余數(shù)據(jù)所在的頁。大致如下圖所示。

總結(jié)

MySQL 的 NULL 值是怎么存放的?

MySQL 的 Compact 行格式中會用「NULL值列表」來標(biāo)記值為 NULL 的列,NULL 值并不會存儲在行格式中的真實數(shù)據(jù)部分。

NULL值列表會占用 1 字節(jié)空間,當(dāng)表中所有字段都定義成 NOT NULL,行格式中就不會有 NULL值列表,這樣可節(jié)省 1 字節(jié)的空間。

行溢出后,MySQL 是怎么處理的?

如果一個數(shù)據(jù)頁存不了一條記錄,InnoDB 存儲引擎會自動將溢出的數(shù)據(jù)存放到「溢出頁」中。

Compact 行格式針對行溢出的處理是這樣的:當(dāng)發(fā)生行溢出時,在記錄的真實數(shù)據(jù)處只會保存該列的一部分?jǐn)?shù)據(jù),而把剩余的數(shù)據(jù)放在「溢出頁」中,然后真實數(shù)據(jù)處用 20 字節(jié)存儲指向溢出頁的地址,從而可以找到剩余數(shù)據(jù)所在的頁。


責(zé)任編輯:華軒 來源: 今日頭條
相關(guān)推薦

2010-05-31 15:23:02

MySQL數(shù)據(jù)庫NUL

2010-09-28 11:48:36

SQL NULL值

2025-06-04 02:55:00

MySQLNULL類型

2024-08-09 11:52:18

2021-11-11 13:05:25

MySQLINSERT

2015-07-20 17:05:38

SQL ServerNULL值

2024-03-15 08:06:58

MySQLJOIN命令

2020-07-09 10:15:55

空值Bug語言

2022-09-13 08:33:05

SQLNULL三值邏輯

2011-03-11 09:53:46

FacebookMySQL

2021-07-26 10:32:54

MySQL數(shù)據(jù)庫存儲

2019-11-15 18:00:18

MySQLSQL數(shù)據(jù)庫

2019-05-28 13:50:27

MySQL幻讀數(shù)據(jù)庫

2024-12-16 08:20:00

2018-02-06 08:32:09

MySQLNull程序員

2019-07-05 07:50:52

數(shù)據(jù)庫空值查詢

2018-01-29 09:21:41

TTL值域名應(yīng)用

2020-01-15 15:29:52

InnoDB數(shù)據(jù)硬盤

2022-07-03 16:26:43

比特幣貨幣加密貨幣

2010-11-26 13:40:58

MySQL空字符串
點贊
收藏

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

主站蜘蛛池模板: 国产激情自拍视频 | 国产综合精品 | 91色视频在线观看 | 日韩欧美中文字幕在线观看 | 亚洲美乳中文字幕 | 成年人网站国产 | 免费一区二区三区 | 99re视频在线 | 综合视频在线 | 天堂在线中文字幕 | 国产成人91视频 | 国产精品久久久久久久久久久免费看 | 亚洲永久免费观看 | 黄视频欧美 | 国产97人人超碰caoprom | 久久不卡区 | 免费毛片网 | 欧美午夜一区 | 亚洲精品一区二区三区免 | 中文字幕在线第一页 | 在线精品亚洲欧美日韩国产 | 黄免费观看视频 | 欧美国产精品一区二区三区 | 久久婷婷色 | 日韩精品在线播放 | 日韩精品一区在线观看 | 97日韩精品 | 免费观看一级视频 | 人人人人人爽 | 国产91精品久久久久久久网曝门 | 亚洲精品久久久一区二区三区 | 亚洲成人精品在线 | 久久最新 | 99精品久久99久久久久 | 亚洲成人福利在线观看 | 国产一区二区精 | 91久久国产精品 | 日韩精品免费视频 | 精品在线一区二区 | 九九视频在线观看 | 欧美精品欧美精品系列 |