=================================================

VARCHAR类型存储空间问题

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

对于VARCHAR类型,除包括字符数据需要的空间外,还额外需要1或2个字节来记录字符串的长度,对于字符串长度小于或等于255字节时使用1个字节表示,大于255字节的字符串的使用2字节表示。对于多字节的字符编码来说,不同字符的编码长度不一样,如对于UTF来说,‘a’需要一个字节来存放,而对于中文‘你’则需要3字节来存放,

因此对于使用UTF8来存放的CHAR(N) 来说,最低使用N字节点空间,最高使用3N字节的空间,因此存储引擎在内部将CHAR类型视为变长字符类型来处理。

使用length(str)来查看str占用的字节数

使用char_length(str)表示str占用的字符数

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

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

对于VARCHAR(N)字段的结尾空格处理:

在MySQL 4.1及其之前版本,MySQL会截取字符串尾部的空格,

在MySQL 5.0及之后版本中,MySQL会保留字符串结尾的空格。

如在MySQL 5.6版本中,使用默认字符集utf8的varchar(5)类,最多可以存放5个数字或5个汉字。

=================================================

VARCHAR类型字符串空格问题

在MySQL 4.1或更老版本中,MySQL会剔除VARCHAR列末尾的空格,而在MySQL 5.0或更高版本中,MySQL在存储和检索时会保留末尾空格。

尾部空格是否截断是在MySQL Server层进行处理,与存储引擎层无关。

=================================================

CHAR类型的空格问题

无论在MySQL 4.1版本之前还是之后,对于CHAR类型字符串,在存储是总会删除所有的末尾空格。

=================================================

存储引擎对字符类型的影响
数据如何存储取决于存储引擎,Memory存储引擎只支持定长列,且Memroy存储引擎不支持BLOB和TEXT类型。
字符串填充和截取空格的行为在MySQL服务器层进行处理,因此对于所有存储引擎都一样。

对于BINARY和VARBINARY类型,在存储时使用字节码来存放,在比较时依次按照每一个字节来对比。
BINARY类型采用\0(零字节)而不是空格来进行填充。

在处理VARCHAR类型数据时,MySQL通常会分配固定大小的内存块来保存内部值,因此对于相同字符串,更长的列会消耗更多的内存,使得在使用内存临时表或磁盘临时表进行排序或操作时消耗更多的资源并且性能低下。

当使用UTF8编码时,每个字符占用3个字节,而MySQL定义行的长度不能超过65535,而且每行还需要至少额外的字节记录该行的信息,因此在UTF8编码下,VARCHAR(N)中的N值最大为(65535-3)/3=21844,当创建表时N超过该最大值,则会将VARCHAR(N)转换成mediumtext类型。

=================================================
限制VARCHAR(N)中N值大小的意义:
对于不同存储引擎,在存放VARCHAR(N)类型数据时采用不同的存储方式,对于Innodb存储引擎,使用额外来1-2byte空间来存放变长列的数据长度,因此数据使用的存储空间与N值无明显关系,N值过大也不会导致数据占用过多的磁盘空间。

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

对于含有1千万数据的表,假设表中有使用UTF8字符集的VARCHAR(1000)列,每个字符占用3字节,如果查询扫描整表进行排序,那么1000000*1000*3字节,就会生成约为30GB的磁盘临时表。

