##=====================================================================================##

MySQL支持的字符类型:

类型 大小 用途
CHAR 0-255字节 定长字符串
VARCHAR 0-65535 字节 变长字符串
TINYBLOB 0-255字节 不超过 255 个字符的二进制字符串
TINYTEXT 0-255字节 短文本字符串
BLOB 0-65 535字节 二进制形式的长文本数据
TEXT 0-65 535字节 长文本数据
MEDIUMBLOB 0-16 777 215字节 二进制形式的中等长度文本数据
MEDIUMTEXT 0-16 777 215字节 中等长度文本数据
LONGBLOB 0-4 294 967 295字节 二进制形式的极大文本数据
LONGTEXT 0-4 294 967 295字节 极大文本数据

##=====================================================================================##

CHAR(N)和VARCHAR(N)中N的问题

在MySQL 4.1版本前,CHAR(N)和VARCHAR(N)中的N指的是字节长度。
从MYSQL 4.1版本后,CHAR(N)和VARCHAR(N)中的N指的是字符的长度。

##=====================================================================================##

字节长度和字符长度

使用length(str)来查看str占用的字节数
使用char_length(str)表示str占用的字符数

对于多字节的字符编码来说,不同字符的编码长度不一样,如对于UTF来说,‘a’需要一个字节来存放,而对于中文‘你’则需要3字节来存放,
因此对于使用UTF8来存放的CHAR(N) 来说,最低使用N字节点空间,最高使用3N字节的空间,因此存储引擎在内部将CHAR类型视为变长字符类型来处理。

在MySQL中定义行的长度不能超过65535字节,因此会根据数据的字符集来限制VARCHAR(N)的N值,如当使用UTF8编码时,每个字符占用3个字节,一行的最大长度只能存放(65535-3)/3=21844个字符(在不考虑其他额外记录信息情况下),当创建表时指定的N超过最大值时,会将VARCHAR(N)类型装换为mediumtext类型。

DROP TABLE IF EXISTS tb1007;
DROP TABLE IF EXISTS tb1008;
CREATE TABLE `tb1007` (
`id` INT (11) NOT NULL AUTO_INCREMENT,
`c1` VARCHAR (21800) DEFAULT NULL,
PRIMARY KEY (`id`)
);
CREATE TABLE `tb1008` (
`id` INT (11) NOT NULL AUTO_INCREMENT,
`c1` VARCHAR (21900) DEFAULT NULL,
PRIMARY KEY (`id`)
);
SHOW CREATE TABLE tb1007;
SHOW CREATE TABLE tb1008; 输出:
CREATE TABLE `tb1007` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`c1` varchar(21800) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 CREATE TABLE `tb1008` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`c1` mediumtext,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8

PS1:对于VARCHAR类型,除包括字符数据需要的空间外,还额外需要1或2个字节来记录字符串的长度,对于字符串长度小于或等于255字节时使用1个字节表示,大于255字节的字符串的使用2字节表示。

PS2:当MySQL表使用ROW_FORMAT=FIXED时,对于定义VARCHAR类型的列会使用定长存储。

##=====================================================================================##

VARCHAR类型字符串空格问题
在MySQL 4.1及其之前版本,MySQL会截取字符串尾部的空格,
在MySQL 5.0及之后版本中,MySQL会保留字符串结尾的空格。
尾部空格是否截断是在MySQL Server层进行处理,与存储引擎层无关。
在MySQL 5.6版本测试如下:

create table tb002(c1 varchar());
insert into tb002(c1)values(' abc ');
select concat('',c1,'') from tb002;
+------------------------+
| concat('',c1,'') |
+------------------------+
| abc |
+------------------------+

##=====================================================================================##

CHAR类型字符串空格问题
无论在MySQL 4.1版本之前还是之后,对于CHAR类型字符串,在检索时总会删除所有的末尾空格。
在MySQL 5.6版本测试如下:

drop table tb002;
create table tb002(c1 char());
insert into tb002(c1)values(' abc ');
select concat('',c1,'') from tb002;
+------------------------+
| concat('',c1,'') |
+------------------------+
| abc456 |
+------------------------+

##=====================================================================================##
VARCHAR和CHAR效率问题
1、当存储的所有数据都接近同一最大长度时,使用CHAR存放效率更高
2、当存储的数据长度差距较大,尤其少量数据长度较大时,使用CHAR存放会浪费较多的存储空间,使用VARCHAR存放更为合理
3、无论使用VARCHAR还是使用CHAR,都应遵守最小存储空间原则,避免将N设置过大造成性能问题。

##=====================================================================================##
其他字符问题
1、对于BINARY和VARBINARY类型,在存储时使用字节码来存放,在比较时依次按照每一个字节来对比
2、BINARY类型采用\0(零字节)而不是空格来进行填充
3、数据如何存储取决于存储引擎,Memory存储引擎只支持定长列,且Memroy存储引擎不支持BLOB和TEXT类型。
4、字符串填充和截取空格的行为在MySQL服务器层进行处理,因此对于所有存储引擎都一样

##=====================================================================================##
限制VARCHAR(N)中N值大小的意义:

