细说varchar与char有哪些区别?

时间:2024-10-29 10:57:55 阅读:8

细说varchar与char有哪些区别?

版权声明:本文为CSDN博主「_陈哈哈」的原创文章

原文链接:
https://blog.csdn.net/qq_39390545/article/details/109379218

一、CHAR和VARCHAR有哪些区别

1、安稳长度 & 可变长度

  • VARCHAR

??VARCHAR典范用于存储可变长度字符串,是最稀有的字符串数据典范。它比安稳长度典范更节流空间,由于它仅使用必要的空间(依据实践字符串的长度改动存储空间)。

有一种情况例外,假如MySQL表使用ROW_FORMAT=FIXED创建的话,每一行都市使用定长存储。

  • CHAR

??CHAR典范用于存储安稳长度字符串:MySQL总是依据界说的字符串长度分派充足的空间。当存储CHAR值时,MySQL会删除字符串中的末了空格(在MySQL 4.1和更老版本中VARCHAR 也是如此完成的——也就是说这些版本中CHAR和VARCHAR在逻辑上是一样的,区别只是在存储格式上)。

同时,CHAR值会依据必要接纳空格举行剩余空间添补,以便利比力和检索。但正由于其长度安稳,以是会占据多余的空间,也是一种空间换时间的战略;

2、存储办法

  • VARCHAR

VARCHAR必要使用1或2个分外字节纪录字符串的长度:假如列的最大长度小于或即是255字节,则只使用1个字节表现,不然使用2个字节。假定接纳latinl字符集,一个VARCHAR(10)的列必要11个字节的存储空间。VARCHAR(1000)的列则必要1002 个字节,由于必要2个字节存储长度信息。

??VARCHAR节流了存储空间,以是对功能也有协助。但是,由于行是变长的,在UPDATE时约莫使行变得比原本更长,这就招致必要做分外的事情。假如一个行占用的空间增长,并且在页内没有更多的空间可以存储,在这种情况下,不同的存储引擎的处理办法是不一样的。比如,MylSAM会将行拆成不同的片断存储,InnoDB则必要崩溃页来使行可以放进页内。

  • CHAR

??CHAR合适存储很短或长度近似的字符串。比如,CHAR十分合适存储暗码的MD5值,由于这是一个定长的值。关于常常变动的数据,CHAR也比VARCHAR更好,由于定长的CHAR典范不容易产生碎片。关于十分短的列,CHAR比VARCHAR在存储空间上也更有听从。比如用CHAR(1)来存储仅有Y和N的值,假如接纳单字节字符集只必要一个字节,但是VARCHAR(1)却必要两个字节,由于另有一个纪录长度的分外字节。

3、存储容量

CHAR

??关于char典范来说,最多只能存放的字符个数为255,和编码不关,任何编码最大容量都是255。

  • VARCHAR

??MySQL默许最大65535字节,是一切列共享(相加)的,以是VARCHAR的最大值受此限定。

表中仅有单列字段情况下,varchar寻常最多能存放(65535 - 3)个字节,varchar的最大好效长度经过最大行数据长度使用的字符集来确定,通常的最大长度是65532个字符(当字符串中的字符都只占1个字节时,能到达65532个字符)

为什么是65532个字符?算法如下(剩余数时向下取整):

最大长度(字符数) = (行存储最大字节数 - NULL标识列占用字节数 - 长度标识字节数) / 字符集单字符最大字节数

  • NULL标识列占用字节数:允许NULL时,占一字节
  • 长度标识字节数:纪录长度的标识,长度小于即是255(28)时,占1字节;小于65535时(216),占2字节

VARCHAR典范在4.1和5.0版本产生了很大的厘革,使得情况愈加繁复。从MySQL 4.1开头,每个字符串列可以界说本人的字符集和排序端正。这些东西会很大水平上影响功能。

  • 4.0版本及以下,MySQL中varchar长度是按字节展现,如varchar(20),指的是20字节
  • 5.0版本及以上,MySQL中varchar长度是按字符展现。如varchar(20),指的是20字符

固然,总长度照旧65535字节,而字符和字节的换算,则与编码办法有关,不同的字符所占的字节是不同的。编码区分如下:

  • GBK编码:
    一个英笔墨符占一个字节,中文2个字节,单字符最大可占用2个字节。
  • UTF-8编码:
    一个英笔墨符占一个字节,中文3个字节,单字符最大可占用3个字节。
  • utf8mb4编码:
    一个英笔墨符占一个字节,中文3个字节,单字符最大占4个字节(如emoji心情4字节)。

