MySQL數據類型 - 數據類型存儲要求

數據類型存儲要求

表數據在磁盤上的存儲需求取決於幾個因素。不同的存儲引擎以不同的方式表示數據類型和存儲原始數據。對於一列或整行,表數據可能會被壓縮,這會使表或列的存儲需求計算複雜化。

儘管磁盤上的存儲佈局有所不同,但內部MySQL API(用於通信和交換錶行的信息)使用了一個適用於所有存儲引擎的一致的數據結構。

本節包括MySQL支持的每種數據類型的存儲要求的指導原則和信息,包括對數據類型使用固定大小表示的存儲引擎的內部格式和大小。信息按類別或存儲引擎列出。

即使存儲引擎能夠支持更大的行,但表的內部表示形式的最大行大小爲65535字節。這個數字不包括BLOB或TEXT列,它們只佔這個大小的9到12個字節。對於BLOB和TEXT數據,信息在內部存儲在與行緩衝區不同的內存區域中。不同的存儲引擎根據它們各自處理相應類型的方法,以不同的方式處理這些數據的分配和存儲。

NDB表存儲要求

重要

NDB表使用4字節對齊;所有NDB數據存儲都是以4字節的倍數進行的。因此,通常15個字節的列值在NDB表中需要16個字節。例如,在NDB表中,由於對齊因子的原因,TINYINT、SMALLINT、MEDIUMINT和INTEGER(INT)列類型每個記錄都需要4字節的存儲空間。

每個BIT(M)列佔用M位的存儲空間。儘管單個BIT列不是4字節對齊的,但是NDB爲每行的BIT列所需的前1-32位保留4個字節(32位),然後爲第33-64位保留另外4個字節,依此類推。

雖然NULL本身不需要任何存儲空間,但如果表定義包含了任何允許NULL的列,則NDB每行保留4個字節,最多支持32個NULL列。(如果NDB羣集表定義了32個以上的空列,最多64個空列,則每行保留8個字節。)

使用NDB存儲引擎的每個表都需要一個主鍵;如果不定義主鍵,NDB會創建一個"隱藏"主鍵。這個隱藏的主鍵爲每個表記錄消耗31-35字節。

你可以使用ndb_size.pl Perl腳本估算NDB存儲需求。它連接到當前的MySQL(而不是NDB集羣)數據庫,並創建一個報告,說明如果使用NDB存儲引擎,該數據庫將需要多少空間。

數字型存儲要求

MySQL數據類型 - 數據類型存儲要求

DECIMAL(和NUMERIC)列的值使用二進制格式表示,將九個十進制(以10爲基數)數壓縮爲四個字節。每個值的整數部分和小數部分的存儲分別確定。每9位數的倍數需要4個字節,"剩餘"位數需要4個字節的一部分。下表給出了多餘數字所需的存儲空間。

MySQL數據類型 - 數據類型存儲要求

日期和時間類型存儲要求

對於TIME、DATETIME和TIMESTAMP列,MySQL 5.6.4之前創建的表與從5.6.4開始創建的表所需的存儲空間不同。這是由於5.6.4中的一個更改,允許這些類型具有小數部分,這需要0到3個字節。

MySQL數據類型 - 數據類型存儲要求

從MySQL5.6.4開始,YEAR和DATE的存儲保持不變。但是,TIME、DATETIME和 TIMESTAMP的表示方式不同。DATETIME的壓縮效率更高,非小數部分需要5個字節而不是8個字節,而且這三個都有小數部分,需要0到3個字節,這取決於存儲值的小數秒精度。

MySQL數據類型 - 數據類型存儲要求
例如,TIME(0)、TIME(2)、TIME(4)和TIME(6) 分別使用3、4、5和6個字節。TIME和TIME(0)相等,需要相同的存儲空間。

字符串類型存儲要求

在下表中,M表示聲明的列長度(對於非二進制字符串類型,以字符爲單位,對於二進制字符串類型,以字節爲單位)。L表示給定字符串值的實際長度(以字節爲單位)。
MySQL數據類型 - 數據類型存儲要求

