MySQL varchar和char类型
varchar和char是兩種最主要的字符串類型。不幸的是,很難精確地解釋這些值是怎么儲存在磁盤和內存中的,因為這根存儲引擎的具體實現有關。下面的描述假設使用的存儲引擎是InnoDB或者MyISAM。如果使用的不是這兩種存儲引擎,請參考所使用的存儲引擎的文檔。
先看看varchar和char值通常在磁盤上怎么存儲的。請注意,存儲引擎存儲char或者varchar值的方式在內存中和磁盤上可能不一樣,所以MySQL服務器從存儲引擎讀出的值可能需要轉換成另一種存儲格式。下面是關于兩種類型的一些比較。
varchar
varchar類型用于存儲可變長度字符串,是最常見的字符串數據類型。它比定長類型更節省空間,因為它僅使用必要的空間(例如,越短的字符串使用越少的空間)。有一種情況例外,MySQL表使用ROW_FROMAT=FIXED創建的話,每一行都會使用定長存儲,這會很浪費空間。
varchar需要使用1或者2個額外字節記錄字符串的長度:如果列的最大長度小于或者等于255字節,則使用1個字節表示,否則使用2個字節。假設采用latin1字符集,一個varchar(10)的列需要2個字節存儲長度信息。
?varchar節省了存儲空間,所以針對性能也有幫助。但是由于長度是變長的,在update時可能使行變得比原來更長,這就導致需要做些額外的工作。但是如果一個行占用的空間增長,并且在頁內沒有更多的空間可以存儲,在這種情況下,不同的存儲引擎的處理方式是不一樣的。例如,MyISAM會將行拆成不同的片段存儲,InnoDB則需要分裂頁來是行可以放進頁內。其他一些存儲引擎也許從不在原數據位置更新數據。
下面這些情況下使用varchar是合適的:
在5.0或者更高的版本,MySQL在存儲和檢索時會保留末尾空格。但在4.1或者更老的版本,MySQL會剔除末尾空格。
char
char類型是定長的:MySQL總是根據定義的字符串長度分配足夠的空間。當存儲char值時,MySQL會刪除所有的末尾空格(4.1和更老版本中varchar也是這樣實現的--也就是說這些版本中的char和varchar在邏輯上是一樣的,區別只是在存儲格式上)。char值會根據需要采用空格進行填充以方便比較。
char適合存儲很短的字符串,或者所有值都接近同一個長度。例如,char非常適合存儲密碼的MD5值,因為這是一個定長的值。對于經常變更的數據,char也比varchar更好,因為定長的char類型不容易產生碎片。對于非常短的列,char比varchar存儲空間上也更有效率,例如用char(1)來存儲只有Y和N的值,如果采用單字節字符集只需要一個字節,但是varchar(1)卻需要兩個字節,因為還有一個記錄長度的額外字節。
Tips?單字節字符集:記住字符串長度的定義不是字節數,是字符數。多字節字符集會需要更多的空間存儲單個字符。
char類型的這些行為可能有點難以理解,下面通過一個具體的列子來說明。首先,我們創建一張只有一個char(10)字段的表,并且往里面插入一些值:
mysql> create table char_test(char_col char(10));insert into char_test(char_col)values('string1'),(' string2'),('string3 ');?
?
當檢索這些值的時候,會發現string3末尾的空格被截斷了。
mysql> select concat("'",char_col,"'") from char_test; +--------------------------+ | concat("'",char_col,"'") | +--------------------------+ | 'string1' | | ' string2' | | 'string3' | +--------------------------+如果使用varchar(10)字段存儲相同的值,結果如下:
mysql> select concat("'",varchar_col,"'") from varchar_test; +-----------------------------+ | concat("'",varchar_col,"'") | +-----------------------------+ | 'string1' | | ' string2' | | 'string3 ' | +-----------------------------+?
數據如何存儲取決于存儲引擎,并非所有的存儲引擎都會按照相同的方式處理定長和變長的字符串。Memory引擎只支持定長的行,即使有變長字段也會根據最大長度分配最大空間。(Percona Server里的Memory引擎支持變長的行)。不過填充和截取空格的行為在不同的存儲引擎都是一樣的。因為這是在MySQL服務器層進行處理的。
與char和varchar類似的類型還有binary和varbinary,它們存儲的是二進制字符串。二進制字符串跟常規字符串非常相似,但是二進制字符串存儲的是字節碼而不是字符。填充也不一樣:MySQL填充binary采用的是\0(零字節) 而不是空格,在檢索時也不會去掉填充值。(如果需要在檢索時保持值不變,則需要特別小心binary類型,MySQL會用\0將其填充到需要的長度。)
慷慨是不明智的使用varchar(5)和使用varchar(200)存儲'hello'的空間開銷是一樣的。那么使用更短的列有什么優勢嗎?事實證明有很大的優勢。更長的列會消耗更多的內存,因為MySQL通常會分配固定大小的內存塊來保存內部值。尤其是使用內存臨時表進行排序或操作時會特別糟糕。在利用磁盤臨時表進行排序同樣糟糕。所以,最好的策略是只分配真正需要的空間。?
轉載于:https://www.cnblogs.com/cyun/p/4346064.html
總結
以上是生活随笔為你收集整理的MySQL varchar和char类型的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: leetcode 300. 最长上升子序
- 下一篇: 调试你的Python代码