MySQL DataType--字符串类型的更多相关文章

  1. mysql数值字符串类型的按照数值进行排序

    今天遇到一个问题,就是对mysql数值字符串类型进行排序,在默认情况下使用order by 字段名称 desc/asc 进行排序的时候,mysql进行的排序规则是按照ASCII码进行排序的,并不会自动 ...

  2. mysql,字符串类型id,获取最大值

    说明,这个id是字符串类型,但是实际值是一个整数,获取最大值的方法是: select max(cast(id as SIGNED)) from table 另外,mysql生成伪列的方法: SELEC ...

  3. mysql中字符串类型char(n)和varchar(n)的区别

    n的含义 根据网络上找到的结果(不能保证准确),在5.0.3以后版本中,n均代表字符数,而不是字节数:我用来测试的版本是5.7.20,该版本中,n表示字符数. 验证过程如下 建表 CREATE TAB ...

  4. MySql 日期字符串类型互转

    1.data_format 日期转字符串 select date_format(Now(), '%Y-%m-%d %H:%i'); 2.str_to_date 字符串转日期 select str_to ...

  5. 对mysql数据库字符串类型的数字排序

    select * from user where  1=1 order by  salary*1 desc limit 0,5 or select * from user where  1=1 ord ...

  6. Mysql在字符串类型的日期上加上10分钟并和如今的日期做比較

    版权声明:本文为博主原创文章,未经博主同意不得转载. https://blog.csdn.net/ufo2910628/article/details/32092869 SELECT id FROM ...

  7. mysql中的字符串类型数据索引优化

    摘自 "高性能mysql" 对于一些字符串类型较长的字段搜索时, 可以参考如下方法

  8. MySQL字符串类型转换时间类型

    如果MySQL数据库里面的某个时间用的是varchar(或者是char)类型的,这样可以方便系统使用而不用随便转换时间类型来适应数据库版本的不同,当要把取出的字段转换成时间类型的时候,可以按如下方法操 ...

  9. MySQL (二)-- 数据类型(列类型)、数值类型、 小数类型、 时间日期类型、 字符串类型 、 MySQL记录长度、列属性

    1 数据类型(列类型) 所谓的数据类型:对数据进行统一的分类,从系统的角度出发是为了能够使用统一的方式进行管理,更好的利用有限的空间. SQL中将数据类型分成了三大类: 2 数值类型 数值类型数据:都 ...

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

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

随机推荐

  1. Java 面向对象的三大特性之一 继承

    继承: Java是继承的三大特性之一,是Java中实现代码重用的手段之一 将重复的代码抽取到父类中继承的有点或者现实 优点: 方便修改代码 减少代码量 Java中继承的语法: 修饰符 SubClass ...

  2. 如何使用VSTO自动将Excel中的图表复制到Word

    如何使用VSTO自动将Excel中的图表复制到Word 原文地址:https://code.msdn.microsoft.com/How-to-copy-Chart-in-Excel-a29f9029 ...

  3. SQL-10 获取所有非manager的员工emp_no

    题目描述 获取所有非manager的员工emp_noCREATE TABLE `dept_manager` (`dept_no` char(4) NOT NULL,`emp_no` int(11) N ...

  4. bootstrap table 列求和

    <div class="modal fade in" id="_modalDialog" tabindex="1" role=&quo ...

  5. dialog销毁不干净与弹出多个dialog问题

    1.关闭dialog的时候不销毁.重新打开然后影响页面的效果与样式. 原因: dialog的close()只是将html片段隐藏,并没有销毁移除. 解决方式: 打开dialog的时候在写onClose ...

  6. chromium ④

    chromium的源码非常大,选择合适的点入手能省不少力气.在 win7下编译chromium中我曾提到学习chromium源码的一个小工程test_shell,代码目录在src/webkit/too ...

  7. FCC JS基础算法题(8):Slasher Flick(截断数组)

    题目描述: 返回一个数组被截断n个元素后还剩余的元素,截断从索引0开始. 这个题目有两个方法,都比较简单,用slice方法: function slasher(arr, howMany) { // 请 ...

  8. Ubuntu add sudo

    为了安全起见,ubuntu中的普通用户一般没有root权限,因此即使知道管理员密码也无法使用sudo,但这个情况可以通过加入sudoer列表或者加入sudo组来改变. 拓展: 不管使用哪种方式,使得一 ...

  9. 2017-2018-2 20165228 实验四《Android程序设计》实验报告

    一.实验报告封面 课程:Java程序设计 班级:1652班 姓名:苏祚堃 学号:20165228 指导教师:娄嘉鹏 实验日期:2018年5月14日 实验时间:13:45 - 3:25 实验序号:实验四 ...

  10. spacemacs conf

    > da100 src $ cat ~/.spacemacs (defun dotspacemacs/layers () (setq-default dotspacemacs-distribut ...