Mysql

MySQL 和 MariaDB:對錶進行整理與對所有列進行整理?

  • June 10, 2019

下表的行為或執行是否會有所不同

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我在創建表格時從不添加。我想知道為什麼系統表設置了這個選項。

  1. 以它們目前的形式: and 的行為和表現t1應該t2是相同的,

和: 2. 如果添加了一個未指定CHARSETorCOLLATE子句的字元串列:行為和性能將有所不同。這是因為:

  1. 中的新列t2將是CHARSET=utf8and COLLATE=utf8_bin(因為它們被指定為表的預設值),但是
  2. 中的新列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 中沒有這樣的東西。

引用自:https://dba.stackexchange.com/questions/240093