細說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下,是可以區分輕重寫的。

版權聲明:本文來自互聯網整理發布,如有侵權,聯系刪除

原文鏈接:http://www.freetextsend.comhttp://www.freetextsend.com/shenghuojineng/54257.html


Copyright ? 2021-2022 All Rights Reserved 備案編號:閩ICP備2023009674號 網站地圖 聯系:dhh0407@outlook.com

www.成人网