假定如今另有6字节可以存放字符,按单字符占用最大字节数来算,可以存放3个GBK、或2个utf8、或1个utf8mb4。

思索:既然VARCHAR长度可变,那我要不要定到最大?

??没错,信赖你以前有答案了,别这么干!

??就像使用VARCHAR(5)和VARCHAR(200)存储 '陈哈哈’的磁盘空间开支是一样的。那么使用更短的列有什么上风呢?

??内幕证实有很大的上风。更长的列会斲丧更多的内存,由于MySQL通常会分派安稳轻重的内存块来保存内里值。

??固然,在没拿到存储引擎存储的数据之前,并不会晓得我这一行拿出来的数据毕竟有多长,约莫长度仅有1,约莫长度是500,那怎样办呢?那就只能先把最大空间分派好了,制止放不下的成绩产生,如此实践上关于真实数据较短的varchar的确会形成空间的糜费。

??举例:我向数据典范为:varchar(1000)的列插进了1024行数据,但是每个只存一个字符,那么这1024行真实数据量但是仅有1K,但是我却必要约1M的内存去顺应他。以是最好的战略是只分派真正必要的空间。

二、CHAR和VARCHAR在SQL中必要注意的点

??底下经过一个具体的示例来分析CHAR和VARCHAR典范存储时的区别。我们创建一张同时存在CHAR(10)字段、VARCHAR(10)字段的表,并且往内里插进一些值来做比力验证:

-- 建表语句 CREATE TABLE `str_table` ( `id` int(11) NOT NULL AUTO_INCREMENT, `str_char` char(10) DEFAULT NULL, `str_varchar` varchar(10) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8mb4;

分散插进一些字符串前方和后方都有空格的示例

-- 插进测试数据 INSERT INTO `str_table` (`id`, `str_char`, `str_varchar`) VALUES (null, '陈哈哈', '陈哈哈'), (null, ' 陈哈哈', ' 陈哈哈'), (null, '陈哈哈 ', '陈哈哈 ');

测试数据查询语句如下,经过拼接能更好的看出比力后果:

-- 测试数据查询 select id,concat("|",str_char,"|") as `char`,concat("|",str_varchar,"|") as `varchar` from str_table;

mysql> select id,concat("|",str_char,"|") as `char`,concat("|",str_varchar,"|") as `varchar` from str_table; +----+---------------+---------------+ | id | char | varchar | +----+---------------+---------------+ | 6 | |陈哈哈| | |陈哈哈| | | 7 | | 陈哈哈| | | 陈哈哈| | | 8 | |陈哈哈| | |陈哈哈 | | +----+---------------+---------------+ 3 rows in set (0.00 sec)

  • 当检索这些值的时分,会发觉id=8行中,char典范的"陈哈哈 "末了的空格被截断了,而VARCHAR(10)字段存储相反的值时,末了的空格被保存了。
  • 别的,id=7行的数据前方空格都被保存了。

可见,CHAR会默许切掉字符串末了的空格,假如必要保存末了的空格,记得用varchar典范!

三、相似的二进制典范:VARBINARY

??与CHAR和VARCHAR相似的典范另有BINARY和VARBINARY,它们存储的是二进制字符串。二进制字符串跟常规字符串十分相似,但是二进制字符串存储的是字节码而不是字符。 添补也不一样:MySQL添补BINARY接纳的是\0 (零字节)而不是空格,在检索时也不会去掉添补值。

??当必要存储二进制数据,并且渴望MySQL使用字节码而不是字符举行比力时,这些典范好坏常有效的。二进制比力的上风并不仅仅表如今轻重写敏感上。MySQL比力BINARY字符串时,每次按一个字节,并且依据该字节的数值举行比力。因此,二进制比 较比字符比力简便很多,以是也就更快。

  • varchar

??varchar是可变长度字符典范,假如对应的数据库排序端正是utf8_general_ci,那么查询的时分将不区分轻重写。假如排序端正是utf8_bin,则会区分轻重写。

  • varbinary

??varbinary是二进制字符典范,在排序端正utf8_general_ci下,是可以区分轻重写的。

版权声明:本文来自互联网整理发布,如有侵权,联系删除

原文链接:https://www.yigezhs.comhttps://www.yigezhs.com/shenghuojineng/54257.html


Copyright © 2021-2022 All Rights Reserved 备案编号:闽ICP备2023009674号 网站地图 联系:dhh0407@outlook.com