字符类型包括:

CHAR 与 VARCHAR

CHAR(m) m 取值范围 0~255。列宽固定,存储时字符串右边会补空格,取出时自动去掉空格,除非开启了 PAD_CHAR_TO_FULL_LENGTH

对于值未超出的情况,VARCHAR 在存储及查询时皆会完整保留末尾的空格字符。

VARCHAR(m) m 取值范围 0~65535,不定长度,根据存储的值而定,但上限为 m。存储时,会在值的前面预留一到两位用来存储字符串长度。0~255时预留一位,超过的情况使用两位来标识所存储的字符串的长度

在非严格模式下,超过的非空格值会自动截断来存储,同时生成警告信息。建议开启严格模式以避免这种不完整数据的产生。

对于超出的空格值,VARCHAR 会在插入钱截断并产生警告信息,而对于 CHAR 则没有警告信息,直接静默截断存储。

以下表格以 m为4的情况展示了 非严格模式下 CHAR,VARCHAR 在存储不同长度字符串时的表现。

Value CHAR(4) Storage Required VARCHAR(4) Storage Required
'' '    ' 4 bytes '' 1 byte
'ab' 'ab  ' 4 bytes 'ab' 3 bytes
'abcd' 'abcd' 4 bytes 'abcd' 5 bytes
'abcdefgh' 'abcd' 4 bytes 'abcd' 5 byte

以下代码展示了两者在查询时对于末尾空格的处理情况。

mysql> CREATE TABLE vc (v VARCHAR(4), c CHAR(4));
Query OK, 0 rows affected (0.01 sec) mysql> INSERT INTO vc VALUES ('ab ', 'ab ');

Query OK, 1 row affected (0.00 sec) mysql> SELECT CONCAT('(', v, ')'), CONCAT('(', c, ')') FROM vc;

+---------------------+---------------------+

| CONCAT('(', v, ')') | CONCAT('(', c, ')') |

+---------------------+---------------------+

| (ab ) | (ab) |

+---------------------+---------------------+

1 row in set (0.06 sec)

在进行排序和字符串比较时,具体表现和使用的字符集(character set collation )有关。

Pad 属性

Pad 即字符串长度不够时的补齐操作,一般是添加空格。大部分字符集都有一个 PAD SPACE 的补齐属性(pad attribute)。基于 UCA 9.0.0 的 Unicode 字符集其补齐属性为 NO PAD

可通过查询 INFORMATION_SCHEMA COLLATIONS 表中的 PAD_ATTRIBUTE 列获取到和字符集的补齐属性。

补齐属性直接影响非二进制字符串(CHAR, VARCHAR, and TEXT)进行比较时的末尾的空白会如何处理。

对于 NO PAD 字符集,末尾的空白会参与字符串比较,PAD SPACE 末尾的空白则不影响比较结果,但在使用 LIKE 关键字时空白是会参与进来的。

mysql> CREATE TABLE names (myname CHAR(10));
Query OK, 0 rows affected (0.03 sec) mysql> INSERT INTO names VALUES ('Monty');

Query OK, 1 row affected (0.00 sec) mysql> SELECT myname = 'Monty', myname = 'Monty ' FROM names;

+------------------+--------------------+

| myname = 'Monty' | myname = 'Monty ' |

+------------------+--------------------+

| 1 | 1 |

+------------------+--------------------+

1 row in set (0.00 sec) mysql> SELECT myname LIKE 'Monty', myname LIKE 'Monty ' FROM names;

+---------------------+-----------------------+

| myname LIKE 'Monty' | myname LIKE 'Monty ' |

+---------------------+-----------------------+

| 1 | 0 |

+---------------------+-----------------------+

1 row in set (0.00 sec)

对于要求列值要求在记录中唯一(unique values)的表格,在插入时需要格外注意,如果插入的值只包含空格的区别,在空格不影响比较结果的字符集中会报 duplicate-key error。比如已经有记录的值为 a 尝试插入 a 时会报错。

BINARY 与 VARBINARY

基本与 CHAR 和 VARCHAR 类似,不同点在于存储的是二进制字符值。存储长度的取值范围也一样,只是单位是字节而不是字符。

写入时对于超出限制的值,会自动截断,除非开启 MySQL 的严格模式,此时会报错而非截断后成功写入。

对于 BINARY 类型,存入的值长度不够时会自动补上二进制中的零 0x00。查询时也会返回补零后的值。在进行比较操作时,所有字节都参与计算,注意二进制的零值 0x00 与空格是不同的值,0x00 < 空格。

