MySQL資料類型varchar詳解_Mysql

來源:互聯網
上載者:User
1、varchar(N)的邏輯意義
從MySQL4.1開始,varchar (N)中的N指的是該欄位最多能儲存多少個字元(characters),不是位元組數。
不管是一個中英文字元或者數字、或者一個漢字,都當做一個字元。在4.1之前,N表示的是最大儲存的位元組數(bytes)。
2、varchar(N)到底能存多長的資料
在mysql reference manual上,varchar最多能儲存65535個位元組的資料。varchar 的最大長度受限於最大行長度(max row size,65535bytes)。65535並不是一個很精確的上限,可以繼續縮小這個上限。65535個位元組包括所有欄位的長度,變長欄位的長度標識(每個變長欄位額外使用1或者2個位元組記錄實際資料長度)、NULL標識位的累計。
NULL標識位,如果varchar欄位定義中帶有default null允許列空,則需要需要1bit來標識,每8個bits的標識組成一個欄位。一張表中存在N個varchar欄位,那麼需要(N+7)/8 (取整)bytes儲存所有的NULL標識位。
如果資料表只有一個varchar欄位且該欄位DEFAULT NULL,那麼該varchar欄位的最大長度為65532個位元組,即65535-2-1=65532 bytes。
複製代碼 代碼如下:
CREATE TABLE `vchar1` (   `name` VARCHAR(65533)  NOT  NULL ) ENGINE=InnoDB DEFAULT CHARSET=latin1;
CREATE TABLE `vchar2` (   `name` VARCHAR(65533)  NOT  NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1;

如果資料表只有一個varchar欄位且該欄位NOT NULL,那麼該varchar欄位的最大長度為65533個位元組,即65535-2=65533bytes。
複製代碼 代碼如下:
CREATE TABLE `vchar3` (   `name` VARCHAR(65532)  DEFAULT  NULL ) ENGINE=InnoDB DEFAULT CHARSET=latin1;
CREATE TABLE `vchar4` (   `name` VARCHAR(65532)  DEFAULT  NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1;

來個略微複雜點的表結構,->
複製代碼 代碼如下:
CREATE TABLE `tv` (
`a` VARCHAR(100) DEFAULT NULL,
`b` VARCHAR(100) DEFAULT NULL,
`c` VARCHAR(100) DEFAULT NULL,
`d` VARCHAR(100) DEFAULT NULL,
`e` VARCHAR(100) DEFAULT NULL,
`f` VARCHAR(100) DEFAULT NULL,
`g` VARCHAR(100) DEFAULT NULL,
`h` VARCHAR(100) DEFAULT NULL,
`i` VARCHAR(N) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1

`i` varchar(N) DEFAULT NULL中N最大值可以為多少?
這樣計算:已知確定的欄位長度為100*8  bytes,8個varchar(100)欄位總共需要變長欄位表示位元組為1*8=8 bytes。每個NULL欄位用1bit標識,9個欄位都是default null,那麼需要用(9+7)/8bit = 2 bytes儲存NULL標識位。65535-100*8-1*8-2 = 64725 > 256, 那麼欄位i的最大長度為64725  - 2 =64723 bytes,即N=64723 。
varchar到底能存多少個字元?這與使用的字元集相關,latin1、gbk、utf8編碼存放一個字元分別需要佔1、2、3個位元組。
3、varchar實體儲存體
在實體儲存體上,varchar使用1到2個額外的位元組表示實際儲存的字串長度(bytes)。如果列的最大長度小於256個位元組,用一個位元組表示(標識)。如果最大長度大於等於256,使用兩個位元組。
當選擇的字元集為latin1,一個字元佔用一個byte
varchar(255)儲存一個字元,一共使用2個bytes物理空間儲存資料實際資料長度和資料值。
varchar(256)儲存一個字元,使用2 bytes表示實際資料長度,一共需要3 bytes實體儲存體空間。
varchar對於不同的RDBMS引擎,有不通的實體儲存體方式,雖然有統一的邏輯意義。對於mysql的不同儲存引擎,其實現方法與資料的物理存放方式也不同。
4、InnoDB中的varchar
InnoDB中varchar的實體儲存體方式與InnoDB使用的innodb_file_format有關。早期的innodb_file_forma使用的Antelope檔案格式,支援redundant和compact兩種row_format。從5.5開始或者InnoDB1.1,可以使用一種新的file format,Barracuda。Barracuda相容Redundant,另外還支援dynamic和compressed兩種row_format.
當innodb_file_format=Antelope,ROW_FORMAT=REDUNDANT 或者COMPACT。
innodb的叢集索引(cluster index)僅僅儲存varchar、text、blob欄位的前768個位元組,多餘的位元組儲存在一個獨立的overflow page中,這個列也被稱作off-page。768個位元組首碼後面緊跟著20位元組指標,指向overflow pages的位置。
另外,在innodb_file_format=Antelope情況下,InnoDB中最多能儲存10個大欄位(需要使用off-page儲存)。innodbd的預設page size為16KB,InnoDB單行的長度不能超過16k/2=8k個位元組,(768+20)*10 < 8k。
當innodb_file_format=Barracuda, ROW_FORMAT=DYNAMIC 或者 COMPRESSED
innodb中所有的varchar、text、blob欄位資料是否完全off-page儲存,根據該欄位的長度和整行的總長度而定。對off-page儲存的列,cluster index中僅僅儲存20位元組的指標,指向實際的overflow page儲存位置。如果單行的長度太大而不能完全適配cluster index page,innodb將會選擇最長的列作為off-page儲存,直到行的長度能夠適配cluster index page。
5、MyISAM中的varchar
對於MyISAM引擎,varchar欄位所有資料存放區在資料行內(in-line)。myisam表的row_format也影響到varchar的實體儲存體行為。
MyISAM的row_format可以通過create或者alter sql語句設為fixed和dynamic。另外可以通過myisampack產生row_format=compresse的儲存格式。
當myisam表中不存在text或者blob類型的欄位,那麼可以把row_format設定為fixed(也可以為dynamic),否則只能為dynamic。
當表中存在varchar欄位的時候,row_format可以設定為fixed或者dynamic。使用row_format=fixed儲存varchar欄位資料,浪費儲存空間,varchar此時會定長儲存。row_format為fixed和dynamic,varchar的物理實現方式也不同(可以查看原始碼檔案field.h和field.cc),因而myisam的row_format在fixed和dynamic之間發生轉換的時候,varchar欄位的實體儲存體方式也將會發生變化。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.