基於MySQL在磁盤上存儲NULL值
1 為何不能直接存個NULL?
NULL值列表,一行數據裡可能有的字段值是NULL,比如nickname字段,允許為NULL,存儲時,如果沒賦值,這字段值就是NULL。
假設這個字段的NULL值在磁盤存儲時,就是按“NULL”字符串存儲的,是不是很浪費存儲空間而且還奇怪?
2 到底怎麼存儲?
不通過字符串,而是通過二進制bit位存儲,一行數據裡假設有多個字段的值都是NULL,那麼這多個字段的NULL,就會以bit位形式存放在NULL值列表。
如下表:
CREATE TABLE customer ( name VARCHAR(10) NOT NULL, address VARCHAR(20), gender CHAR(1), job VARCHAR(30), school VARCHAR(50) ) ROW_FORMAT=COMPACT;
有4個變長字段,還有個定長字段,name
聲明NOT NULL
,其他4個字段都可能NULL
如下一行數據怎麼存儲在磁盤呢:
jack NULL m NULL xx_school
有倆字段都是NULL
3 一行數據的磁盤存儲格式
思考上面那個表裡的那行案例數據,在磁盤上如何存儲呢,因為他有多個變長字段,還有多個字段允許為NULL。首先我們先回顧一下,一行數據在磁盤上的存儲格式應該是下面這樣的:
變長字段長度列表 NULL值列表 頭信息 column1=value1 column2=value2 … columnN=valueN
4個變長字段,逆序先放school字段的長度,再放job、address、name幾個字段的值長度?
但要區分一個問題,若這變長字段值為NULL,就不用在變長字段長度列表裡存放他的值長度,所以在上面那行數據,隻有name和school兩個變長字段有值,把他們的長度按照逆序放在變長字段長度列表即可:
0x09 0x04 NULL值列表 頭信息 column1=value1 column2=value2 … columnN=valueN
所有允許值為NULL的字段,不是說值就得是NULL,隻要是允許為NULL的字段,每個字段都有個二進制bit位值:
- bit值是1說明是NULL
- bit值是0說明不是NULL
比如上面4個字段都允許為NULL,每個人都會有一個bit位,這一行數據的值是
jack NULL m NULL xx_school
其中2個字段是null,2個字段不是null,所以4個bit位應該是:1010
但實際放在NULL值列表時,按逆序放,所以NULL值列表裡放的:0101,整體這一行數據如下:
0x09 0x04 0101 頭信息 column1=value1 column2=value2 … columnN=valueN
實際NULL值列表存放時,一般起碼8個bit位的倍數,不足8個bit位就高位補0,所以實際存放如下:
0x09 0x04 00000101 頭信息 column1=value1 column2=value2 … columnN=valueN
4 如何讀磁盤的一行數據?
磁盤數據存儲格式:
0x09 0x04 00000101 頭信息 column1=value1 column2=value2 … columnN=valueN
先讀:
- 變長字段長度列表
就知道有幾個變長字段
- NULL值列表
哪些變長字段是NULL:
從變長字段長度列表中解析出不為NULL的變長字段的值長度,然後也知道哪些字段是NULL。根據這些信息,就能從實際的列值存儲區域裡,把你每個字段的值讀取出來瞭。
- 變長字段值,就按值長度讀取,若為NULL,就知道他是個NULL,沒有值存儲
- 定長字段,按定長長度讀取
到此這篇關於基於MySQL在磁盤上存儲NULL值的文章就介紹到這瞭,更多相關在磁盤上存儲NULL值內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!
推薦閱讀:
- MySQL約束之默認約束default與零填充約束zerofill
- MySQL如何優化索引
- MySQL索引結構詳細解析
- Mysql數據庫表中為什麼有索引卻沒有提高查詢速度
- MySQL數據庫之數據表操作DDL數據定義語言