本節說明二進位字串的 binary
校對與非二進位字串的 _bin
校對之間的比較方式。
二進位字串(使用 BINARY
、VARBINARY
和 BLOB
資料類型儲存)具有名為 binary
的字元集和校對。二進位字串是位元組序列,這些位元組的數值會決定比較和排序順序。請參閱 第 12.10.8 節,「二進位字元集」。
非二進位字串(使用 CHAR
、VARCHAR
和 TEXT
資料類型儲存)具有 binary
以外的字元集和校對。給定的非二進位字元集可以有多個校對,每個校對都為該集合中的字元定義特定的比較和排序順序。對於大多數字元集,其中一個是二進位校對,在校對名稱中以 _bin
字尾表示。例如,latin1
和 big5
的二進位校對分別命名為 latin1_bin
和 big5_bin
。utf8mb4
是一個例外,它有兩個二進位校對,utf8mb4_bin
和 utf8mb4_0900_bin
;請參閱 第 12.10.1 節,「Unicode 字元集」。
binary
校對在幾個方面與 _bin
校對不同,以下各節將討論這些差異
二進位字串是位元組序列。對於 binary
校對,比較和排序是基於數值位元組值。非二進位字串是字元序列,字元可能是多位元組。非二進位字串的校對定義了用於比較和排序的字元值順序。對於 _bin
校對,此順序是基於數值字元代碼值,這與二進位字串的排序類似,只是字元代碼值可能是多位元組。
非二進位字串具有字元集,並且在許多情況下會自動轉換為另一個字元集,即使字串具有 _bin
校對也是如此
當將資料行值指派給另一個具有不同字元集的資料行時
UPDATE t1 SET utf8mb4_bin_column=latin1_column; INSERT INTO t1 (latin1_column) SELECT utf8mb4_bin_column FROM t2;
當使用字串文字為
INSERT
或UPDATE
指派資料行值時SET NAMES latin1; INSERT INTO t1 (utf8mb4_bin_column) VALUES ('string-in-latin1');
當將結果從伺服器傳送到用戶端時
SET NAMES latin1; SELECT utf8mb4_bin_column FROM t2;
對於二進位字串資料行,不會進行轉換。對於與上述類似的情況,字串值會按位元組複製。
非二進位字元集的校對提供關於字元字母大小寫的資訊,因此非二進位字串中的字元可以從一個字母大小寫轉換為另一個字母大小寫,即使對於忽略字母大小寫排序的 _bin
校對也是如此
mysql> SET NAMES utf8mb4 COLLATE utf8mb4_bin;
mysql> SELECT LOWER('aA'), UPPER('zZ');
+-------------+-------------+
| LOWER('aA') | UPPER('zZ') |
+-------------+-------------+
| aa | ZZ |
+-------------+-------------+
字母大小寫的概念不適用於二進位字串中的位元組。若要執行字母大小寫轉換,必須先使用適用於字串中儲存資料的字元集,將字串轉換為非二進位字串
mysql> SET NAMES binary;
mysql> SELECT LOWER('aA'), LOWER(CONVERT('aA' USING utf8mb4));
+-------------+------------------------------------+
| LOWER('aA') | LOWER(CONVERT('aA' USING utf8mb4)) |
+-------------+------------------------------------+
| aA | aa |
+-------------+------------------------------------+
MySQL 校對具有一個填補屬性,其值為 PAD SPACE
或 NO PAD
大多數 MySQL 校對的填補屬性為
PAD SPACE
。基於 UCA 9.0.0 和更高版本的 Unicode 校對具有
NO PAD
的填補屬性;請參閱 第 12.10.1 節,「Unicode 字元集」。
對於非二進位字串(CHAR
、VARCHAR
和 TEXT
值),字串校對填補屬性決定字串末尾尾隨空格在比較中的處理方式
對於
PAD SPACE
校對,尾隨空格在比較中並不重要;字串的比較不考慮尾隨空格。NO PAD
校對將尾隨空格視為比較中的重要字元,就像任何其他字元一樣。
可以使用兩種 utf8mb4
二進位排序規則來示範不同的行為,其中一種是 PAD SPACE
,另一種是 NO PAD
。此範例還展示如何使用 INFORMATION_SCHEMA
的 COLLATIONS
表格來判斷排序規則的填充屬性。
mysql> SELECT COLLATION_NAME, PAD_ATTRIBUTE
FROM INFORMATION_SCHEMA.COLLATIONS
WHERE COLLATION_NAME LIKE 'utf8mb4%bin';
+------------------+---------------+
| COLLATION_NAME | PAD_ATTRIBUTE |
+------------------+---------------+
| utf8mb4_bin | PAD SPACE |
| utf8mb4_0900_bin | NO PAD |
+------------------+---------------+
mysql> SET NAMES utf8mb4 COLLATE utf8mb4_bin;
mysql> SELECT 'a ' = 'a';
+------------+
| 'a ' = 'a' |
+------------+
| 1 |
+------------+
mysql> SET NAMES utf8mb4 COLLATE utf8mb4_0900_bin;
mysql> SELECT 'a ' = 'a';
+------------+
| 'a ' = 'a' |
+------------+
| 0 |
+------------+
此處的「比較」不包含 LIKE
模式比對運算子,無論排序規則為何,尾隨空格對此運算子都具有意義。
對於二進位字串(BINARY
、VARBINARY
和 BLOB
值),所有位元組在比較時都具有意義,包括尾隨空格。
mysql> SET NAMES binary;
mysql> SELECT 'a ' = 'a';
+------------+
| 'a ' = 'a' |
+------------+
| 0 |
+------------+
CHAR(
欄位儲存長度為 N
)N
個字元的非二進位字串。對於插入,短於 N
個字元的值會以空格延伸。對於擷取,尾隨空格會被移除。
BINARY(
欄位儲存長度為 N
)N
個位元組的二進位字串。對於插入,短於 N
個位元組的值會以 0x00
位元組延伸。對於擷取,不會移除任何內容;始終會傳回宣告長度的值。
mysql> CREATE TABLE t1 (
a CHAR(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin,
b BINARY(10)
);
mysql> INSERT INTO t1 VALUES ('x','x');
mysql> INSERT INTO t1 VALUES ('x ','x ');
mysql> SELECT a, b, HEX(a), HEX(b) FROM t1;
+------+------------------------+--------+----------------------+
| a | b | HEX(a) | HEX(b) |
+------+------------------------+--------+----------------------+
| x | 0x78000000000000000000 | 78 | 78000000000000000000 |
| x | 0x78200000000000000000 | 78 | 78200000000000000000 |
+------+------------------------+--------+----------------------+