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

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. 编程最好用的字体consolas

    python 自带idle最好用的字体consolas https://www.icourse163.org/learn/BIT-268001?tid=1002788003#/learn/forumd ...

  2. VS2017打包设置

    本文为网络贴文,引用于:http://www.cnblogs.com/overstep/p/6942423.html 一.  安装打包插件: 安装打包插件:Microsoft Visual Studi ...

  3. django admin 设置(转载https://www.cnblogs.com/wumingxiaoyao/p/6928297.html)

    Django admin 一些有用的设置   Django自带的后台管理是Django明显特色之一,可以让我们快速便捷管理数据.后台管理可以在各个app的admin.py文件中进行控制.以下是我最近摸 ...

  4. centos 7设置本地yum资源库

    前言 同样的,是在这两天安装ambari的时候遇到的问题之一,那就是关于centos的本地yum源的制作,当时是一种是制作iso镜像的yum源,还有一种将rpm软件包打成压缩包上传到centos的某一 ...

  5. Shiro Remember me设置

    1. 在Spring的相关配置文件中加入如下Remember me管理器配置: <!-- rememberMe管理器 --> <bean id="rememberMeMan ...

  6. 【Django】重定向

    view函数中使用重定向方法 return HttpResponseRedirect('redir2.html')的时候不自觉的在前面加了request参数,结果报错: TypeError at /b ...

  7. CSS3 white-space属性

    white-space 属性设置如何处理元素内的空白. 可能的值 值 描述 normal 默认.空白会被浏览器忽略. pre 空白会被浏览器保留.其行为方式类似 HTML 中的 <pre> ...

  8. 10.13 新版本go on~

    上午1.5 终审 and 排期 合同管理那边又是切换选项时各种联动,我第一想法是 好麻烦,不想做这个...第二想法才是给我做吧 锻炼锻炼我 然后 分任务的时候 分给我了,,哈哈 开心 虽然我没想躲 但 ...

  9. 186. Reverse Words in a String II 翻转有空格的单词串 里面不变

    [抄题]: Given an input string , reverse the string word by word. Example: Input: ["t"," ...

  10. [leetcode]88. Merge Sorted Array归并有序数组

    Given two sorted integer arrays nums1 and nums2, merge nums2 into nums1 as one sorted array. Note: T ...