可變長度字符串類型使用長度前綴加數據存儲。長度前綴需要1到4個字節,具體取決於數據類型,前綴的值是L(字符串的字節長度)。例如,存儲MEDIUMTEXT值需要L個字節來存儲該值,再加上三個字節來存儲值的長度。

要計算用於存儲特定CHAR、VARCHAR或TEXT列值的字節數,必須考慮用於該列的字符集以及該值是否包含多字節字符。特別是,使用utf8 Unicode字符集時,必須記住並非所有字符都使用相同的字節數。utf8mb3和utf8mb4字符集分別需要每個字符最多3個和4個字節。

VARCHAR、VARBINARY以及BLOB和TEXT類型是可變長度類型。對於每種情況,存儲要求取決於以下因素:

●列值的實際長度

●列的最大可能長度

●用於列的字符集,因爲某些字符集包含多字節字符

例如,VARCHAR(255)列可以包含最大長度爲255個字符的字符串。假設列使用latin1字符集(每個字符一個字節),實際需要的存儲空間是字符串的長度(L),再加上一個字節來記錄字符串的長度。對於字符串'abcd',L爲4,存儲空間要求5個字節。如果此列被聲明爲使用ucs2雙字節字符集,則存儲空間要求10個字節:'abcd'的長度爲8個字節,該列需要兩個字節來存儲長度,因爲最大長度大於255(最多510個字節)。

VARCHAR或VARBINARY列中可存儲的最大有效字節數受65535字節的最大行大小限制,該行大小在所有列之間共享。對於存儲多字節字符的VARCHAR列,有效存儲的最大字符數會較少。例如,utf8mb4字符每個字符最多需要4個字節,因此使用utf8mb4字符集的VARCHAR列可以聲明爲最多16383個字符。

InnoDB將長度大於或等於768字節的固定長度字段編碼爲可變長度字段,可在頁外存儲。例如,如果字符集的最大字節長度大於3(就像utf8mb4一樣),CHAR(255)列可以超過768字節。

NDB存儲引擎支持可變寬度的列。這意味着NDB集羣表中的VARCHAR列需要與任何其他存儲引擎相同的存儲量,但這些值是4字節對齊的。因此,使用latin1字符集存儲在VARCHAR(50)列中的字符串'abcd'需要8個字節(而不是MyISAM表中相同列值的5個字節)。

TEXT列和BLOB列在NDB中的實現方式不同;TEXT列中的每一行都由兩個獨立的部分組成。其中一個是固定大小(256字節),實際上存儲在原始表中,另一個由超過256字節部分的數據組成,這些數據存儲在一個隱藏的表中。第二個表中的行總是2000字節長。這意味着,如果size<=256(其中size表示行的大小),則text列的大小爲256;否則,大小爲256+size+(2000×(size−256)%2000)。< span="">

ENUM對象的大小由枚舉值的數目決定。一個字節最多用於255個可能值的枚舉。兩個字節用於可能值在256到65535之間的枚舉。

SET對象的大小由集合成員的數目決定。如果集合大小爲N,則對象佔用(N+7)/8字節,四捨五入爲1、2、3、4或8字節。一個SET最多可以有64個成員。

空間類型存儲要求

MySQL使用4個字節存儲SRID,後跟值的WKB表示。LENGTH()函數的作用是返回值存儲所需的字節空間。

JSON存儲要求

通常,JSON列的存儲需求與LONGBLOB或LONGTEXT列的存儲需求大致相同;也就是說,JSON文檔所消耗的空間與存儲在這些類型之一的列中的文檔的字符串表示形式大致相同。但是,對於存儲在JSON文檔中的各個值,二進制編碼(包括查找所需的元數據和字典)會帶來開銷。例如,存儲在JSON文檔中的字符串需要4到10個字節的額外存儲,這取決於字符串的長度以及存儲它的對象或數組的大小。

此外,MySQL對存儲在JSON列中的任何JSON文檔的大小都有限制,它不能大於max_allowed_packet的值。

ndb_size.pl Perl 腳本下載地址:
https://dev.mysql.com/doc/refman/8.0/en/mysql-cluster-programs-ndb-size-pl.html
官方文檔地址:
https://dev.mysql.com/doc/refman/8.0/en/storage-requirements.html


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章