以下代码展示了自动补零在存取时的表现,

mysql> CREATE TABLE t (c BINARY(3));
Query OK, 0 rows affected (0.01 sec) mysql> INSERT INTO t SET c = 'a';

Query OK, 1 row affected (0.01 sec) mysql> SELECT HEX(c), c = 'a', c = 'a\0\0' from t;

+--------+---------+-------------+

| HEX(c) | c = 'a' | c = 'a\0\0' |

+--------+---------+-------------+

| 610000 | 0 | 1 |

+--------+---------+-------------+

1 row in set (0.09 sec)

所以如果你期望查询时得到与存储时一致的值,最好使用 VARBINARYBLOB 类型。

BLOB 与 TEXT 类型

BLOB (binary large object) 即大型二进制形式的对象,用于数据量大的情况。BLOB 大类中具体包含:TINYBLOB, BLOB, MEDIUMBLOB 以及 LONGBLOB 四种数据类型,他们只存在存储上限的区别。

文本类型 TEXT 下面同样包含不同上限的具体类型:TINYTEXT, TEXT, MEDIUMTEXT 及 LONGTEXT 。这四种类型功能及上限与 BLOB 中的四种类型一一对应,只是该类型用于字符而非二进制值。

BLOB 类型内部处理时以二进制字符串的形式处理,在进行比较操作或排序时,按其表示的二进制数字来进行。而 TEXT 类型表示非二进制字符,在进行比较或排序时与字符集有关。

非严格模式下写入一个超出长度的值时,会自动截断后存入,同时生成警告信息,这一行为可通过开启严格模式来避免。

其中对于 TEXT 类型,截取末尾的空格字符时始终生成警告信息,与 MySQL 当前设置的模式无关。

一般来说你可把 BLOB 看作是 VARBLOB,存储任意大的数据。TEXT 同理,可看成 VARCHAR。但还是有一些区别的:

  • 建立索引时 BLOB 和 TEXT 需要指定长度(index prefix length),而 CHAR 和 VARCHAR 不需要。
  • BLOB 和 TEXT 类型没有默认值,不能设置 DEFAULT 属性。

因为 BLOB 和 TEXT 所存的值有可能很大,实际使用时会遇到些限制,比如

  • 排序时只取 max_sort_length 的长度。该值默认为 1024,但可随时配置:
mysql> SET max_sort_length = 2000;
mysql> SELECT id, comment FROM t
-> ORDER BY comment;
  • 查询 BLOB 和 TEXT 类型时其结果会处理到一个临时表中,而不是像其他类型一样放到内存里,因为内存中是不支持这两种类型的(关于原因详见 Section 8.4.4, “Internal Temporary Table Use in MySQL)。这里临时表的操作涉及到额外的文件 I/O,在查询时会影响性能,所以应该尽量避免这样的操作。
  • 尽管 BLOB 和 TEXT 允许存储的值很大,实际使用时,其上限受内存及传输 buffer 大小的影响。

ENUM 类型

枚举值类型通过在创建表时指定该类型可接受的合法值列表,相比一般的字符类型有以下优势:

  • 节省存储空间,枚举值实际存储时会转成数字。
  • 语义化。相比 直接使用数字类型,枚举类型在查询时会返回其对应的字符串。

枚举的创建与使用

枚举中的项通过单引号指定,以下是一个创建和使用枚举类型的示例:

CREATE TABLE shirts (
name VARCHAR(40),
size ENUM('x-small', 'small', 'medium', 'large', 'x-large')
);
INSERT INTO shirts (name, size) VALUES ('dress shirt','large'), ('t-shirt','medium'),
('polo shirt','small');
SELECT name, size FROM shirts WHERE size = 'medium';
+---------+--------+
| name | size |
+---------+--------+
| t-shirt | medium |
+---------+--------+
UPDATE shirts SET size = 'small' WHERE size = 'large';
COMMIT;

不支持在创建时使用表达式,比如下面这样是不行的:

# 												

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

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

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

  2. mysql中比较字符串类型数字

    操作的表: p.p1 { margin: 0; font: 16px Menlo; color: rgba(0, 0, 0, 1) } span.s1 { font-variant-ligatures ...

  3. Mysql中对字符串类型的字段进行数字值排序

    排序字段+0或者*1,类似  Java 把 其他类型转换成字符串 比如 +“”: 一.对普通数字字符串字段排序 -- 方式一 SELECT * FROM xxxxxx WHERE STATUS ' O ...

  4. [转]mysql中的字符串的拼接

    字符串的拼接 1,Mysql 在Java.C#等编程语言中字符串的拼接可以通过加号“+”来实现,比如:"1"+"3"."a"+"b ...

  5. Oracle和Mysql中的字符串的拼接

    SQL允许两个或者多个字段之间进行计算,字符串类型的字段也不例外.比如我们需要 以"工号+姓名"的方式在报表中显示一个员工的信息,那么就需要把工号和姓名两个字符 串类型的字段拼接计 ...

  6. java中,字符串类型的时间数据怎样转换成date类型。

    将字符串类型的时间转换成date类型可以使用SimpleDateFormat来转换,具体方法如下:1.定义一个字符串类型的时间:2.创建一个SimpleDateFormat对象并设置格式:3.最后使用 ...

  7. Mysql中的一些类型

    列类型--整数类型Tinyint:迷你整形 一个字节=8位 最大能表示的数值是0-255 实际区间 -128~127Smallint:小整形 两个字节 能表示0-65535Mediumint:中整型 ...

  8. 解析MySQL中存储时间日期类型的选择问题

    解析MySQL中存储时间日期类型的选择问题_Mysql_脚本之家 https://www.jb51.net/article/125715.htm 一般应用中,我们用timestamp,datetime ...

  9. 关于MySql中的varchar类型

    今天新开始的项目在做数据库设计,发现自己对MySql的varchar类型还不熟悉,故又上网收集资料整理如下. 1.varchar类型的变化 MySQL 数据库的varchar类型在4.1以下的版本中的 ...

随机推荐

  1. 多个线程运行MR程序时hadoop出现的问题

    夜间多个任务同时并行,总有几个随机性有任务失败,查看日志: cat -n ads_channel.log |grep "Caused by" Caused by: java.uti ...

  2. [python / selenium] - 用python刷公选课是一种什么体验?

    前言 看公选课还是能学到很多知识的,这里是给大家提供一个selenium的使用思路(好好学公选课,我真的看了) 思路 当观看者移动鼠标到某一范围时就会停止播放,就让selenium一直将鼠标悬停在视频 ...

  3. new String()与toString

    str.toString是调用了str这个object对象的类的toString方法.一般是返回这么一个String:[class name]@[hashCode].new String(str)是根 ...

  4. 【朝花夕拾】Android自定义View篇之(七)Android事件分发机制(下)滑动冲突解决方案总结

    前言 转载请声明,转自[https://www.cnblogs.com/andy-songwei/p/11072989.html],谢谢! 前面两篇文章,花了很大篇幅讲解了Android的事件分发机制 ...

  5. 每日一题LeetCode 8. 字符串转换整数 (atoi)

    问题描述 请你来实现一个 atoi 函数,使其能将字符串转换成整数. 首先,该函数会根据需要丢弃无用的开头空格字符,直到寻找到第一个非空格的字符为止. 当我们寻找到的第一个非空字符为正或者负号时,则将 ...

  6. ActiveMQ学习总结------Spring整合ActiveMQ 04

    通过前几篇的学习,相信大家已经对我们的ActiveMQ的原生操作已经有了个深刻的概念, 那么这篇文章就来带领大家一步一步学习下ActiveMQ结合Spring的实战操作 注:本文将省略一部分与Acti ...

  7. 缓存AJAX的请求

      在客户端缓存Ajax请求 浏览器可以缓存图片.js文件.css文件,同样浏览器也可以缓存XML Http调用(当然这需要XML Http以get方式发送调用),这种缓存基于URL,当我们发送一个请 ...

  8. Oracle 事务ACID的特性

    1.事务对数据库控制操作 事务(Transaction)是用户定义的一个数据库操作序列,是不可分割的一部分的整体.这些操作要么做,要么不做(原子性).事务是对数据库对进行操作的最基本的逻辑单位,他可以 ...

  9. C#中获取指定路径下特定开头和后缀的所有文件

    场景 指定一个文件路径,获取当前路径下所有文件,并筛选出以指定内容开头和结尾的文件. 注: 博客主页: https://blog.csdn.net/badao_liumang_qizhi 关注公众号 ...

  10. 详解Condition的await和signal等待/通知机制

    本人免费整理了Java高级资料,涵盖了Java.Redis.MongoDB.MySQL.Zookeeper.Spring Cloud.Dubbo高并发分布式等教程,一共30G,需要自己领取.传送门:h ...