MySQL数据类型varchar详解

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字段的物理存储方式也将会发生变化。

(0)

相关推荐

  • MySQL 数据类型 详解

    1.整型 MySQL数据类型 含义(有符号) tinyint(m) 1个字节 范围(-128~127) smallint(m) 2个字节 范围(-32768~32767) mediumint(m) 3个字节 范围(-8388608~8388607) int(m) 4个字节 范围(-2147483648~2147483647) bigint(m) 8个字节 范围(+-9.22*10的18次方) 取值范围如果加了unsigned,则最大值翻倍,如tinyint unsigned的取值范围为(0~25

  • mysql存储引擎和数据类型(二)

    存储引擎: 1. 查看支持的存储引擎:       show engines \G;       show variables like 'have%'; 2. 查看默认存储引擎:       show variables like 'storage_engine%'; 3. 修改默认的存储引擎:  ① 安装版可以通过向导的方式:     "开始"-> "程序" -> "MySQL" -> "MySQL Server

  • MySQL数据类型和常用字段属性总结

    前言 好比C++中,定义int类型需要多少字节,定义double类型需要多少字节一样,MySQL对表每个列中的数据也会实行严格控制,这是数据驱动应用程序成功的关键.M前言 好比C++中,定义int类型需要多少字节,定义double类型需要多少字节一样,MySQL对表每个列中的数据也会实行严格控制,这是数据驱动应用程序成功的关键.MySQL提供了一组可以赋给表中各个列的数据类型,每个类型都强制数据满足为该数据类型预先确定的一组规则,例如大小.类型及格式. 这里先总结数据类型.MySQL中的数据类型

  • MySQL Memory 存储引擎浅析

    后来看到博客园在用NorthScale Memcached Server(官方站点:http://www.couchbase.com/products-and-services/memcached),貌似共享收费,又犹豫了.其实项目里的需求很简单,也想自己用.Net Cache来实现,但稳定性难以评估,开发维护成本又似乎太大,没办法,My SQL Memory Storage成了唯一选择,因为几乎不怎么需要编写代码. 先看官方手册,然后写了个简单的性能测试.因为官方最新的文档都是英文版的,所以译

  • MySQL存储引擎总结

    前言 在数据库中存的就是一张张有着千丝万缕关系的表,所以表设计的好坏,将直接影响着整个数据库.而在设计表的时候,我们都会关注一个问题,使用什么存储引擎.等一下,存储引擎?什么是存储引擎? 什么是存储引擎? 关系数据库表是用于存储和组织信息的数据结构,可以将表理解为由行和列组成的表格,类似于Excel的电子表格的形式.有的表简单,有的表复杂,有的表根本不用来存储任何长期的数据,有的表读取时非常快,但是插入数据时去很差:而我们在实际开发过程中,就可能需要各种各样的表,不同的表,就意味着存储不同类型的

  • 浅谈MySQL存储引擎选择 InnoDB与MyISAM的优缺点分析

    下面先让我们回答一些问题: ◆你的数据库有外键吗? ◆你需要事务支持吗? ◆你需要全文索引吗? ◆你经常使用什么样的查询模式? ◆你的数据有多大? 思考上面这些问题可以让你找到合适的方向,但那并不是绝对的.如果你需要事务处理或是外键,那么InnoDB 可能是比较好的方式.如果你需要全文索引,那么通常来说 MyISAM是好的选择,因为这是系统内建的,然而,我们其实并不会经常地去测试两百万行记录.所以,就算是慢一点,我们可以通过使用Sphinx从InnoDB中获得全文索引. 数据的大小,是一个影响你

  • Mysql5.5 InnoDB存储引擎配置和优化

    环境为CentOS系统,1G内存,Mysql5.5.30.在/etc/my.cnf内添加: 复制代码 代码如下: skip-external-lockingskip-name-resolvemax_connections = 1024query_cache_size = 16Msort_buffer_size = 1Mtable_cache = 256innodb_buffer_pool_size = 128Minnodb_additional_mem_pool_size = 4Minnodb_

  • MySQL存储引擎 InnoDB与MyISAM的区别

    基本的差别:MyISAM类型不支持事务处理等高级处理,而InnoDB类型支持.MyISAM类型的表强调的是性能,其执行数度比InnoDB类型更快,但是不提供事务支持,而InnoDB提供事务支持以及外部键等高级数据库功能.以下是一些细节和具体实现的差别:1.InnoDB不支持FULLTEXT类型的索引.2.InnoDB 中不保存表的具体行数,也就是说,执行select count(*) from table时,InnoDB要扫描一遍整个表来计算有多少行,但是MyISAM只要简单的读出保存好的行数即

  • MySQL日期数据类型、时间类型使用总结

    MySQL 日期类型:日期格式.所占存储空间.日期范围 比较. 日期类型        存储空间       日期格式                 日期范围 ------------ ---------   --------------------- ----------------------------------------- datetime       8 bytes   YYYY-MM-DD HH:MM:SS   1000-01-01 00:00:00 ~ 9999-12-31

  • MySQL存储引擎中的MyISAM和InnoDB区别详解

    在使用MySQL的过程中对MyISAM和InnoDB这两个概念存在了些疑问,到底两者引擎有何分别一直是存在我心中的疑问.为了解开这个谜题,搜寻了网络,找到了如下信息: MyISAM是MySQL的默认数据库引擎(5.5版之前),由早期的ISAM(Indexed Sequential Access Method:有索引的顺序访问方法)所改良.虽然性能极佳,但却有一个缺点:不支持事务处理(transaction).不过,在这几年的发展下,MySQL也导入了InnoDB(另一种数据库引擎),以强化参考完

随机推荐