对于不同存储引擎,在存放VARCHAR(N)类型数据时采用不同的存储方式,对于Innodb存储引擎,使用额外来1-2byte空间来存放变长列的数据长度,因此数据使用的存储空间与N值无明显关系,N值过大也不会导致数据占用过多的磁盘空间。
当数据从存储引擎读取到MySQL内存中时,数据在存储引擎中存放方式和在内存中的存放方式不同,存储引擎负责将数据进行转换放入至MySQL内存,而MySQL通常会分配固定大小的内存块来存放数据,因此对于VARCHAR(N)类型数据,当N值越大时,可能会导致MySQL分配越多的内存来存放数据,尤其在使用内存临时表进行排序或操作时,N值过大可能会导致内存临时表超过参数tmp_table_size阀值而升级为磁盘临时表,引发严重的性能问题。

PS1:由于测试过程中无法使用profile工具查看语句使用的内存信息,对于两个数据相同但VARCHAR(N)列N值差异较大的两个表做相同SQL查询发现性能没有太大差异,生成的临时表消耗的IO也接近,无法明确验证上述观点。

MySQL 基础--字符类型的更多相关文章

  1. Mysql 数据库字符类型详解

    MySQL 中提供了多种对字符数据的存储类型,不同的版本可能有所差异.以5.0 版本为例,MySQL 包括了CHAR.VARCHAR.BINARY.VARBINARY.BLOB.TEXT.ENUM 和 ...

  2. java 基础 字符类型

    1.char类型的字面量可以是一个英文字母.字符或一个汉字,并且由单引号包括. 2.Java底层使用一个16位的整数来处理字符类型,该数值是一个字符的unicode编码值. unicode: 1.un ...

  3. MySQL基础--字符函数

    1.UPPER和UCASE返回字符串str,根据当前字符集映射(缺省是ISO-8859-1 Latin1)把所有的字符改变成大写.该函数对多字节是可靠的. 2.LOWER和LCASE返回字符串str, ...

  4. MySQL 基础--时间戳类型

    时间戳数据存储 .TimeStamp的取值范围为'1970-01-01 00:00:01' UTC 至'2038-01-19 03:14:07' UTC: .在存储时间戳数据时先将数据转换为UTC时区 ...

  5. 003-python基础-字符类型

    基本数据类型(int,bool,str) 1.基本数据数据类型: int 整数 str 字符串. 一般不存放大量的数据 bool 布尔值. 用来判断. True, False list 列表.用来存放 ...

  6. mysql基础 日期类型

  7. mysql 基础,列类型

  8. { MySQL基础数据类型}一 介绍 二 数值类型 三 日期类型 四 字符串类型 五 枚举类型与集合类型

    MySQL基础数据类型 阅读目录 一 介绍 二 数值类型 三 日期类型 四 字符串类型 五 枚举类型与集合类型 一 介绍 存储引擎决定了表的类型,而表内存放的数据也要有不同的类型,每种数据类型都有自己 ...

  9. Mysql基础1-基础语法-字段类型

    主要: 基础 字段类型 基础 基本概念 1) 数据库分类 层次数据库,网状数据库,关系数据库 常见:SQL Server, Oracle,infomix,sybase,ibmDB2,Mysql 2)数 ...

随机推荐

  1. linux 僵尸进程查看方式

    ps -A -ostat,ppid,pid,cmd |grep -e '^[Zz]' # 结果 Z 169925 49893 [sw] <defunct> Z 169925 120690 ...

  2. python大法好——继承、多态

    1.继承 类的继承 面向对象的编程带来的主要好处之一是代码的重用,实现这种重用的方法之一是通过继承机制. 通过继承创建的新类称为子类或派生类,被继承的类称为基类.父类或超类. 继承语法 class 派 ...

  3. RocketMQ入门(Filter)_5

    RocketMQ中存储的消息对于消费者来说,并不完全都是他们需要的,因此需要对消息进行过滤. 订阅Topic主题 ,选择Tags都是我们简单的过滤.Topic是大分类,Tags是二级分类. Rocke ...

  4. Web页面长时间无操作后再获取焦点时转到登录界面

    今天开始讲新浪博客搬到博客园.        在工作中遇到的小问题,感觉有点意思,就记录下来吧!        该问题分为两种情况,一.Web页面长时间无操作后,在对其进行操作,比如点击“首页”.“设 ...

  5. 楚乔传 Princess Agents

    英文片名是:Princess Agents 公主特工,哈哈,女主角是公主...所有隐藏的线索都暴露了...这么搞笑呢.

  6. python学习笔记之读取配置文件【转自https://my.oschina.net/u/3041656/blog/793467】

    [转自https://my.oschina.net/u/3041656/blog/793467] 最近在接触利用python来写测试框架,本人也是个刚接触python,所以是个小菜鸟,今天开始,一点点 ...

  7. 使用rpm-build制作nginx的rpm包

    2014-11-27 11:05:49   一.RPM包的分类 RPM有五种基本的操作功能:安装.卸载.升级.查询和验证. linux软件包分为两大类: (1)二进制类包,包括rpm安装包(一般分为i ...

  8. 20175314 《Java程序设计》第三周学习总结

    20175314 <Java程序设计>第三周学习总结 教材学习内容总结 编程语言的发展事是从面向机器(汇编.机器)到面向过程(C)再到面向对象(Java) 成员变量: 1.成员变量定义在类 ...

  9. Django缓存设置

    由于Django构建得是动态网站,每次客户端请求都要严重依赖数据库,当程序访问量大时,耗时必然会更加明显,最简单解决方式是使用:缓存,缓存将一个某个views的返回值保存至内存或者memcache中, ...

  10. 688. Knight Probability in Chessboard棋子留在棋盘上的概率

    [抄题]: On an NxN chessboard, a knight starts at the r-th row and c-th column and attempts to make exa ...