欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

MySQL數(shù)據(jù)類(lèi)型varchar詳解

 更新時(shí)間:2014年03月17日 11:10:11   作者:  
這篇文章詳細(xì)介紹了MySQL數(shù)據(jù)類(lèi)型varchar,探討varchar到底能存多長(zhǎng)的數(shù)據(jù)、InnoDB和MyISAM中的varchar等問(wèn)題,需要的朋友可以參考下
1、varchar(N)的邏輯意義
從MySQL4.1開(kāi)始,varchar (N)中的N指的是該字段最多能存儲(chǔ)多少個(gè)字符(characters),不是字節(jié)數(shù)。
不管是一個(gè)中英文字符或者數(shù)字、或者一個(gè)漢字,都當(dāng)做一個(gè)字符。在4.1之前,N表示的是最大存儲(chǔ)的字節(jié)數(shù)(bytes)。
2、varchar(N)到底能存多長(zhǎng)的數(shù)據(jù)
在mysql reference manual上,varchar最多能存儲(chǔ)65535個(gè)字節(jié)的數(shù)據(jù)。varchar 的最大長(zhǎng)度受限于最大行長(zhǎng)度(max row size,65535bytes)。65535并不是一個(gè)很精確的上限,可以繼續(xù)縮小這個(gè)上限。65535個(gè)字節(jié)包括所有字段的長(zhǎng)度,變長(zhǎng)字段的長(zhǎng)度標(biāo)識(shí)(每個(gè)變長(zhǎng)字段額外使用1或者2個(gè)字節(jié)記錄實(shí)際數(shù)據(jù)長(zhǎng)度)、NULL標(biāo)識(shí)位的累計(jì)。
NULL標(biāo)識(shí)位,如果varchar字段定義中帶有default null允許列空,則需要需要1bit來(lái)標(biāo)識(shí),每8個(gè)bits的標(biāo)識(shí)組成一個(gè)字段。一張表中存在N個(gè)varchar字段,那么需要(N+7)/8 (取整)bytes存儲(chǔ)所有的NULL標(biāo)識(shí)位。
如果數(shù)據(jù)表只有一個(gè)varchar字段且該字段DEFAULT NULL,那么該varchar字段的最大長(zhǎng)度為65532個(gè)字節(jié),即65535-2-1=65532 bytes。
復(fù)制代碼 代碼如下:
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;

如果數(shù)據(jù)表只有一個(gè)varchar字段且該字段NOT NULL,那么該varchar字段的最大長(zhǎng)度為65533個(gè)字節(jié),即65535-2=65533bytes。
復(fù)制代碼 代碼如下:
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;

