共计 3259 个字符,预计需要花费 9 分钟才能阅读完成。
咱们都晓得,MySQL 中对于字符,有 char 和 varchar 两种罕用的类型,可能在平时的应用过程中,大家不会去关怀这两种类型的区别,只是会用就能够了,或者说看到过一些它们的区别,然而没有工夫去测试,明天有工夫了,我将这两种类型的具体情况试验一把,让大家直观感触下,纯属分享,大神请绕道。
先说说实践吧。
char 类型为固定长度的字符串,比如说 char(10), 它定义了指定的字符串长度最大为 10 个字符,如果你当初输出一个字符串为 ’12345678’,那么它在 char 类型中到底会占用多少个字符呢?答案是 10 个,前面短少的 2 个字符,MySQL 会主动补充为空值,而后进行寄存。在取这个记录的时候,char 类型的会应用 trim() 函数去掉多余的空格,所以咱们看到的还是 8 个字符的记录。当输出的字符长度大于最大的长度时,MySQL 会主动报错。
varchar 类型是长度可变的字符串,varchar(M) 示意最大长度是 M 个字符,varchar 的最大理论长度由最大的行的大小和应用的字符集确定。例如 varchar(50) 定义了一个最大长度为 50 的字符串,如果插入的字符串只有 20 个字符,那么理论存储的字符串具备 21 个字符,因为 varchar 会主动蕴含一个字符串完结字符。varchar 在值保留和检索时,尾部的空格依然保留。
介绍完概念,咱们来看具体的实际过程,本文中应用的测试版本为 MySQL5.7.22 版本。
1. 测试 char 的 trim() 性能
首先创立一个表,这个表外面蕴含两个字段,d_char 和 d_varchar,设定初始的字符长度都为 4,如下:
查看一下,
此时,咱们插入两条记录,每条记录都是 ’ab ‘,留神,ab 前面有 2 个空格,
而后咱们应用 mysql 外面的 concat 函数进行字符连贯,给每条记录的左右别离增加小括号,
此时咱们能够看到,d_char 的 ab 前面的空格被勾销掉了,而 d_varchar 前面的空格还仍旧存在。
2. 测试两种字符类型的最大长度
首先看看 char 的最大长度,咱们设置的值为 256,后果如下
所以,char 类型的长度取值范畴为 0~255 个字符
下面提到了 varchar 的最大理论长度由最大的行的大小和应用的字符集确定,这里咱们进行试验:
能够看到,字符集不一样,最初的 max 的值也是不一样的,
utf8 模式下是 0~21845,一个字符占三个字节,最多能存 21844 个字符
latin1 模式下是 0~65535,一个字符占一个字节,最多能寄存 65532 个字符
gbk 模式下是 0~32767,一个字符占两个字节,最多能存 32766 个字符
若定义的时候超过上述限度,则 varchar 字段会被强行转为 text 类型,并产生 warning。
可能这里有人要问了,为什么最大值是 32767,而最多只能放 32766 个字符呢?
举两个例阐明一下理论长度的计算。
a) 若一个表只有一个 varchar 类型,如定义为
create table t4(c varchar(N)) charset=gbk;
则此处 N 的最大值为 (65535-1-2)/2= 32766 个字符。
减 1 的起因是理论行存储从第二个字节开始’;
减 2 的起因是 varchar 头部的 2 个字节示意长度;
除 2 的起因是字符编码是 gbk。
b) 若一个表定义为
create table t4(c int, c2 char(30), c3 varchar(N)) charset=utf8;
则此处 N 的最大值为 (65535-1-2-4-30*3)/3=21812
减 1 和减 2 与上例雷同;
减 4 的起因是 int 类型的 c 占 4 个字节;
减 30* 3 的起因是 char(30) 占用 90 个字节,编码是 utf8。
如果被 varchar 超过上述的 b 规定,被强转成 text 类型,则每个字段占用定义长度为 11 字节,当然这曾经不是“varchar”了。
则此处 N 的最大值为 (65535-1-2-4-30*3)/3=21812
3.MySQL 的字段长度模式
字段长度的模式分为严格模式和不严格模式,在严格模式下,如果咱们想给一个字段中插入一个大于规定长度的字符串,MySQL 会给出谬误提醒,例如咱们的表:
当咱们插入一个大于 4 字符的记录时,
如果在非严格模式下,mysql 会主动截断超出最大长度的字符,
下面的操作是,咱们先把字段模式改为非严格模式,而后查问更改,确保更改失效,接着咱们插入 ’abcde’ 字符串,发现它能够被胜利执行,然而蕴含两个正告,查看正告能够发现,一些数据被截断了,
试验局部的内容根本就实现了,这里咱们进行几点剖析:
1.MySQL 为什么要设置这两种类型?它们各自有什么长处?
char 是固定长度的,它的存取速度比 varchar 快,不便程序的存储于查找,然而它须要节约肯定的空间,能够看做是一种以空间换工夫的办法。
而 varchar 的特点是可变长,当定义一个 varchar(10) 而只存入了 4 个字符,此时 varchar 会间接将字符记录的长度变为 4,从而节俭空间,它能够看做是一种用工夫换取空间的办法。
char 的存储形式是,对英文字符(ASCII)占用 1 个字节,对一个汉字占用两个字节;而 varchar 的存储形式是,对每个英文字符占用 2 个字节,汉字也占用 2 个字节,两者的存储数据都非 unicode 的字符数据。
2. 两种类型适应的状况剖析 。
对于 char:
CHAR 适宜存储很短的字符串,或者所有值都靠近同一个长度。
对于常常变更的数据,CHAR 也比 VARCHAR 更好,因为定长的 CHAR 类型不容易产生碎片。
对于十分短的列,CHAR 在存储空间上也更有效率。例如用 char(1) 来存储只有 Y 和 N 的值,只须要一个字节,然而 varchar 却须要两个字节,因为还一个记录长度的额定字节。
对于 varchar
VARCHAR 类型用于存储可变长字符串,是最常见的字符串数据类型。它比定长类型 更节俭空间,因为它仅应用必要的空间(例如,越短的字符串应用越少的空间)。
VARCHAR 节俭了存储空间,所以对性能也有帮忙。然而,因为行是变长的,在 UPDATE 时可能使行变得比原来更长,这就导致须要做额定的工作。如果一个行占用 的空间增长,并且在页内没有更多的空间能够存储,在这种状况下,不同的存储引擎的解决形式是不一样的。例如,MyISAM 会将行拆成不同的片段存储,InnoDB 则须要决裂页来使行能够放进页内。
VARCHAR 须要应用 1 或 2 个额定字节记录字符串的长度:如果列的最大长度小于或等于 255 字节,则只应用 1 个字节示意,否则应用 2 个字节。假如采纳 latinl 字符集,一个 varchar(10)的列须要 11 个字节的存储空间。varchar(1000)的列则须要 1002 个字节,因为须要 2 个字节存储长度信息。
实用状况:
1、对于 MyISAM 表,尽量应用 Char,对于那些常常须要批改而容易造成碎片的 myisam 和 isam 数据表就更是如此,它的毛病就是占用磁盘空间;
2、对于 InnoDB 表,因为它的数据行外部存储格局对固定长度的数据行和可变长度的数据行不加区分(所有数据行共用一个表头局部,这个标头局部寄存着指向各无关数据列的指针),所以应用 char 类型不见得会比应用 varchar 类型好。事实上,因为 char 类型通常要比 varchar 类型占用更多的空间,所以从缩小空间占用量和缩小磁盘 i / o 的角度,应用 varchar 类型反而更无利;
3、存储很短的信息,比方门牌号码 101,201……这样很短的信息应该用 char,因为 varchar 还要占个 byte 用于存储信息长度,原本打算节约存储的当初得失相当。
4、固定长度的。比方应用 uuid 作为主键,那用 char 应该更适合。因为他固定长度,varchar 动静依据长度的个性就隐没了,而且还要占个长度信息。
5、非常频繁扭转的 column。因为 varchar 每次存储都要有额定的计算,失去长度等工作,如果一个十分频繁扭转的,那就要有很多的精力用于计算,而这些对于 char 来说是不须要的。
对于 MySQL 之 char、varchar,你学废了么?