MySQL 字串型別與字元集

最後更新: 2024-09-07 23:40:56 +0800 +0800
tags: Mysql | Sql | Databases
原文以英文撰寫。您正在閱讀AI翻譯版本。

MySQL 字串欄位同時具有邏輯字元限制與實體位元組表示。將這兩個概念分開,可以避免多語言文字與索引產生許多意外。

CHAR 與 VARCHAR #

CHAR(n) 是固定長度的字元字串。MySQL 會依宣告長度填補值以符合儲存語意,因此它適合真正固定寬度的值,例如國家代碼。VARCHAR(n) 是可變長度,通常是名稱、標籤及其他長度會變動的文字之較佳預設選擇。

在這兩種型別中,n 都是最大字元數,而不是位元組數。因此,當字元集支援時,VARCHAR(10) 欄位可以容納十個表情符號或十個中文字,即使這些字元在磁碟上使用超過十個位元組。

sql
CREATE TABLE profile (
  country_code CHAR(2) NOT NULL,
  display_name VARCHAR(100) NOT NULL
) CHARACTER SET utf8mb4;

TEXT 型別 #

較大的可變長度文字可使用 TINYTEXT、TEXT、MEDIUMTEXT 或 LONGTEXT。它們的限制以位元組計算,因此實際字元容量取決於欄位字元集。TEXT 欄位可以建立索引,但較大的或較舊的 MySQL 設定可能需要索引前綴;在以長文字設計索引前,應檢查儲存引擎與 MySQL 版本。

字元集與定序 #

字元集定義字元如何編碼為位元組。對新的 MySQL 應用程式而言,utf8mb4 通常是安全選擇,因為它支援完整的 Unicode 範圍。MySQL 歷史上的 utf8 名稱可能指三位元組實作,無法表示每個 Unicode 字元。

定序定義字元集的比較與排序規則。它決定比較是否區分大小寫或重音,以及字串如何排序。字元集與定序可以在伺服器、資料庫、資料表或欄位層級設定;明確的資料表或欄位設定能讓應用程式的預期更清楚。

sql
CREATE TABLE article (
  title VARCHAR(255) CHARACTER SET utf8mb4
    COLLATE utf8mb4_0900_ai_ci NOT NULL
);

依應用程式需要的比較方式選擇定序。對識別碼而言,二進位或區分大小寫的比較可能適當;對面向使用者的搜尋而言,不區分重音與大小寫的定序可能較合適。

二進位字串型別 #

BINARY 與 VARBINARY 儲存位元組,而不是文字。它們使用 binary 字元集與定序,因此 MySQL 不會轉碼,也不會套用語言比較規則。BINARY(n) 會以 0x00 填補儲存值;VARBINARY(n) 則不會。較大的位元組序列請使用 BLOB 型別。不要將加密資料、摘要或協定位元組儲存在字元欄位中,因為連線轉換與定序規則可能改變它們的解讀方式。

sql
CREATE TABLE artifact (
  sha256 BINARY(32) NOT NULL,
  payload LONGBLOB NOT NULL,
  PRIMARY KEY (sha256)
);

預設值、連線設定與索引 #

字元集與定序的預設值會從伺服器、資料庫、資料表與欄位設定解析。字串常值也具有字元集與定序。連線會宣告 character_set_client、character_set_connection 與 character_set_results;對未設定它的用戶端,使用驅動程式的 utf8mb4 設定或發出 SET NAMES utf8mb4。

應檢查有效設定,而不是假設套件預設值:

sql
SHOW CREATE TABLE article;
SHOW VARIABLES LIKE 'character_set%';
SHOW VARIABLES LIKE 'collation%';

索引限制以位元組計算。在 utf8mb4 下,VARCHAR(255) 的字元資料最多可能需要 1,020 個位元組,還不包括索引中繼資料。目前的 MySQL 版本中,InnoDB 支援大型索引鍵,但設計仍必須考慮選取的資料列格式、頁面大小與 MySQL 版本。優先對有界搜尋鍵建立索引;只有在前綴仍具有選擇性時,才使用前綴索引。

評論

在 GitHub 上閱讀或評論(發表評論需要登入)