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/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- MySQL中TEXT與BLOB欄位型別的區別MySql型別
- PHP 操作 mysql blob 資料型別的欄位PHPMySql資料型別
- SAP WM中階儲存型別裡的Full stk rmvl 欄位和Return Storage type欄位型別
- MySQL VARCHAR型別欄位到底可以定義多長MySql型別
- mssql sqlserver 可以儲存二進位制資料的欄位型別詳解SQLServer型別
- mysql變長型別欄位varchar值更新變長或變短底層檔案儲存原理MySql型別
- sql語句修改欄位型別和增加欄位SQL型別
- 關於mysql設定varchar 欄位的預設值''和null的區別,以及varchar和char的區別MySqlNull
- 檢查型別是否溢位型別
- Mysql varchar型別欄位為什麼經常定義為255MySql型別
- 查詢/刪除重複的資料(單個欄位和多個欄位條件)
- 聯機重定義修改欄位型別(NVARCHAR2->VARCHAR2)型別
- Oracle 修改欄位型別和長度Oracle型別
- Mysql BLOB、BLOB與TEXT區別及效能影響、將BLOB型別轉換成VARCHAR型別MySql型別
- MongoDB更改欄位型別MongoDB型別
- [BUG反饋]模型中的欄位型別為日期是隻儲存了年份模型型別
- Spark儲存Parquet資料到Hive,對map、array、struct欄位型別的處理SparkHiveStruct型別
- MySQL欄位新增註釋,但不改變欄位的型別MySql型別
- [提問交流]建立模型,新增屬性,欄位型別如何設定2位小數的欄位型別模型型別
- MySQL 數值型別溢位處理MySql型別
- ES Mapping ,1 欄位型別APP型別
- MySQL欄位型別最全解析MySql型別
- SAP 銷售條件表增強欄位
- 【mongo】mongo 欄位型別互轉Go型別
- JSON欄位型別在ORM中的使用JSON型別ORM
- SAP MIGO 報錯-在例程WERT_SIMULIEREN欄位NEUER_PREIS中欄位溢位-Go
- mysql的varchar欄位最大長度真的是65535嗎?MySql
- mysql表操作(alter)/mysql欄位型別MySql型別
- 欄位管理,為什麼只有新增的時候才自動匹配欄位型別型別
- select * 和 select 所有欄位的區別
- 如何在Spring Data MongoDB 中儲存和查詢動態欄位SpringMongoDB
- 多型關聯自定義的型別欄位的處理多型型別
- SAP CRM銷售訂單UI上的欄位對應的資料庫表儲存欄位:requested start date和end dateUI資料庫
- 關於Thinkphp 使用AdvModel來讀取Blob欄位PHP
- 儲存過程、觸發器、遊標、檢視、自定義函式 欄位型別、欄位可空、統計欄位、邏輯刪除 許可權系統資料庫&無限極類別設計儲存過程觸發器函式型別資料庫
- ORACLE 表char欄位混合儲存數字和字母類似資料時按數字的where條件查詢報錯ORA-01722Oracle
- Java中redis用String儲存型別單獨設定二維表中每條資料或每個欄位的過期時間JavaRedis型別
- 阿里大佬講解Java記憶體溢位示例(堆溢位、棧溢位)阿里Java記憶體溢位
- 溢位、上溢、下溢