CHAR
和 VARCHAR
類型相似,但在儲存和擷取方式上有所不同。它們在最大長度以及是否保留尾隨空格方面也有所不同。
CHAR
和 VARCHAR
類型的宣告會使用一個長度,表示您想要儲存的最大字元數。例如,CHAR(30)
最多可容納 30 個字元。
CHAR
欄位的長度固定為您在建立表格時宣告的長度。長度可以是 0 到 255 之間的任何值。當儲存 CHAR
值時,它們會以空格向右填補到指定的長度。當擷取 CHAR
值時,除非啟用 PAD_CHAR_TO_FULL_LENGTH
SQL 模式,否則會移除尾隨空格。
VARCHAR
欄位中的值是可變長度字串。長度可以指定為 0 到 65,535 之間的值。VARCHAR
的有效最大長度取決於最大列大小(65,535 個位元組,在所有欄位之間共用)以及所使用的字元集。請參閱第 10.4.7 節「表格欄位計數和列大小的限制」。
與 CHAR
相反,VARCHAR
值會以 1 位元組或 2 位元組長度前置詞加上資料的方式儲存。長度前置詞會指示值中的位元組數。如果值不需要超過 255 個位元組,則欄位會使用一個長度位元組;如果值可能需要超過 255 個位元組,則會使用兩個長度位元組。
如果未啟用嚴格的 SQL 模式,並且您為 CHAR
或 VARCHAR
欄位指定的值超過欄位的最大長度,則該值會被截斷以符合長度,並產生警告。對於截斷非空格字元,您可以讓錯誤發生(而不是警告),並透過使用嚴格的 SQL 模式來禁止插入值。請參閱第 7.1.11 節「伺服器 SQL 模式」。
對於 VARCHAR
欄位,超過欄位長度的尾隨空格會在插入前被截斷,並產生警告,無論使用何種 SQL 模式。對於 CHAR
欄位,從插入值中截斷多餘的尾隨空格會以靜默方式執行,無論 SQL 模式為何。
VARCHAR
值在儲存時不會填補。尾隨空格會在儲存和擷取值時保留,符合標準 SQL。
下表說明了 CHAR
和 VARCHAR
之間的差異,方法是顯示將各種字串值儲存到 CHAR(4)
和 VARCHAR(4)
欄位中的結果(假設該欄位使用單一位元組字元集,例如 latin1
)。
值 | CHAR(4) |
所需儲存空間 | VARCHAR(4) |
所需儲存空間 |
---|---|---|---|---|
'' |
' ' |
4 個位元組 | '' |
1 個位元組 |
'ab' |
'ab ' |
4 個位元組 | 'ab' |
3 個位元組 |
'abcd' |
'abcd' |
4 個位元組 | 'abcd' |
5 個位元組 |
'abcdefgh' |
'abcd' |
4 個位元組 | 'abcd' |
5 個位元組 |
表格最後一列中顯示的儲存值 僅在未使用嚴格 SQL 模式時適用;如果啟用嚴格模式,則超過欄位長度的值不會儲存,並導致錯誤。
長度大於或等於 768 位元組的固定長度欄位,InnoDB
會將其編碼為可變長度欄位,這可以儲存在頁面之外。例如,如果字元集的最大位元組長度大於 3(如 utf8mb4
所示),則 CHAR(255)
欄位可能會超過 768 個位元組。
如果將給定的值儲存到 CHAR(4)
和 VARCHAR(4)
欄位中,則從欄位擷取的值並不總是相同,因為從 CHAR
欄位擷取時會移除尾隨空格。以下範例說明此差異
mysql> CREATE TABLE vc (v VARCHAR(4), c CHAR(4));
Query OK, 0 rows affected (0.01 sec)
mysql> INSERT INTO vc VALUES ('ab ', 'ab ');
Query OK, 1 row affected (0.00 sec)
mysql> SELECT CONCAT('(', v, ')'), CONCAT('(', c, ')') FROM vc;
+---------------------+---------------------+
| CONCAT('(', v, ')') | CONCAT('(', c, ')') |
+---------------------+---------------------+
| (ab ) | (ab) |
+---------------------+---------------------+
1 row in set (0.06 sec)
CHAR
、VARCHAR
和 TEXT
欄位中的值會根據指派給欄位的字元集排序規則進行排序和比較。
除了基於 UCA 9.0.0 及更高版本的 Unicode 排序規則以外,MySQL 排序規則的填補屬性為 PAD SPACE
,這些排序規則的填補屬性為 NO PAD
。(請參閱第 12.10.1 節「Unicode 字元集」)。
若要判斷排序規則的填補屬性,請使用 INFORMATION_SCHEMA
COLLATIONS
表格,其具有 PAD_ATTRIBUTE
欄位。
對於非二進位字串(CHAR
、VARCHAR
和 TEXT
值),字串排序規則填補屬性會決定字串末尾的尾隨空格在比較中的處理方式。NO PAD
排序規則在比較中將尾隨空格視為重要,就像任何其他字元一樣。PAD SPACE
排序規則在比較中將尾隨空格視為不重要;比較字串時不考慮尾隨空格。請參閱比較中的尾隨空格處理。伺服器 SQL 模式對尾隨空格的比較行為沒有影響。
有關 MySQL 字元集和排序規則的詳細資訊,請參閱第 12 章字元集、排序、Unicode。有關儲存需求的更多資訊,請參閱第 13.7 節「資料類型儲存需求」。
在尾隨填充字元被移除或比較忽略它們的情況下,如果欄位具有需要唯一值的索引,則插入僅在尾隨填充字元數量上不同的欄位值會導致重複鍵錯誤。例如,如果表格包含 'a'
,則嘗試儲存 'a '
會導致重複鍵錯誤。