來(lái)個(gè)略微復(fù)雜點(diǎn)的表結(jié)構(gòu),->
復(fù)制代碼 代碼如下:
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最大值可以為多少?
這樣計(jì)算:已知確定的字段長(zhǎng)度為100*8  bytes,8個(gè)varchar(100)字段總共需要變長(zhǎng)字段表示字節(jié)為1*8=8 bytes。每個(gè)NULL字段用1bit標(biāo)識(shí),9個(gè)字段都是default null,那么需要用(9+7)/8bit = 2 bytes存儲(chǔ)NULL標(biāo)識(shí)位。65535-100*8-1*8-2 = 64725 > 256, 那么字段i的最大長(zhǎng)度為64725  - 2 =64723 bytes,即N=64723 。
varchar到底能存多少個(gè)字符?這與使用的字符集相關(guān),latin1、gbk、utf8編碼存放一個(gè)字符分別需要占1、2、3個(gè)字節(jié)。
3、varchar物理存儲(chǔ)
在物理存儲(chǔ)上,varchar使用1到2個(gè)額外的字節(jié)表示實(shí)際存儲(chǔ)的字符串長(zhǎng)度(bytes)。如果列的最大長(zhǎng)度小于256個(gè)字節(jié),用一個(gè)字節(jié)表示(標(biāo)識(shí))。如果最大長(zhǎng)度大于等于256,使用兩個(gè)字節(jié)。
當(dāng)選擇的字符集為latin1,一個(gè)字符占用一個(gè)byte
varchar(255)存儲(chǔ)一個(gè)字符,一共使用2個(gè)bytes物理空間存儲(chǔ)數(shù)據(jù)實(shí)際數(shù)據(jù)長(zhǎng)度和數(shù)據(jù)值。
varchar(256)存儲(chǔ)一個(gè)字符,使用2 bytes表示實(shí)際數(shù)據(jù)長(zhǎng)度,一共需要3 bytes物理存儲(chǔ)空間。
varchar對(duì)于不同的RDBMS引擎,有不通的物理存儲(chǔ)方式,雖然有統(tǒng)一的邏輯意義。對(duì)于mysql的不同存儲(chǔ)引擎,其實(shí)現(xiàn)方法與數(shù)據(jù)的物理存放方式也不同。
4、InnoDB中的varchar
InnoDB中varchar的物理存儲(chǔ)方式與InnoDB使用的innodb_file_format有關(guān)。早期的innodb_file_forma使用的Antelope文件格式,支持redundant和compact兩種row_format。從5.5開(kāi)始或者InnoDB1.1,可以使用一種新的file format,Barracuda。Barracuda兼容Redundant,另外還支持dynamic和compressed兩種row_format.
當(dāng)innodb_file_format=Antelope,ROW_FORMAT=REDUNDANT 或者COMPACT。
innodb的聚集索引(cluster index)僅僅存儲(chǔ)varchar、text、blob字段的前768個(gè)字節(jié),多余的字節(jié)存儲(chǔ)在一個(gè)獨(dú)立的overflow page中,這個(gè)列也被稱(chēng)作off-page。768個(gè)字節(jié)前綴后面緊跟著20字節(jié)指針,指向overflow pages的位置。
另外,在innodb_file_format=Antelope情況下,InnoDB中最多能存儲(chǔ)10個(gè)大字段(需要使用off-page存儲(chǔ))。innodbd的默認(rèn)page size為16KB,InnoDB單行的長(zhǎng)度不能超過(guò)16k/2=8k個(gè)字節(jié),(768+20)*10 < 8k。
當(dāng)innodb_file_format=Barracuda, ROW_FORMAT=DYNAMIC 或者 COMPRESSED
innodb中所有的varchar、text、blob字段數(shù)據(jù)是否完全off-page存儲(chǔ),根據(jù)該字段的長(zhǎng)度和整行的總長(zhǎng)度而定。對(duì)off-page存儲(chǔ)的列,cluster index中僅僅存儲(chǔ)20字節(jié)的指針,指向?qū)嶋H的overflow page存儲(chǔ)位置。如果單行的長(zhǎng)度太大而不能完全適配cluster index page,innodb將會(huì)選擇最長(zhǎng)的列作為off-page存儲(chǔ),直到行的長(zhǎng)度能夠適配cluster index page。
5、MyISAM中的varchar
對(duì)于MyISAM引擎,varchar字段所有數(shù)據(jù)存儲(chǔ)在數(shù)據(jù)行內(nèi)(in-line)。myisam表的row_format也影響到varchar的物理存儲(chǔ)行為。
MyISAM的row_format可以通過(guò)create或者alter sql語(yǔ)句設(shè)為fixed和dynamic。另外可以通過(guò)myisampack生成row_format=compresse的存儲(chǔ)格式。
當(dāng)myisam表中不存在text或者blob類(lèi)型的字段,那么可以把row_format設(shè)置為fixed(也可以為dynamic),否則只能為dynamic。
當(dāng)表中存在varchar字段的時(shí)候,row_format可以設(shè)定為fixed或者dynamic。使用row_format=fixed存儲(chǔ)varchar字段數(shù)據(jù),浪費(fèi)存儲(chǔ)空間,varchar此時(shí)會(huì)定長(zhǎng)存儲(chǔ)。row_format為fixed和dynamic,varchar的物理實(shí)現(xiàn)方式也不同(可以查看源代碼文件field.h和field.cc),因而myisam的row_format在fixed和dynamic之間發(fā)生轉(zhuǎn)換的時(shí)候,varchar字段的物理存儲(chǔ)方式也將會(huì)發(fā)生變化。

相關(guān)文章

最新評(píng)論