本文是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_size
和myisam_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, HASHCLUSTERING={YES|NO}
僅對Tokudb有效。
CREATE INDEX
和DROP 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_table
和innodb_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
文章來源: