翻譯:MariaDB ALTER TABLE語句

分類:IT技術 時間:2017-09-26

本文是MariaDB官方ALTER TABLE手冊的翻譯,99%的內容是按照手冊給的內容進行翻譯的。

原文地址:https://mariadb.com/kb/en/library/alter-table/

我提交到MariaDB官方手冊的譯文:https://mariadb.com/kb/zh-cn/library/alter-table/

Syntax

ALTER [ONLINE] [IGNORE] TABLE tbl_name
    [WAIT n | NOWAIT]
    alter_specification [, alter_specification] ...

alter_specification:
    table_option ...
  | ADD [COLUMN] col_name column_definition
        [FIRST | AFTER col_name ]
  | ADD [COLUMN] (col_name column_definition,...)
  | ADD {INDEX|KEY} [index_name]
        [index_type] (index_col_name,...) [index_option] ...
  | ADD [CONSTRAINT [symbol]] PRIMARY KEY
        [index_type] (index_col_name,...) [index_option] ...
  | ADD [CONSTRAINT [symbol]]
        UNIQUE [INDEX|KEY] [index_name]
        [index_type] (index_col_name,...) [index_option] ...
  | ADD FULLTEXT [INDEX|KEY] [index_name]
        (index_col_name,...) [index_option] ...
  | ADD SPATIAL [INDEX|KEY] [index_name]
        (index_col_name,...) [index_option] ...
  | ADD [CONSTRAINT [symbol]]
        FOREIGN KEY [index_name] (index_col_name,...)
        reference_definition
  | ALTER [COLUMN] col_name SET DEFAULT literal | (expression)
  | ALTER [COLUMN] col_name DROP DEFAULT
  | CHANGE [COLUMN] old_col_name new_col_name column_definition
        [FIRST|AFTER col_name]
  | MODIFY [COLUMN] col_name column_definition
        [FIRST | AFTER col_name]
  | DROP [COLUMN] [IF EXISTS] col_name [RESTRICT|CASCADE]
  | DROP PRIMARY KEY
  | DROP {INDEX|KEY} index_name
  | DROP FOREIGN KEY fk_symbol
  | DROP CONSTRAINT constraint_name
  | DISABLE KEYS
  | ENABLE KEYS
  | RENAME [TO] new_tbl_name
  | ORDER BY col_name [, col_name] ...
  | CONVERT TO CHARACTER SET charset_name [COLLATE collation_name]
  | [DEFAULT] CHARACTER SET [=] charset_name
  | [DEFAULT] COLLATE [=] collation_name
  | DISCARD TABLESPACE
  | IMPORT TABLESPACE
  | ALGORITHM [=] {DEFAULT|INPLACE|COPY}
  | LOCK [=] {DEFAULT|NONE|SHARED|EXCLUSIVE}
  | FORCE
  | partition_options
  | ADD PARTITION (partition_definition)
  | DROP PARTITION partition_names
  | COALESCE PARTITION number
  | REORGANIZE PARTITION [partition_names INTO (partition_definitions)]
  | ANALYZE PARTITION partition_names
  | CHECK PARTITION partition_names
  | OPTIMIZE PARTITION partition_names
  | REBUILD PARTITION partition_names
  | REPAIR PARTITION partition_names
  | EXCHANGE PARTITION partition_name WITH TABLE tbl_name
  | REMOVE PARTITIONING

column_definition:
    data_type [NOT NULL | NULL] [DEFAULT default_value | (expression)]
      [AUTO_INCREMENT] [UNIQUE [KEY] | [PRIMARY] KEY]
      [COMMENT 'string']
      [COLUMN_FORMAT {FIXED|DYNAMIC|DEFAULT}]
      [STORAGE {DISK|MEMORY|DEFAULT}]
  | data_type [GENERATED ALWAYS]  AS   ( <expression> )  {VIRTUAL | PERSISTENT}
      [UNIQUE] [UNIQUE KEY] [COMMENT 'string']

index_col_name:
    col_name [(length)] [ASC | DESC]

index_type:
    USING {BTREE | HASH | RTREE}

index_option:
    KEY_BLOCK_SIZE [=] value
  | index_type
  | WITH PARSER parser_name
  | COMMENT 'string'
  | CLUSTERING={YES| NO}

table_options:
    table_option [[,] table_option] ...  (see CREATE TABLE options)

從MariaDB 10.0.2開始,ALTER TABLE還支持IF EXISTS和IF NOT EXISTS字句。包括以下幾種情況:

ADD COLUMN       [IF NOT EXISTS]
ADD INDEX        [IF NOT EXISTS]
ADD FOREIGN KEY  [IF NOT EXISTS]
ADD PARTITION    [IF NOT EXISTS]
CREATE INDEX     [IF NOT EXISTS]

DROP COLUMN      [IF EXISTS]
DROP INDEX       [IF EXISTS]
DROP FOREIGN KEY [IF EXISTS]
DROP PARTITION   [IF EXISTS]
CHANGE COLUMN    [IF EXISTS]
MODIFY COLUMN    [IF EXISTS]
DROP INDEX       [IF EXISTS]

當使用了IF EXISTS或IF NOT EXISTS時,當滿足存在或不存在的條件時,查詢將不會產生任何錯誤。

基本描述

ALTER TABLE語句可以改變已存在表的結構。例如,可以增減字段、創建或銷毀索引、修改字段類型、重命名字段或重命名表自身。還可以改變表的註釋以及表的存儲引擎。

如果有某個連接正在使用表,將會激活一個元數據鎖,這使得ALTER語句會一直等待直到該鎖被釋放。這也適用於非事務表

當在已存在重復值的某字段(或某幾個字段)上建立UNIQUE索引時,將生成一個錯誤信息,然後alter語句終止。可以指定IGNORE選項忽略字段中的重復值,以禁止該錯誤並強制創建UNIQUE索引。但它將無法控制已存在的行。還需要註意,alter table ... exchange partition語句雖然接受IGNORE選項,但會忽略它。

ALTER TABLE可以重命名表,詳細信息見我的另一篇譯文RENAME TABLE

當創建索引時,存儲引擎將在處理過程中使用可配置的buffer。增大buffer可以加速索引的創建。Aria和MyISAM存儲引擎分別根據aria_sort_buffer_sizemyisam_sort_buffer_size指定的值大小來分配buffer,在REPAIR TABLE時也同樣會使用其值來分配buffer空間。InnoDB/XtraDB存儲引擎使用innodb_sort_buffer_size的值來分配3個具有該值大小的buffer空間。

註:innodb sort buffer的大小影響索引創建速度,還影響online DDL操作時記錄並發寫的臨時日誌文件數量。在MariaDB 10.0以前,innodb_sort_buffer_size的大小是固定不可配置的,其值為1M。設置的值越大,在排序時合並結果的次數和階段就越少,速度就越快。當CREATE TABLE或ALTER TABLE創建新的索引時,將分配3個具有該值大小的buffer空間,還包括緩沖區中的行的指針。該變量為全局變量,單位為字節,默認值為1048576(即1M),有效範圍為65536-67108864(即64k-64M)。

索引類型Index Type

存儲引擎允許的索引類型如下:

Storage EnginePermitted Indexes Aria BTREE, RTREE MyISAM BTREE, RTREE InnoDB BTREE MEMORY/HEAP HASH, BTREE NDB BTREE, HASH

CLUSTERING={YES|NO}僅對Tokudb有效。

CREATE INDEXDROP INDEX同樣也可以添加或刪除索引。

字符集和排序規則Character Sets and Collations

CONVERT TO CHARACTER SET charset_name [COLLATE collation_name]
[DEFAULT] CHARACTER SET [=] charset_name
[DEFAULT] COLLATE [=] collation_name

WAIT/NOWAIT

從MariaDB 10.3.0開始引入WAIT和NOWAIT選項,用於設置某些語句的鎖等待超時時長。詳細信息見我的另一篇譯文:MariaDB wait/nowait

ADD COLUMN [IF NOT EXISTS] (col_name column_definition,...)

向表中添加一個字段。語法同CREATE TABLE。如果使用了IF NOT EXISTS,則待添加的列已存在時不會被創建。這在腳本中想要修改表時非常有用。

FIRST和AFTER字句會影響數據文件datafile中字段的物理順序。使用FIRST以將字段添加到表的最左邊的位置,即作為第一列。或者使用AFTER使得新建的列在指定的字段之後。註意,直到目前為止,字段的物理位置順序通常是無關緊要的。

DROP COLUMN [IF EXISTS] col_name [CASCADE|RESTRICT]

從表中刪除字段。如果使用IF EXISTS,那麽在字段不存在時不會產生錯誤信息。如果字段是某個或某些索引的一部分,刪除字段將會從索引中將其刪除,除非你在同一時刻創建一個同名的新字段(例如修改字段類型時會隱式重建字段)。如果索引中的所有字段都被刪除了,則索引會自動被刪除。如果在視圖或觸發器中引用了某個字段,將在下次訪問視圖或觸發器時產生一個錯誤信息。

從MariaDB 10.2.8開始,從多列復合的UNIQUE約束中刪除某個字段是不被允許的,例如:

CREATE TABLE a (
  a int,
  b int,
  primary key (a,b)
);

ALTER TABLE x DROP COLUMN a;
[42000][1072] Key column 'A' doesn't exist in table

刪除字段a的過程中將導致新的約束(刪除字段a就變成了新約束)要求字段b中的所有值都是唯一的。要刪除UNIQUE索引中的字段,需要顯式指定drop primary key以及add primary key。而MariaDB 10.2.7版本及以前的版本,都可以直接刪除字段並應用新的約束,如下:

ALTER TABLE x DROP COLUMN a;
Query OK, 0 rows affected (0.46 sec)

DESC x;
+-------+---------+------+-----+---------+-------+
| Field | Type    | Null | Key | Default | Extra |
+-------+---------+------+-----+---------+-------+
| b     | int(11) | NO   | PRI | NULL    |       |
+-------+---------+------+-----+---------+-------+

RESTRICT和CASCADE使得從其他數據庫系統移植數據更加容易,但在MariaDB中,它們沒有任何作用。

MODIFY COLUMN

可以用來修改字段類型。modify操作不會改變字段順序,也不會影響索引中的字段元素。註意,當modifiy字段時,必須重新指定新字段的所有屬性,但因為不會影響索引中的內容,所以無需再指定約束類屬性。

