MySQL char與varchar的差異
轉自:https://www.cnblogs.com/zejin2008/p/6020030.html
字元與位元組的區別
一個字元由於所使用的字符集的不同,會並存儲在一個或多個位元組中,所以一個字元佔用多少個位元組取決於所使用的字符集
注意:char與varchar後面接的資料大小為儲存的字元數,而不是位元組數
char與varchar的差異
為方便說明,我們下面定義一個表:
CREATE TABLE `t_users` (
`name` CHAR(10) NOT NULL,
`subject` VARCHAR(10) NOT NULL,
`description` CHAR(10) NOT NULL
)
INSERT INTO `t_users` (`name`, `subject`, `description`) VALUES ('zejin', 'zejin ', 'zejin ');
存資料時的區別
char定義的是固定長度,長度範圍為0-255,儲存時,如果字元數沒有達到定義的位數,會在後面用空格補全存入資料庫中,在上例中,name實際儲存在資料中的資料為'zejin '
varchar是變長長度,長度範圍為0-65535,儲存時,如果字元沒有達到定義的位數,也不會在後面補空格,在上例subject欄位中,實際儲存在資料中的資料為'zejin ',當然還有一或兩個位元組來描述該位元組長度
取資料時的區別
資料庫取char的資料時,會把後面的空格全部丟棄掉,譬如上例中的description欄位取出來時只剩zejin
mysql> select concat('(',name,')'),concat('(',description,')') from t_users;
+----------------------+-----------------------------+
| concat('(',name,')') | concat('(',description,')') |
+----------------------+-----------------------------+
| (zejin) | (zejin) |
+----------------------+-----------------------------+
1 row in set (0.00 sec)
也就是說,在char中的尾部存入空格時,最後取出來都會被丟棄
當然指定PAD_CHAR_TO_FULL_LENGTH時,在取資料時讓尾部的空格保留
而資料庫在取varchar資料時,尾部空格會保留,譬如subject欄位:
mysql> select concat('(',subject,')'),concat('(',description,')') from t_users;
+-------------------------+-----------------------------+
| concat('(',subject,')') | concat('(',description,')') |
+-------------------------+-----------------------------+
| (zejin ) | (zejin) |
+-------------------------+-----------------------------+
1 row in set (0.00 sec)
佔用位元組差別
以latin編碼為便,一個字元佔用一個位元組。
Value | CHAR(4) | Storage Required | VARCHAR(4) | Storage Required |
'' | ' ' | 4 bytes | '' | 1 byte |
'ab' | 'ab ' | 4 bytes | 'ab' | 3 bytes |
'abcd' | 'abcd' | 4 bytes | 'abcd' | 5 bytes |
'abcdefgh' | 'abcd' | 4 bytes | 'abcd' | 5 bytes |
可以用上表來表示,當定義char時,不管你存入多少字元,都會佔用到你定義的字元數,而用varchar時,則和你輸入的字元數有關,會多一到兩個位元組來記錄位元組長度,當資料位佔用的位元組數小於255時,用1個位元組來記錄長度,資料位佔用位元組數大於255時,用2個位元組來記錄長度,還有一位來記錄是否為nul值
注意
mysql每一行的最大位元組數為65535,當你使用utf8,一個字元有可能佔用三個位元組的時候,varchar如果定義允許空的話能定義的最大長度為(65535-1-2)/3=21844.
Mysql在對比char,varchar,text型別的資料時,是不會把尾部的空格考慮在內的,這對所有字符集都適用,但在這裡是除了like比較符的,譬如:
mysql> select name='zejin',name='zejin ' from t_users;
+--------------+----------------+
| name='zejin' | name='zejin ' |
+--------------+----------------+
| 1 | 1 |
+--------------+----------------+
1 row in set (0.00 sec)
mysql> select name like 'zejin',name like 'zejin ' from t_users;
+-------------------+---------------------+
| name like 'zejin' | name like 'zejin ' |
+-------------------+---------------------+
| 1 | 0 |
+-------------------+---------------------+
1 row in set (0.00 sec)