varchar or blob:欄位型別的儲存和溢位條件
遇到大欄位儲存的時候,是使用長varchar還是blob(text)?
行模式不同,行溢位的行為也不同:
下面介紹不同行模式的表現:
row format:
compact:
1、compact格式的首部是一個非空的變長欄位長度列表,按照列的順利逆序放置,
當列長度<255的時候,用一個位元組表示;>255的時候用2個位元組表示,變長字
段最大值2個位元組(mysql的varchar最大長度2的16次方=65535)
2、第二部分是NULL標誌位,表示該行是否有NULL值,用1表示。該部分的單位是
bytes。
3、行記錄頭:固定佔用5個位元組(40位),分佈如下:
1 未知
1 未知
1 deleted_flag 刪除標記
1 min_rec_flag 為1,如果該記錄是預先被定為最小的記錄
4 n_owned 改記錄擁有的記錄數
13 heap_no 索引堆中該記錄的排序記錄
3 record_type 記錄型別 000=普通 001=B+樹節點指標 010=informum
011=superemum 1xx=保留
16 next_recorder 頁中下一條記錄的相對位置:(innodb引擎在頁內部是通過鏈
表來串聯各行記錄的)
4、資料記錄行:NULL不佔用該部分的任何資料(NULL除了佔用NULL標誌位,實際儲存
不佔用任何空間) 每行行除了使用者定義的資料,還有兩個隱藏列:事務ID列(6位元組)和
回滾指標列(7位元組),如果沒有定義主鍵,每行還會增加一個rowid列(6位元組)
5、使用 hexdump -C [-v] table.ibd驗證
redundant:
mysql5.0之前的行記錄格式,跟compact記錄格式不同:
NULL的varchar不佔用空間,而空的char需要佔用
compact和redundant行溢位:
1、如果一個能夠至少放入兩行,varchar就不會放到blob頁中,這個
閾值是8098,超過閾值,資料頁儲存768個位元組,剩餘儲存到blob頁
(實驗:py_innodb_page_info, create table t(a varchar(9000)),
repeat('a',8098))
2、blob(text)表也不是全部儲存到blob頁,只有超出限制(8098)才會放置
到blob頁(實驗:同上); 當blob列發生行溢位的時候資料頁儲存
768個位元組,剩餘的儲存的blob頁
compact、redundant統稱:antelope
compressed、dynamic統稱:barracuda
dyanmic,compressed格式:
溢位使用完全的行溢位模式(溢位閾值也是8098),在資料頁只存放20個位元組的指標,
實際的資料都存放到blob頁中。
compressed格式的另外一個功能就是儲存的行資料會使用zlib的演算法進行壓縮,
對blob,text,varchar這類的長型別能進行有效的儲存。
總上:
1、在儲存大欄位型別的時候使用blob(比如圖片等)
2、在需要建索引的時候使用varchar(blob不能建立索引,可以使用字首索引)
3、大欄位型別不能有預設值,有預設值的場合使用varchar
4、varchar有長度限制,表的所有varchar列之和不能超過65535
5、使用大欄位型別的時候,儘量使用的少,避免使用多個
6、儲存長字串的時候看varchar和blob好像沒有太大的效能差異(varchar是
字元比較,blob是二進位制流對比效率會高一些)
參考:
http://www.percona.com/blog/2010/02/09/blob-storage-in-innodb/
《mysql技術內幕innodb儲存引擎》
行模式不同,行溢位的行為也不同:
下面介紹不同行模式的表現:
row format:
compact:
1、compact格式的首部是一個非空的變長欄位長度列表,按照列的順利逆序放置,
當列長度<255的時候,用一個位元組表示;>255的時候用2個位元組表示,變長字
段最大值2個位元組(mysql的varchar最大長度2的16次方=65535)
2、第二部分是NULL標誌位,表示該行是否有NULL值,用1表示。該部分的單位是
bytes。
3、行記錄頭:固定佔用5個位元組(40位),分佈如下:
1 未知
1 未知
1 deleted_flag 刪除標記
1 min_rec_flag 為1,如果該記錄是預先被定為最小的記錄
4 n_owned 改記錄擁有的記錄數
13 heap_no 索引堆中該記錄的排序記錄
3 record_type 記錄型別 000=普通 001=B+樹節點指標 010=informum
011=superemum 1xx=保留
16 next_recorder 頁中下一條記錄的相對位置:(innodb引擎在頁內部是通過鏈
表來串聯各行記錄的)
4、資料記錄行:NULL不佔用該部分的任何資料(NULL除了佔用NULL標誌位,實際儲存
不佔用任何空間) 每行行除了使用者定義的資料,還有兩個隱藏列:事務ID列(6位元組)和
回滾指標列(7位元組),如果沒有定義主鍵,每行還會增加一個rowid列(6位元組)
5、使用 hexdump -C [-v] table.ibd驗證
redundant:
mysql5.0之前的行記錄格式,跟compact記錄格式不同:
NULL的varchar不佔用空間,而空的char需要佔用
compact和redundant行溢位:
1、如果一個能夠至少放入兩行,varchar就不會放到blob頁中,這個
閾值是8098,超過閾值,資料頁儲存768個位元組,剩餘儲存到blob頁
(實驗:py_innodb_page_info, create table t(a varchar(9000)),
repeat('a',8098))
2、blob(text)表也不是全部儲存到blob頁,只有超出限制(8098)才會放置
到blob頁(實驗:同上); 當blob列發生行溢位的時候資料頁儲存
768個位元組,剩餘的儲存的blob頁
compact、redundant統稱:antelope
compressed、dynamic統稱:barracuda
dyanmic,compressed格式:
溢位使用完全的行溢位模式(溢位閾值也是8098),在資料頁只存放20個位元組的指標,
實際的資料都存放到blob頁中。
compressed格式的另外一個功能就是儲存的行資料會使用zlib的演算法進行壓縮,
對blob,text,varchar這類的長型別能進行有效的儲存。
總上:
1、在儲存大欄位型別的時候使用blob(比如圖片等)
2、在需要建索引的時候使用varchar(blob不能建立索引,可以使用字首索引)
3、大欄位型別不能有預設值,有預設值的場合使用varchar
4、varchar有長度限制,表的所有varchar列之和不能超過65535
5、使用大欄位型別的時候,儘量使用的少,避免使用多個
6、儲存長字串的時候看varchar和blob好像沒有太大的效能差異(varchar是
字元比較,blob是二進位制流對比效率會高一些)
參考:
http://www.percona.com/blog/2010/02/09/blob-storage-in-innodb/
《mysql技術內幕innodb儲存引擎》
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/20625855/viewspace-1453859/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- varchar型別的欄位儲存純數字的排序型別排序
- 在SQL Server中修改欄位型別和欄位名稱的儲存過程SQLServer型別儲存過程
- MySQL中TEXT與BLOB欄位型別的區別MySql型別
- PHP 操作 mysql blob 資料型別的欄位PHPMySql資料型別
- mysql的text/blob和行溢位MySql
- SAP WM中階儲存型別裡的Full stk rmvl 欄位和Return Storage type欄位型別
- WHRER條件裡的資料型別必須和欄位資料型別一致資料型別
- MySQL VARCHAR型別欄位到底可以定義多長MySql型別
- mssql sqlserver 可以儲存二進位制資料的欄位型別詳解SQLServer型別
- sql語句修改欄位型別和增加欄位SQL型別
- mysql變長型別欄位varchar值更新變長或變短底層檔案儲存原理MySql型別
- oracle的欄位型別Oracle型別
- 溢位OF和進位CF區別
- 保留兩位小數:資料庫欄位型別NUMBER,Java欄位型別Double型別資料庫型別Java
- MySQL中欄位型別與合理的選擇欄位型別;int(11)最大長度是多少?varchar最大長度是多少?MySql型別
- 檢查型別是否溢位型別
- 小議lob欄位結構和儲存
- Mysql varchar型別欄位為什麼經常定義為255MySql型別
- 修改表的欄位型別型別
- 查詢/刪除重複的資料(單個欄位和多個欄位條件)
- 關於mysql設定varchar 欄位的預設值''和null的區別,以及varchar和char的區別MySqlNull
- Oracle 修改欄位型別和長度Oracle型別
- MongoDB更改欄位型別MongoDB型別
- MySQL欄位新增註釋,但不改變欄位的型別MySql型別
- 物件型介面 / 定製操作型別和欄位物件型別
- [BUG反饋]模型中的欄位型別為日期是隻儲存了年份模型型別
- Spark儲存Parquet資料到Hive,對map、array、struct欄位型別的處理SparkHiveStruct型別
- 聯機重定義修改欄位型別(NVARCHAR2->VARCHAR2)型別
- 如何將varchar2修改為clob型別欄位(使用long過渡)型別
- BLOB及CLOB欄位處理
- Mysql BLOB、BLOB與TEXT區別及效能影響、將BLOB型別轉換成VARCHAR型別MySql型別
- 記憶體溢位:native溢位 和 上層溢位記憶體溢位
- MongoDB中的欄位型別IdMongoDB型別
- oracle 修改欄位型別的方法Oracle型別
- [提問交流]建立模型,新增屬性,欄位型別如何設定2位小數的欄位型別模型型別
- MySQL 數值型別溢位處理MySql型別
- MySQL欄位型別最全解析MySql型別
- date、timestamp欄位型別型別