CREATE TABLE t1 (a INT UNSIGNED AUTO_INCREMENT, PRIMARY KEY((a));
ALTER TABLE t1 MODIFY a BIGINT UNSIGNED AUTO_INCREMENT;

CHANGE COLUMN

change和modify工作方式基本相同,除了change可以改變字段名稱。同樣不會改變字段順序和索引中的字段元素。

CREATE TABLE t1 (a INT UNSIGNED AUTO_INCREMENT, PRIMARY KEY(a));
ALTER TABLE t1 CHANGE a b BIGINT UNSIGNED AUTO_INCREMENT;

ENABLE/ DISABLE KEYS

DISABLE KEYS將無視表中存儲引擎(至少是MyISAM和Aria)支持的所有非unique索引。這可以加速向空表插入數據。

ENABLE KEYS用來啟用所有被DISABLE的KEYS。

ENGINE/FORCE For Re-building a Table

ALTER TABLE可以強制MariaDB重建(rebuild)表。在MariaDB 10.0以前,只能通過設置表的ENGINE為原值來實現。從MariaDB 10.0開始,還可以使用FORCE選項來實現。例如下面的InnoDB表,可以:

ALTER TABLE tab_name ENGINE = InnoDB;

從MariaDB 10.0開始,這等價於:

ALTER TABLE tab_name FORCE;

對於InnoDB存儲引擎,ALTER TABLE將在innodb_file_per_table設置為ON時回收未使用的空間(例如,之前刪除行後遺留下來的空間)。如果該變量的值為OFF,在ALTER TABLE後將不會回收未使用的空間,但新插入數據時可以重新使用這些空間。

IMPORT TABLESPACE

用於導入由flush tables for export創建的InnoDB表。

導入的過程大致如下:

CREATE TABLE t…; /* using the output from SHOW CREATE TABLE */
ALTER TABLE t DISCARD TABLESPACE; /* effectively corrupts the database! */
/* copy the file t.ibd to the file system */
ALTER TABLE t IMPORT TABLESPACE;

其他存儲引擎無需使用alter table ...import。這些數據被拷貝後可以立刻被成功訪問。

ALGORITHM子句/ALTER TABLE何時會拷貝全表數據?

在MariaDB 10.0之前,ALTER TABLE操作表時會創建該表的臨時副本,這使得操作大表時速度較慢。從MariaDB 10.0開始,ALTER TABLE的許多操作都可以直接在原地操作,不再需要創建表的臨時副本。

隨著時間的推移,可能越來越多的操作都不再需要拷貝全表數據。以下是目前不需要表拷貝的動作的alter table行為:

  • 修改字段名稱。
  • 擴大整型數據類型的顯示寬度,例如INT(2)-->INT(3)。
  • 修改表註釋。
  • 向enum的列表尾部添加值。
  • 重命名表。

如果要執行多個操作,並且其中可能有一個或多個操作要求重建表,那麽可以很方便地將這些操作組合在單個ALTER TABLE語句中,以便只執行一次重建操作。

從MariaDB 10.0開始,ALTER TABLE開始支持ALGORITHM字句,該字句有3種值:

  • ALGORITHM=DEFAULT (未指定ALGORITHM子句時的默認值)
  • ALGORITHM=COPY
  • ALGORITHM=INPLACE

設置ALGORITHM=COPY時,即使是那些沒必要拷貝表數據的操作也會進行copy。這會導致大量表數據的拷貝。

設置ALGORITHM=INPLACE時,將采用in-place技術(原地執行操作),它會禁止表數據拷貝。如果某操作要求拷貝表數據,那麽會返回類似如下的錯誤:

CREATE TABLE t1 (a INT, e ENUM ('red','green'));
ALTER TABLE t1 MODIFY e EMUM('red','green','blue'), ALGORITHM=INPLACE;
-> Query OK, 0 rows affected (0.11 sec)
-> Records: 0  Duplicates: 0  Warnings: 0

ALTER TABLE t1 ADD c INT, ALGORITHM=INPLACE;
-> ERROR 1845 (0A000): ALGORITHM=INPLACE is not supported for this operation. Try ALGORITHM=COPY.

默認的行為(ALGORITHM=DEFAULT,或未設置ALGORITHM子句)通常僅在需要拷貝時進行表數據拷貝。可以通過設置系統變量old_alter_table的值為ON(默認為OFF)來改變它的行為,這種情況下將使用pre-mysql 5.0的拷貝算法進行表拷貝。

當設置ALGORITHM=INPLACE算法時,某些情況下會需要一些臨時文件,這些臨時文件創建在tmpdir系統變量指定的臨時目錄內。

註意,如果使用了COPY算法,那麽innodb_file_per_tableinnodb_file_format變量的當前值會在InnoDB表重建時被提交。

LOCK子句

不同的操作、不同的存儲引擎,ALTER TABLE采用的鎖策略也不同。在某些情況下完全不需要任何鎖,某些情況下僅需要讀鎖,某些情況下又需要寫鎖。LOCK子句可以指定一個固定的鎖策略。它會強制使用該鎖策略(即使指定的鎖策略可能比操作正常需求的鎖策略更嚴格),但如果存儲引擎上的某個操作要求比指定的策略更嚴格的策略,將生成錯誤信息。LOCK接受的值包括:

  • DEFAULT: 采用所允許的最高並發級別的鎖。
  • NONE: 不采用任何鎖,這可能會經常性地產生錯誤信息。
  • SHARED: 采用讀鎖。
  • EXCLUSIVE: 采用寫鎖。
  • 不指定LOCK子句時,默認LOCK=DEFAULT。

此外,可以使用ALTER ONLINE TABLE確保ALTER TABLE子句不會阻塞任何正在並發的操作(不使用任何鎖),這等價於LOCK=NONE。

顯示進度

從MariaDB 5.3開始,可以在支持進度報告協議的客戶端上獲取ALTER TABLE的處理進度。例如,從mysql客戶端:

ALTER TABLE test ENGINE=Aria;
Stage: 1 of 2 'copy to tmp table'    46% of stage

show processlist以及information_schema.processlist表同樣也可以顯示處理進度。

權限需求

ALTER TABLE要求至少有ALTER權限。重命名表還需要DROP, CREATE以及INSERT權限(因為重命名表是重建表的過程,需要拷貝整個表數據到臨時副本,並使用副本填充新表)。

示例

添加一個字段:

ALTER TABLE t1 ADD x INT;

刪除一個字段:

ALTER TABLE t1 DROP x;

修改字段類型:

ALTER TABLE t1 MODIFY x bigint unsigned;

修改字段名稱以及字段類型:

ALTER TABLE t1 CHANGE a b bigint unsigned auto_increment;

整合多個子句到單個ALTER TABLE語句中,使用逗號分隔:

ALTER TABLE t1 DROP x, ADD x2 INT,  CHANGE y y2 INT;

更換存儲引擎:

ALTER TABLE t1 ENGINE = InnoDB;

強制重建表(如果上面的例子中存儲引擎已經是InnoDB,也將會重建表):

ALTER TABLE t1 FORCE;

 

回到linux系列文章大綱:http://www.cnblogs.com/f-ck-need-u/p/7048359.html

回到數據庫系列文章大綱:http://www.cnblogs.com/f-ck-need-u/p/7586194.html

轉載請註明出處:http://www.cnblogs.com/f-ck-need-u/p/7595248.html

註:若您覺得這篇文章還不錯請點擊右下角推薦,您的支持能激發作者更大的寫作熱情,非常感謝!


Tags: button font-size display margin input overflow

文章來源:


ads
ads

相關文章
ads

相關文章

ad