MySQL学习分享-->字符类型

字符类型

首先我们会讲到字符集的概念,字符集是指一些字符的集合,而字符编码是指一个字符的编码格式,因此两者的关系可以这样描述,例如:“使用Unicode编码的字符集”,意思就是该字符集中的所有字符都是使用Unicode进行编码的。

接着说一下Unicode,它是一种字符编码,不是字符集,它为每种语言的每个字符设定了统一且唯一的二进制编码。在MySQL5.5及以上版本中支持ucs2、utf8、utf8mb4、utf16、utf32五种Unicode编码的字符集,而在MySQL5.5版本之前,仅支持ucs2和utf8两种Unicode编码的字符集。

MySQL可以为每个列单独指定字符集。我们在创建表时若没有给列单独指定字符集,那么会默认采用创建表时指定的字符集;若创建表时没有指定字符集,那么会默认采用创建库时指定的字符集;若创建库时也没有指定字符集,那么会默认采用MySQL配置文件中指定的字符集。目前MySQL5.5版本配置文件中默认的字符集是latin1。

接下来我们要说一说排序规则,它是指对字符集中不同字符的比较规则。它的命名规则以_ci结尾表示对大小写不敏感,以_cs结尾表示对大小写敏感,以_bin结尾表示二进制的比较。可以对列单独指定排序规则。排序规则不仅影响大小写的比较问题还会影响索引。

char和varchar

两者在声明时都可以指定能存储的字符数,char(N)、varchar(N),这里的N是指字符数而不是字节数,例如将N设置为4,则可以存储4个中文或字母或数字。两者的主要区别是char列的长度固定为创建表时声明的长度,而varchar列的长度则是可变长的。

char(N)长度的列最多可占用的字节数,为该字符集单字符最大占用字节数*N。

上图验证了前面说到的char(N)、varchar(N)的N是指字符数而不是字节数。由于这张表是utf8编码格式的表,这种编码格式下一个中文字符是占用3个字节的,如果N是指代字节,则很明显“测试数据”这四个字符是无法插入的,因为它们需要12个字节才能存储。

另外在插入数据时若插入的字符串尾部包含空格,char会删除掉尾部的这些空格而varchar会保留尾部的这些空格。详见上图,可以看到char对于头部和中间的空格是不做处理的。

为什么char会删除掉尾部空格呢?

这是因为在指定了能存储的字符数后,若插入的数据字符数未达到指定能存储的字符数,则会对这些数据进行右空格填充(也可以理解为进行尾部空格填充),使其长度达到指定能存储的字符数。举个例子,例如插入“测试 ”这个字符串,其长度为3个字符未达到上面定义的4个字符存储长度,MySQL会删除原数据的尾部空格,因为MySQL本身就要进行右空格填充操作,而这个原数据尾部却带有空格,明显会造成冲突。

有人会说,那MySQL只需要填充还缺少的空格数就行了啊。不,MySQL并不会对数据尾部你带几个空格,我需要填充几个空格这种行为做记录,因为没必要设计的这么复杂,因此直接将原数据尾部的空格都干掉,然后看距离达到指定存储的字符还差几个空格,再进行相应数量的右空格填充即可。

在对char列的数据进行检索时,MySQL会自动删除掉原先填充的右空格。这个行为也是可以理解的,因为如果不把自动填充的右空格删除,你所想检索的数据和实际存储的数据根本就不匹配,会导致无法检索出数据的情况。

鉴于此如果我们需要存储的数据尾部本身就带有空格,那么建议使用varchar类型。

附MySQL官方手册对这一块儿的说明:

“The length of a CHAR column is fixed to the length that you declare when you create the table. The length can be any value from 0 to 255. When CHAR values are stored, they are right-padded with spaces to the specified length. When CHAR values are retrieved, trailing spaces are removed unless the PAD_CHAR_TO_FULL_LENGTH SQL mode is enabled. ”

大意为:

“CHAR列的长度固定为创建表时声明的长度。 其长度可以是0到255之间的任意值。当存储CHAR类型的值时,MySQL会用指定长度的空格进行右填充。当检索CHAR类型值时,除非启用 PAD_CHAR_TO_FULL_LENGTH 的SQL模式,否则将会删除掉尾部空格。”

varchar最多能存储多少个字符?

这个问题千万不要想当然,不然结果会出乎你意料。

虽然我们在定义varchar时能够指定其能存储多少字符,但实际varchar能存储的字符数量是受限于其能存储的字节数的,这个限制字节数为65535,就是说被定义为varchar类型的列,最多能存储65535个字节。

这里详细说明下:

①如果是非空的varchar,则实际最多能存储65533个字节,因为还有两个字节是用来标记列长度的(当存储的数据大于255个字节,就需要用2个字节来标记列长度,若小于255个字节,则需要用1个字节来标记列长度);

②如果是可为空的varchar则实际最多能存储65532个字节,因为还需要一个字节用来标记是否为空。

最多能存储字符数的计算:

在utf8编码格式下,将varchar定义为非空,再利用公式:(65535-2)/3=21844余1,就能得到其最多能存储的字符数为21844个。若需要存储的字符串超过了这个部分,则应该根据实际情况来选择用tinytext、mediumtext、text或longtext作为该列的数据类型。

binary和varbinary

两者是用来存储二进制的字符串的。它们与char和varchar的区别如下:

①binary(N)和varbinary(N)中N代表字节而不是字符;

②binary和varbinary的值排序和比较都是按照二进制值来进行的;

③binary的填充字符是0x00,char的填充字符是0x20;

blob和text

两者和varbinary和varchar的区别主要为:

①在blob和text列上创建索引时,必须制定索引的前缀长度;

②blob和text列没有默认值;

③在排序时只使用列的前max_sort_length个字节;

时间: 2024-08-07 04:45:29

MySQL学习分享-->字符类型的相关文章

跟王老师学MySQL:MySQL数据类型之字符类型

跟王老师学MySQL:MySQL数据类型之字符类型 主讲教师:王少华   QQ群号:483773664 学习内容: 字符串类型的种类及其特点 char和varchar的异同 字符串类型是在数据库中存储字符串的数据类型. 字符串类型包括 CHAR. VARCHAR BLOB TEXT 一.char和varchar (一)定义语法 1 字符串类型 (M) 注: 字符串类型:char或varchar M:指定了该字符串最大长度 (二)二者不同之处 char类型长度是固定的,即在创建表时就指定了,其长度

MySql学习之 bit类型的查询和删除

今天项目从SqlServer转移到了MySql,转移过程中发现了一些问题,以前没遇到过,在网上查了查,总算是解决了,但是问题的根源还弄明白,暂且记录下来: 首先有个tb_paymentmethod表,表中有几条数据如下: DAO层获取Model时这样: if (row["IsDefault"] != null && row["IsDefault"].ToString().Trim() != "") { model.IsDefaul

MySQL学习分享-->日期时间类型

日期时间类型 ①如果要用来表示年月日时分秒,一般使用datetime类型: ②如果要用来表示年月日,一般使用date类型: ③如果要表示时分秒,一般使用time类型: ④如果只是表示年份,一般使用year类型,需要注意的是5.5.27版本之前(不包含该版本)year类型有2位和4位格式这两种表示,在5.5.27版本之后2位格式的year已经不再被支持,year类型的值都会以YYYY的格式显示. year(2)被弃用我个人的理解是因为两位的显示宽度使得该类型表示模糊.不明确(显示的值仅仅是最后两位

Mysql 支持的字符类型

MySQL中定义数据字段的类型对你数据库的优化是非常重要的.尤其和oracle某些不一致. 比如没有number类型,特此总结下来方便以后查询 MySQL支持多种类型,大致可以分为三类:数值.日期/时间和字符串(字符)类型. 数值类型 MySQL支持所有标准SQL数值数据类型. 这些类型包括严格数值数据类型(INTEGER.SMALLINT.DECIMAL和NUMERIC),以及近似数值数据类型(FLOAT.REAL和DOUBLE PRECISION). 关键字INT是INTEGER的同义词,关

MySQL学习----各种字符的长度总结

数字型 类型 大小 范围(有符号) 范围(无符号) 用途 TINYINT 1 字节 (-128,127) (0,255) 小整数值 SMALLINT 2 字节 (-32 768,32 767) (0,65 535) 大整数值 MEDIUMINT 3 字节 (-8 388 608,8 388 607) (0,16 777 215) 大整数值 INT或INTEGER 4 字节 (-2 147 483 648,2 147 483 647) (0,4 294 967 295) 大整数值 BIGINT 8

MySQL学习分享-->查询-->查询的分类

MySQL的查询可以分为交叉联接.内联接.外联接.自然联接.straight_join 下面对于查询的学习,会用到以下四张表: create table t_commodity_type( `id` BIGINT(20) not null auto_increment comment '商品类别ID', `time` TIMESTAMP not null DEFAULT CURRENT_TIMESTAMP comment '入库时间', `name` VARCHAR(32) not null D

mysql 数值与字符类型 长度梳理

上述表格中的数值类型都是定长的,也就是说,无论你存的数值是多少,多大或者多小,占用的存储字节大小都是固定的.例如,之前设置的int(1),虽然M值是1个字符,但是它所占用的空间大小永远都是4个字节的大小,换句话说就是,你可以存入有符号整型从-2 147 483 648到2 147 483 647包括这两个数的中间任何一个数.int(1)和int(11)占用的是4个字节,可以存入上述这些数,tinyint(1)和tinyint(4)占用的是1个字节,可以存入从-128到127的数. 那么,这个我们

MySQL学习分享-->查询-->子查询

子查询是指在查询语句中嵌套另一个查询语句. 子查询外面的查询部分被称为外部查询. 子查询必须包含括号. any.in.some any关键字必须与一个比较操作符一起使用,它的意思是"与子查询中返回列的数值进行逐一对比,只要其中一个数值比较为true,则返回true",我们来看一个查询实例, select id_temp from t_user_collect where commodity_id > any (select id from t_commodity); 得到如下结果

MySQL学习分享-->查询-->查询的原理

查询的原理 在一个查询中常包含下述子句: 1.select,2.distinct,3.join,4.on,5.from,6.where,7.having,8.group by,9.order by,10.limit 在查询执行过程中,每个子句按照一定的顺序被执行,每个子句被执行时都会产生一张虚拟表,只有最后一步生成的虚拟表才会返回给用户. 我们用实际的例子来讲解下查询的执行过程,先准备以下两张表: create table t_student( id bigint(20) not null au