码迷,mamicode.com
首页 > 数据库 > 详细

MySQL数据类型 - 字符串数据类型(2)

时间:2020-12-14 13:12:25      阅读:3      评论:0      收藏:0      [点我收藏+]

标签:tiny   进制   意义   orm   页面   length   引擎   sql   特性   

1.CHAR和VARCHAR类型

CHAR和VARCHAR类型相似,但存储和检索方式不同。它们在最大长度和是否保留尾随空格方面也有所不同。

CHAR和VARCHAR类型的声明长度表示要存储的最大字符数。例如,CHAR(30)最多可以容纳30个字符。

CHAR列的长度固定为创建表时声明的长度。长度可以是0到255之间的任意值。在存储CHAR值时,会用空格从右开始填充到指定的长度。检索CHAR值时,除非启用PAD_CHAR_TO_FULL_LENGTH SQL模式,否则将删除尾随空格。

VARCHAR列中的值是可变长度字符串。长度可以指定为0到65535之间的值。VARCHAR的有效最大长度取决于最大行大小(65535字节,在行的所有列之间共享)和使用的字符集。

与CHAR相比,VARCHAR值存储为1或2字节长度前缀再加上具体数据。长度前缀指示值中的字节数。如果值的字节数不超过255,则列使用一个长度字节前缀;如果值要求的字节数超过255,则列使用两个长度字节。

如果未启用严格 SQL模式,并且为CHAR或VARCHAR列分配的值超过了该列的最大长度,则截断该值以适应列要求,并生成警告。使用严格的SQL模式,对于非空格字符的截断,会导致错误(而不是警告)并禁止插入该值。

对于VARCHAR列,无论使用何种SQL模式,超出列长度的尾部空格在插入之前会被截断,并生成警告。对于CHAR列,不管SQL模式如何,从插入值中截断多余的尾部空格都将以静默方式执行。

存储VARCHAR值时不会填充尾部空格。在存储和检索值时,根据标准SQL保留尾部空格。

下表通过显示将各种字符串值存储到CHAR(4)和VARCHAR(4)列中的结果(假设该列使用单字节字符集,如latin1)来说明CHAR和VARCHAR之间的区别。
技术图片

存储在表最后一行中的值仅在不使用严格SQL模式时才适用;如果启用严格模式,超过列长度的值不会存储,并将导致错误。

InnoDB将长度大于等于768字节的固定长度字段编码为可变长度字段,这些字段可以在页面外存储。例如,如果字符集的最大字节长度大于3(就像utf8mb4一样),CHAR(255)列可以超过768字节。

如果给定值存储在CHAR(4)和VARCHAR(4)列中,则从列中检索的值并不总是相同的,因为检索时会从CHAR列中删除尾随空格。以下示例说明了这种差异:
技术图片

CHAR、VARCHAR和TEXT列中的值根据分配给该列的字符集排序规则进行排序和比较。

MySQL排序规则具有填充属性PAD SPACE,而基于UCA 9.0.0及更高版本的Unicode排序规则具有填充属性NO PAD。

要确定排序规则的填充属性,请使用INFORMATION_SCHEMA COLLATIONS表,此表有PAD_ATTRIBUTE列。

对于非二进制字符串(CHAR、VARCHAR和TEXT值),字符串排序规则填充属性确定在比较字符串尾部空格时的处理方式。NO PAD排序规则像对待任何其他字符一样,将尾部空格视为比较中的重要内容。PAD SPACE排序规则在比较中将尾部空格视为无关紧要;字符串的比较不考虑尾部空格。服务器SQL模式对尾部空格的比较行为没有影响。

对于删除尾部填充字符或比较时忽略它们的情况,如果列具有需要唯一值的索引,则向列中插入仅尾部填充字符数不同的值将导致重复键错误。例如,如果表包含‘a‘,则尝试存储‘a ‘会导致重复键错误。

2.BINARY和VARBINARY类型

BINARY和VARBINARY类型与CHAR和VARCHAR类似,只是它们存储的是二进制字符串而不是非二进制字符串。也就是说,它们存储字节字符串而不是字符字符串。这意味着它们具有二进制字符集和排序规则,并且比较和排序基于字节的数值。

对于BINARY和VARBINARY,允许的最大长度与CHAR和VARCHAR相同,只是BINARY和VARBINARY的长度是以字节而不是字符度量的。

BINARY和VARBINARY数据类型不同于CHAR BINARY和VARCHAR BINARY数据类型。对于后一种类型,BINARY属性不会将列视为二进制字符串列。相反,它将给列字符集(如果未指定列字符集,则使用表默认字符集)使用二进制(_bin)排序规则,并且列本身存储非二进制字符串,而不是二进制字节字符串。例如,如果默认字符集是utf8mb4,则CHAR(5) BINARY被视为CHAR(5) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin。这与BINARY(5)不同,后者存储5字节二进制字符串,使用二进制字符集和排序规则。

如果未启用严格 SQL模式,并且为列BINARY或VARBINARY分配超过列最大长度的值,则该值将被截断以适应列长度限制,并生成警告。对于截断情况,若要导致发生错误(而不是警告)并禁止插入值,请启用严格SQL模式。

当存储BINARY值时,它们用填充值从右侧开始填充到指定的长度。填充值为0x00(0字节)。值用0x00右填充以进行插入,并且检索时不删除尾随字节。所有字节在比较中都是重要的,包括ORDER BY和DISTINCT操作。在比较时0x00和空格是不同的,排序时0x00在空格之前。

示例:对于BINARY(3)列,插入时‘a ‘变为‘a \0‘,‘a\0‘变为‘a\0\0‘。两个插入的值在检索时保持不变。

对于VARBINARY,插入时没有填充,检索时也不会剥离字节。所有字节在比较中都是重要的,包括ORDER BY和DISTINCT操作。0x00和空格在比较时是有区别的,0x00的排序在空格之前。

对于比较时需要删除尾部填充字节或忽略它们的情况,如果列需要唯一值的索引,则将仅在尾部填充字节数量不同的值插入列将导致重复的键错误。例如,如果表包含‘a‘,则尝试存储‘a\0‘会导致重复键错误。

如果计划使用BINARY数据类型存储二进制数,并且要求检索的值与存储的值完全相同,则应仔细考虑前面提到的填充和剥离特性。以下示例说明BINARY值的0x00填充如何影响列值比较:

技术图片

如果检索到的值必须与不带填充的存储值相同,则最好使用VARBINARY或某个BLOB数据类型。

3.BLOB和TEXT类型

BLOB是一个二进制大对象,可以保存可变数量的数据。四种BLOB类型是TINYBLOB、BLOB、MEDIUMBLOB和LONGBLOB。这些类型的唯一区别就是值的最大长度不同。四种TEXT类型是TINYTEXT、TEXT、MEDIUMTEXT和LONGTEXT。它们对应于四种BLOB类型,并与它们具有相同的最大长度和存储要求。

BLOB值被视为二进制字符串(字节字符串)。它们有二进制字符集和排序规则,比较和排序都基于字节中的数值。TEXT值被视为非二进制字符串(字符字符串)。它们的字符集不是二进制字符集,并且根据字符集的排序规则对值进行排序和比较。

如果未启用严格SQL模式,并且为BLOB或TEXT列分配一个超出该列最大长度的值,则该值将被截断以满足列要求,并生成警告。使用严格SQL模式,对于非空格字符的截断,会引发错误(而不是警告)并禁止插入该值。

不管何种SQL模式,从要插入到TEXT列的值中截断多余的尾部空格始终会生成警告。

对于TEXT和BLOB列,在插入值时不会填充任何内容,在查询时也不会剥离任何内容。

如果TEXT列已建立索引,比较的索引项在结尾处填充了空格。这意味着,如果索引要求唯一的值,则只有尾部空格数不同的值将出现重复键错误。例如,如果表包含‘a‘,则尝试存储‘a ‘会导致重复键错误。BLOB列不存在这种情况。

在大多数情况下,您可以将BLOB列视为VARBINARY列,该列可以根据您的需要无限大。类似地,可以将TEXT列视为VARCHAR列。BLOB和TEXT与VARBINARY和VARCHAR有以下区别:

●对于BLOB和TEXT列上的索引,必须指定索引前缀长度。对于CHAR和VARCHAR,前缀长度是可选的。

●BLOB列和TEXT列不能有DEFAULT值。

如果对TEXT数据类型使用BINARY属性,则会为列指定列字符集的二进制(_bin)排序规则。

LONG和LONG VARCHAR映射到MEDIUMTEXT数据类型。这是一个兼容性功能。

MySQL Connector/ODBC将BLOB值定义为LONGVARBINARY,将TEXT值定义为LONGVARCHAR。

由于BLOB和TEXT值可能非常长,因此在使用它们时可能会遇到一些限制:

●排序时只使用列的第一个max_sort_length字节。max_sort_length的默认值是1024。通过在服务器启动或运行时增加max_sort_length的值,可以使更多字节在排序或分组中具有重要意义。任意客户端都可以更改其会话的max_sort_length变量的值:

技术图片

●使用临时表处理的查询结果中的BLOB或TEXT列实例会导致服务器使用磁盘上的表,而不是内存中的表,因为MEMORY存储引擎不支持这些数据类型。使用磁盘会导致性能损失,因此请只有在确实需要时才在查询结果中包含BLOB列或TEXT列。例如,避免使用SELECT *,它将选择所有列。

●BLOB或TEXT对象的最大大小由其类型决定,但实际可以在客户端和服务器之间传输的最大值由可用内存量和通信缓冲区大小决定。您可以通过更改max_allowed_packet变量的值来更改消息缓冲区大小,但需要对于服务器和客户端程序都必须这样做。例如,mysql和mysqldump都允许您更改客户端的max_allowed_packet值。

每个BLOB或TEXT值在内部由单独分配的对象表示。这与所有其他数据类型不同,它们在打开表时为每列分配一次存储空间。

在某些情况下,可能需要在BLOB或TEXT列中存储二进制数据,例如媒体文件。您可能会发现MySQL的字符串处理函数对于处理此类数据非常有用。出于安全和其他原因,通常最好使用应用程序代码,而不是授予应用程序用户FILE权限。

英文文档:
https://dev.mysql.com/doc/refman/8.0/en/char.html

MySQL数据类型 - 字符串数据类型(2)

标签:tiny   进制   意义   orm   页面   length   引擎   sql   特性   

原文地址:https://blog.51cto.com/15023289/2561173

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!