MySQL 和 MariaDB:對錶進行整理與對所有列進行整理?
下表的行為或執行是否會有所不同
CREATE TABLE t1 ( foo char(60) COLLATE utf8_bin, bar char(64) COLLATE utf8_bin, baz char(80) COLLATE utf8_bin ) DEFAULT CHARSET=utf8;
比這張表
CREATE TABLE t2 ( foo char(60), bar char(64), baz char(80) ) DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
我問這個是因為當我執行
SHOW CREATE TABLE mysql.db
它時,它會在每列(如t1
)和表格上(如t2
)顯示標記。DEFAULT COLLATE
我在創建表格時從不添加。我想知道為什麼系統表設置了這個選項。
- 以它們目前的形式: and 的行為和表現
t1
應該t2
是相同的,和: 2. 如果添加了一個未指定
CHARSET
orCOLLATE
子句的字元串列:行為和性能將有所不同。這是因為:
- 中的新列
t2
將是CHARSET=utf8
andCOLLATE=utf8_bin
(因為它們被指定為表的預設值),但是- 中的新列
t1
將是CHARSET=utf8
(因為它被指定為表的預設值),但也將是COLLATE=utf8_general_ci
(因為這應該是utf8
字元集的預設值)現在,我在問題中創建了這兩個表,結果如下:
SHOW CREATE TABLE t1; CREATE TABLE `t1` ( `foo` char(60) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT NULL, `bar` char(64) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT NULL, `baz` char(80) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT NULL ) ENGINE=InnoDB DEFAULT CHARSET=utf8
和:
SHOW CREATE TABLE t2; CREATE TABLE `t2` ( `foo` char(60) COLLATE utf8_bin DEFAULT NULL, `bar` char(64) COLLATE utf8_bin DEFAULT NULL, `baz` char(80) COLLATE utf8_bin DEFAULT NULL ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin
我不確定為什麼
CHARACTER SET
在聲明的儲存版本中明確說明CREATE TABLE t1
,但我想我知道為什麼COLLATE
這樣做了CREATE TABLE t2
:一旦你送出聲明,這就是它在處理過程中被翻譯成的內容。為什麼只是COLLATE
聲明而不是CHARACTER SET
呢?這很可能是由於字元集使用 1 個或多個排序規則,因此指定字元集並不意味著排序規則。另一方面,排序規則僅適用於 1 個字元集,因此指定排序規則確實暗示字元集。是的,字元集具有預設排序規則,但預設值可能會隨著時間或上下文之間發生變化。是的,有為表顯式聲明的預設值,但是如果 a) 表預設值不受尊重,和/或 b) 正在讀取的任何內容,DDL 都希望在解析列時了解有關列的所有資訊,而不是需要先讀取完整的表 DDL 並可能返回應用預設值。添加COLLATE
子句使操作非常清晰明確。此外,CREATE TABLE Statement Retention的文件指出:
原始
CREATE TABLE
語句,包括所有規格和表選項,在創建表時由 MySQL 儲存。該資訊被保留,因此如果您使用ALTER TABLE
語句更改儲存引擎、排序規則或其他設置,指定的原始表選項將被保留。即使兩個引擎支持的行格式不同,這也使您能夠在InnoDB
和表類型之間進行更改。MyISAM
我在db<>fiddle上針對 MariaDB 10.2 和 10.3 進行了測試。和 MySQL 5.6、5.7 和 8.0,它們的行為都是相同的。
不,我相信它是一樣的(假設沒有其他人回答不同)。從文件
**如果未在單個列定義中指定列字元集和排序規則,則表字元集和排序規則將用作列定義的預設值。**表字元集和排序規則是 MySQL 的擴展;標準 SQL 中沒有這樣的東西。