ALTER TABLEtbl_name[alter_option(,alter_option)……] [partition_options]alter_option:{table_options| add[列]col_namecolumn_definition[第一|之后。col_name|添加[列](col_namecolumn_definition| add{索引|键}[index_name] [index_type) (key_part,……)index_option)……| add{全文| spatial}[索引|键][index_name) (key_part,……)index_option)……| add [constraint]象征主键[index_type) (key_part,……)index_option)……| add [constraint]象征[索引|键][index_name] [index_type) (key_part,……)index_option)……| add [constraint]象征]]外键[index_name) (col_name,……)reference_definition| add [constraint]象征[]支票(expr[[not] forced] | drop {check | constraint}象征| alter {check | constraint}象征[not] forced | algorithm [=] {default | instant | inplace | copy} | alter [column]col_name设置默认值文字| (expr)} | set {visible | invisible} | drop default} | alter index .index_name{visible | invisible} | change [column]old_col_namenew_col_namecolumn_definition[第一|之后。col_name| [default]字符集[=]charset_name(核对(=)collation_name|转换为字符集charset_name(核对collation_name| {disable | enable} keys | {discard | import} tablespace | drop [column]col_name删除索引|键index_name|删除主键|删除外键fk_symbol| force | lock [=] {default | none | shared | exclusive} | modify [column]col_namecolumn_definition[第一|之后。col_name订购col_name(,col_name)……|重命名列old_col_name来new_col_name|重命名索引|键old_index_name来new_index_name| rename[使|成为]new_tbl_name|{不带| with}验证}partition_options:partition_option[partition_option)……partition_option:{添加分区(partition_definition) |删除分区partition_names丢弃分区{partition_names|的所有表空间partition_names截断表空间partition_names| all} |合并分区数量重新组织分区partition_names到(partition_definitions) |交换分区partition_name与表tbl_name[{with | without}验证]| analyze partition {partition_names| all} |检查分区{partition_names|优化分区{partition_names|重建分区{partition_names|修复分区{partition_names|删除分区key_part:{col_name[(长度)] | (expr)} [asc | desc]index_type:使用{btree | hash}index_option: {key_block_size [=]价值|index_type|与解析器parser_name|评论'字符串' |{可见|不可见}}table_options:table_option[[,]table_option)……table_option: {autoextend_size [=]价值| auto_increment [=]价值| avg_row_length [=]价值| [default]字符集[=]charset_name| checksum [=] {0 | 1} | [default] collate [=]collation_name| comment [=] '字符串|压缩[=]{“ZLIB”|“LZ4”|“没有”}|连接(=)”connect_string' |{数据|索引}目录[=]'到目录的绝对路径“| DELAY_KEY_WRITE[=]{0} | 1 |加密(=){' Y ' | ' N '} |引擎(=)engine_name| engine_attribute [=] '字符串' | insert_method [=] {no | first | last} | key_block_size [=]价值| max_rows [=]价值| min_rows [=]价值| pack_keys [=] {0 | 1 | default} | password [=] '字符串' | row_format [=] {default | dynamic | fixed | compressed | redundancy | compact} | secondary_engine_attribute [=] '字符串' | stats_auto_recalc [=] {default | 0 | 1} | stats_persistent [=] {default | 0 | 1} | stats_sample_pages [=]价值|表空间tablespace_name[storage {disk | memory}] | union [=] (tbl_name(,tbl_name]…)}partition_options:(参见CREATE TABLE选项)
ALTER TABLE
更改表的结构。例如,您可以添加或删除列,创建或删除索引,更改现有列的类型,或者重命名列或表本身。您还可以更改表使用的存储引擎或表注释等特征。
使用
ALTER TABLE
,你需要改变
,创建
,插入
表的特权。重命名表需要改变
而且下降
在旧桌子上,改变
,创建
,插入
在新桌子上。在表名后面,指定要进行的更改。如果没有给出,
ALTER TABLE
什么也不做。的子句中许多允许的更改的语法与
创建表
声明。column_definition
子句使用相同的语法添加
而且改变
至于创建表
.有关更多信息,请参见第13.1.20节," CREATE TABLE语句".这个词
列
是可选的,可以省略,除了重命名列
的列重命名操作与重命名
table-renaming操作)。多个
添加
,改变
,下降
,改变
单句中允许使用从句ALTER TABLE
语句,以逗号分隔。这是对标准SQL的MySQL扩展,它只允许每个子句中的一个ALTER TABLE
声明。例如,要在一条语句中删除多个列,可以这样做:删除列c,删除列d
如果存储引擎不支持尝试
ALTER TABLE
操作时,可能会产生警告。可以显示此类警告显示警告
.看到第13.7.7.42节,“SHOW WARNINGS声明”.有关故障排除的信息ALTER TABLE
,请参阅B.3.6.1节“ALTER TABLE的问题”.有关已生成列的信息,请参见第13.1.9.2节“ALTER TABLE and Generated column”.
有关使用示例,请参见第13.1.9.3节“ALTER TABLE示例”.
InnoDB
在MySQL 8.0.17和更高版本中支持在JSON列上添加多值索引key_part
说明可以采取形式(投
.看到多值的索引,以了解有关多值索引的创建和使用,以及多值索引的限制和限制的详细信息。json_path
作为类型
数组)与
mysql_info ()
C API函数,你可以找出有多少行被复制ALTER TABLE
.看到mysql_info ().
还有几个额外的方面ALTER TABLE
声明,在本节的下列主题下描述:
表选项
table_options
控件中使用的那种表选项创建表
语句,例如引擎
,AUTO_INCREMENT
,AVG_ROW_LENGTH
,MAX_ROWS
,ROW_FORMAT
,或表空间
.
有关所有表选项的描述,请参见第13.1.20节," CREATE TABLE语句".然而,ALTER TABLE
忽略了数据目录
而且索引目录
当给出表选项时。ALTER TABLE
只允许它们作为分区选项,并要求您具有文件
特权。
表选项的使用ALTER TABLE
提供一种方便的方法来更改单个表的特性。例如:
如果
t1
目前不是InnoDB
表中,此语句将其存储引擎更改为InnoDB
:ALTER TABLE t1 ENGINE = InnoDB;
看到第15.6.1.5节“表从MyISAM转换到InnoDB”类时的注意事项
InnoDB
存储引擎。当您指定
引擎
条款,ALTER TABLE
重新构建表。即使表已经有了指定的存储引擎,这也是正确的。运行
ALTER TABLE
在现有的tbl_name
引擎= INNODBInnoDB
表执行”零”ALTER TABLE
操作,该操作可用于对文件进行碎片整理InnoDB
表中描述的第15.11.4节“整理表碎片”.运行ALTER TABLE
在一个tbl_name
力InnoDB
表执行相同的功能。ALTER TABLE
而且tbl_name
引擎= INNODBALTER TABLE
使用在线DDL.有关更多信息,请参见第15.12节“InnoDB和在线DDL”.tbl_name
力的设置会影响试图更改表的存储引擎的结果
NO_ENGINE_SUBSTITUTION
SQL模式,如第5.1.11节,“Server SQL模式”.为防止意外丢失数据,
ALTER TABLE
不能用于将表的存储引擎更改为合并
或黑洞
.
更改
InnoDB
表使用压缩行存储格式:修改表t1 ROW_FORMAT = COMPRESSED;
的
加密
子句启用或禁用页级数据加密InnoDB
表格必须安装和配置密匙环插件以启用加密。如果
table_encryption_privilege_check
变量,则TABLE_ENCRYPTION_ADMIN
权限使用加密
子句的设置与默认模式加密设置不同。在MySQL 8.0.16之前,
加密
子句仅在修改驻留在每个表文件表空间中的表时支持。从MySQL 8.0.16开始,加密
子句也支持驻留在一般表空间中的表。对于位于一般表空间中的表,表和表空间加密必须匹配。
不允许通过将表移动到不同的表空间或更改存储引擎来更改表加密,除非显式指定
加密
条款。从MySQL 8.0.16开始,指定一个
加密
子句的值不是“N”
或”
如果表使用不支持加密的存储引擎,则不允许。此前,该条款已被接受。正在尝试创建一个没有加密
子句也不允许在使用不支持加密的存储引擎的启用加密的模式中使用。有关更多信息,请参见第15.13节“InnoDB数据静止加密”.
重置当前自动递增值。
修改表t1 AUTO_INCREMENT = 13;
不能将计数器重置为小于或等于当前正在使用的值。对于这两个
InnoDB
而且MyISAM
的值小于或等于当前的最大值AUTO_INCREMENT
列时,该值重置为当前最大值AUTO_INCREMENT
列值加1。更改默认的表字符集。
ALTER TABLE t1 CHARACTER SET = utf8;
另请参阅更改字符集.
添加(或更改)一个表注释:
ALTER TABLE t1 COMMENT = '新表注释';
使用
ALTER TABLE
与表空间
选择移动InnoDB
现有的表之间一般的表空间,file-per-table表空间和系统表空间.看到使用ALTER TABLE在表空间之间移动表.MySQL NDB Cluster 8.0支持设置
NDB_TABLE
控件的表注释的一部分,用于控制表的分区平衡(片段计数类型)、从任意副本读取功能、完全复制或这些功能的任何组合的选项ALTER TABLE
以与for相同的方式陈述创建表
,如下例所示:ALTER TABLE t1 COMMENT = "NDB_TABLE=READ_BACKUP=0,PARTITION_BALANCE=FOR_RA_BY_NODE";
请记住
修改表…发表评论…
丢弃表的任何现有注释。看到设置NDB_TABLE选项,以获取更多信息和示例。ENGINE_ATTRIBUTE
而且SECONDARY_ENGINE_ATTRIBUTE
options(从MySQL 8.0.21开始可用)用于为主存储引擎和辅助存储引擎指定表、列和索引属性。这些选项保留以备将来使用。不能更改索引属性。必须删除索引,并将其添加回所需的更改,这可以在单个索引中执行ALTER TABLE
声明。
要验证表选项是否按预期更改,请使用显示创建表
,或查询INFORMATION_SCHEMA。表
表格
性能和空间要求
ALTER TABLE
操作处理采用以下算法之一:
复制
:在原表的副本上执行操作,并将表数据逐行从原表复制到新表中。不允许并发DML。原地
:操作避免复制表数据,但可能会在原位置重建表。在操作的准备和执行阶段,可以短暂地执行表上的独占元数据锁。通常,支持并发DML。即时
:操作只修改数据字典中的元数据。在准备和执行过程中,表上没有独占元数据锁,表数据不受影响,因此操作是瞬时的。允许并发DML。(在MySQL 8.0.12中引入)
的算法
子句是可选的。如果算法
子句省略,MySQL使用算法=即时
对于存储引擎和ALTER TABLE
支持它的从句。否则,算法=原地
使用。如果算法=原地
不支持,算法=复制
使用。
指定一个算法
子句要求操作对支持它的子句和存储引擎使用指定的算法,否则将失败并出现错误。指定算法=违约
是否等同于省略算法
条款。
ALTER TABLE
的操作复制
算法等待正在修改表的其他操作完成。在对表副本应用更改之后,将复制数据,删除原始表,并将表副本重命名为原始表的名称。而ALTER TABLE
操作执行时,原始表可被其他会话读取(稍后将说明例外情况)。之后开始对表的更新和写入ALTER TABLE
操作开始被暂停,直到新表准备好,然后自动重定向到新表。表的临时副本是在原始表的数据库目录中创建的,除非它是重命名为
将表移动到位于不同目录中的数据库的操作。
前面提到的例外情况是ALTER TABLE
在准备从表和表定义缓存中清除过时的表结构时,阻塞读取(而不仅仅是写入)。此时,它必须获得一个独占锁。为此,它等待当前的读取器完成,并阻塞新的读写。
一个ALTER TABLE
的操作。复制
算法防止并发DML操作。仍然允许并发查询。也就是说,表复制操作总是至少包含的并发限制锁=共享
(允许查询,但不允许DML)。控件支持的操作的并发性还可以进一步限制锁
条款。锁=独家
,它阻止了DML和查询。有关更多信息,请参见并发控制.
强迫使用复制
的算法ALTER TABLE
否则将不使用它的操作,指定算法=复制
或启用old_alter_table
系统变量。如果有冲突old_alter_table
设置和算法
子句的值不是默认的
,算法
子句优先。
为InnoDB
表,一个ALTER TABLE
的操作。复制
对象中的表上的算法共享表空间可以增加表空间使用的空间量。这样的操作需要与表中的数据加上索引一样多的额外空间。对于驻留在共享表空间中的表,操作期间使用的额外空间不会释放回操作系统,就像驻留在共享表空间中的表一样file-per-table表空间。
有关在线DDL操作的空间需求的信息,请参见第15.12.3节“在线DDL空间要求”.
ALTER TABLE
支持原地
算法包括:
ALTER TABLE
由InnoDB
在线DDL特性。看到第15.12.1节“在线DDL操作”.重命名表。MySQL重命名与表对应的文件
tbl_name
不需要复印。(你也可以使用重命名表
语句来重命名表。看到第13.1.36节,“RENAME TABLE语句”)。专门为重命名表授予的特权不会迁移到新名称。它们必须手动更改。只修改表元数据的操作。这些操作是即时的,因为服务器不接触表内容。纯元数据操作包括:
重命名列。NDB Cluster 8.0.18及以上版本也可以在线执行此操作。
更改列的默认值(除
NDB
表)。修改对象的定义
枚举
或集
类中添加新的枚举或集合成员来创建结束的有效成员值列表,只要数据类型的存储大小不变。例如,将成员添加到集
有8个成员的列将每个值所需的存储空间从1字节更改为2字节;这需要一个表副本。在列表中间添加成员会导致对现有成员重新编号,这需要表副本。更改空间列的定义以删除
SRID
属性。(增加或改变SRID
属性确实需要重新构建,并且不能在原地完成,因为服务器必须验证所有值都具有指定的SRID值。)从MySQL 8.0.14开始,当以下条件适用时,更改列字符集:
在MySQL 8.0.14中,当以下条件适用时,更改生成的列:
为
InnoDB
修改生成的存储列但不更改其类型、表达式或可空性的表、语句。为非
InnoDB
修改生成的存储列或虚拟列但不更改其类型、表达式或可空性的表、语句。
此类更改的一个例子是对列注释的更改。
重命名索引。
添加或删除二级索引,for
InnoDB
而且NDB
表。看到第15.12.1节“在线DDL操作”.为
NDB
表,在变宽列上添加和删除索引的操作。这些操作是在线进行的,不需要表复制,也不需要在大部分时间阻塞并发DML操作。看到第23.5.11节“在NDB集群中使用ALTER TABLE进行在线操作”.方法修改索引可见性
改变指数
操作。类的列对包含已生成的列的表的列修改
默认的
值,如果生成的列表达式中没有涉及修改的列。例如,更改零
属性可以在不重新构建表的情况下就地完成。
ALTER TABLE
支持即时
算法包括:
添加列。这个特性被称为”即时
添加一列
”.限制适用。看到第15.12.1节“在线DDL操作”.添加或删除虚拟列。
添加或删除列默认值。
更改索引类型。
重命名表。与上面描述的相同的限制适用于
算法=即时
.
有关支持的操作的详细信息算法=即时
,请参阅第15.12.1节“在线DDL操作”.
ALTER TABLE
升级MySQL 5.5时态列为5.6格式添加一列
,改变列
,修改列
,添加索引
,力
操作。方法无法完成此转换原地
算法,因为表必须重建,所以指定算法=原地
在这些情况下会导致错误。指定算法=复制
如果有必要的话)。
如果一个ALTER TABLE
对用于对表进行分区的多列索引的操作关键
更改列的顺序时,只能使用算法=复制
.
的没有验证
而且与验证
条款影响是否ALTER TABLE
执行原地操作虚拟生成列修改。看到第13.1.9.2节“ALTER TABLE and Generated column”.
NDB Cluster 8.0支持在线操作算法=原地
标准MySQL服务器使用的语法。NDB
不支持在线更改表空间;从NDB 8.0.21开始,它是不允许的。看到第23.5.11节“在NDB集群中使用ALTER TABLE进行在线操作”,以查询更多资料。
ALTER TABLE
与丢弃……分区…表空间
或进口…分区…表空间
不创建任何临时表或临时分区文件。
ALTER TABLE
与添加分区
,删除分区
,合并分区
,重建分区
,或重组分区
不创建临时表(除了与NDB
表);但是,这些操作可以并且确实创建临时分区文件。
添加
或下降
操作范围
或列表
分区是即时操作或近似于即时操作。添加
或合并
操作哈希
或关键
分区在所有分区之间复制数据,除非线性散列
或线性关键
使用;这实际上与创建新表相同,尽管添加
或合并
操作是按分区执行的。重组
操作只复制已更改的分区,不触及未更改的分区。
为MyISAM
表,您可以通过设置索引重新创建(更改过程中最慢的部分)来加速索引的重新创建myisam_sort_buffer_size
系统变量设置为高值。
并发控制
为ALTER TABLE
支持它的操作,可以使用锁
子句在修改表时控制表上的并发读写级别。为该子句指定非默认值使您能够在alter操作期间要求一定数量的并发访问或独占性,并在所请求的锁定程度不可用时停止操作。
只有Lock = default
是否允许使用算法=即时
.另一个锁
子句参数不适用。
的参数锁
条款是:
Lock = default
的最大并发级别
算法
条款(如有)和ALTER TABLE
operation:允许并发读写。如果不支持,则允许并发读。如果不是,强制独占访问。锁= none
如果支持,则允许并发读写。否则,将出现错误。
锁=共享
如果支持,允许并发读,但阻止写。即使给定的存储引擎支持并发写,写入也会被阻塞
算法
条款(如有)和ALTER TABLE
操作。如果不支持并发读取,则会发生错误。锁=排他性
强制独占访问。即使给定的存储引擎支持并发读/写,也会这样做
算法
条款(如有)和ALTER TABLE
操作。
添加和删除列
使用添加
向表中添加新列下降
删除现有列。下降
是对标准SQL的一个MySQL扩展。col_name
若要在表行的特定位置添加列,请使用第一个
或后
.默认是最后添加列。col_name
如果表只包含一个列,则不能删除该列。如果您打算删除表,请使用删除表
语句代替。
如果从表中删除列,则这些列也将从它们所属的任何索引中删除。如果删除组成索引的所有列,则索引也将被删除。如果你使用改变
或修改
如果要缩短列上存在索引的列,并且得到的列长度小于索引长度,MySQL会自动缩短索引。
为修改表…添加
,如果列具有使用非确定性函数的表达式默认值,则该语句可能产生警告或错误。有关更多信息,请参见第11.6节“数据类型默认值”,第17.1.3.7节“gtid复制的限制”.
重命名、重定义和重排序列
的改变
,修改
,重命名列
,改变
子句允许修改现有列的名称和定义。它们具有这些比较特征:
改变
:可以重命名列并更改其定义,或者两者都可以。
能力比
修改
或重命名列
,但牺牲了一些操作的便利性。改变
如果不重命名列,则需要对其命名两次;如果只重命名列,则需要重新指定列定义。与
第一个
或后
,可以重新排列列。
修改
:可以更改列定义,但不能更改列名称。
比
改变
更改列定义而不重命名它。与
第一个
或后
,可以重新排列列。
重命名列
:可以更改列名,但不能更改其定义。
比
改变
在不更改列定义的情况下重命名列。
改变
:仅用于修改列的默认值。
改变
是对标准SQL的一个MySQL扩展。修改
而且重命名列
是MySQL扩展Oracle兼容。
若要更改列以更改其名称和定义,请使用改变
,指定旧的、新的名称和新的定义。例如,重命名Int不为空
列从一个
来b
改变它的定义,使用长整型数字
数据类型,同时保留非空
属性,这样做:
修改表t1的BIGINT NOT NULL;
若要更改列定义但不更改其名称,请使用改变
或修改
.与改变
,该语法需要两个列名,因此必须两次指定相同的名称以保持名称不变。例如,更改列的定义b
,这样做:
修改表t1 INT NOT NULL;
修改
在不更改名称的情况下更改定义更方便,因为它只需要一次列名:
修改表t1 INT NOT NULL;
若要更改列名而不更改其定义,请使用改变
或重命名列
.与改变
,该语法需要列定义,因此要保持定义不变,必须重新指定列当前拥有的定义。例如,重命名Int不为空
列从b
来一个
,这样做:
ALTER TABLE t1 CHANGE b a INT NOT NULL;
重命名列
在不更改定义的情况下更改名称更方便,因为它只需要旧名称和新名称:
将列b重命名为a
通常,不能将列重命名为表中已经存在的名称。然而,有时情况并非如此,例如当您交换名称或在循环中移动名称时。如果一个表有命名的列一个
,b
,c
,这些都是有效的操作:
将表1中的a列重命名为b列,将b列重命名为a列ALTER TABLE t1将列a重命名为b,列b重命名为c,列c重命名为a
用于列定义更改改变
或修改
,定义必须包括数据类型和应应用于新列的所有属性,而不包括索引属性,例如主键
或独特的
.在原始定义中存在但未为新定义指定的属性不会继续使用。假设有一列col1
被定义为'我的列'
然后按以下方式修改该列,只打算更改INT
来长整型数字
:
修改表t1的BIGINT值
该语句将数据类型从INT
来长整型数字
,但它也会下降无符号
,默认的
,评论
属性。为了保留它们,语句必须显式包含它们:
ALTER TABLE t1 MODIFY col1 BIGINT UNSIGNED DEFAULT 1 COMMENT 'my column';
用于数据类型更改改变
或修改
, MySQL尝试将现有的列值尽可能地转换为新类型。
这种转换可能导致数据的更改。例如,如果缩短字符串列,值可能会被截断。如果转换到新数据类型会导致数据丢失,为了防止操作成功,请在使用前启用严格的SQL模式ALTER TABLE
(见第5.1.11节,“Server SQL模式”).
如果你使用改变
或修改
如果要缩短列上存在索引的列,并且得到的列长度小于索引长度,MySQL会自动缩短索引。
对于重命名为改变
或重命名列
, MySQL自动重命名这些引用到重命名的列:
引用旧列的索引,包括不可见的索引和禁用的索引
MyISAM
索引。引用旧列的外键。
对于重命名为改变
或重命名列
, MySQL不会自动重命名这些引用到重命名的列:
生成引用重命名列的列和分区表达式。你必须使用
改变
重新定义这样的表达式ALTER TABLE
语句作为重命名列的语句。引用重命名列的视图和存储程序。您必须手动更改这些对象的定义,以引用新的列名。
若要对表中的列重新排序,请使用第一个
而且后
在改变
或修改
操作。
改变设置默认
或改变降低违约
分别为列指定新的默认值或删除旧的默认值。如果旧的默认值被删除,列可以零
,新的默认值为零
.如果列不能零
, MySQL会指定一个默认值第11.6节“数据类型默认值”.
从MySQL 8.0.23开始,改变组可见
而且改变设置无形的
允许更改列可见性。看到第13.1.20.10节“隐形列”.
主键和索引
删除主键
下降的主键.如果没有主键,则会发生错误。有关主键的性能特征的信息,特别是InnoDB
表,请参阅第8.3.2节“主键优化”.
如果sql_require_primary_key
系统变量已启用,则试图删除主键会产生错误。
如果你添加一个唯一索引
或主键
MySQL将它存储在任何非唯一索引之前,以便尽可能早地检测到重复的键。
指数下降
删除索引。这是对标准SQL的MySQL扩展。看到第13.1.27节“DROP INDEX语句”.要确定索引名称,请使用显示索引
.tbl_name
有些存储引擎允许在创建索引时指定索引类型。的语法index_type
说明符是使用
.有关详情type_name
使用
,请参阅第13.1.15节“CREATE INDEX语句”.首选位置是列列表之后。期望在将来的MySQL版本中删除列列表之前支持使用该选项。
index_option
值指定索引的其他选项。使用
就是这样一种选择。有关允许的详情index_option
值,请参阅第13.1.15节“CREATE INDEX语句”.
重命名索引
重命名索引。这是对标准SQL的MySQL扩展。表的内容保持不变。old_index_name
来new_index_name
old_index_name
必须是表中没有被相同索引删除的现有索引的名称ALTER TABLE
声明。new_index_name
是新的索引名称,在应用更改后,该名称不能复制结果表中的索引名称。两个索引名都不能主要的
.
如果你使用ALTER TABLE
在一个MyISAM
表中,所有非唯一索引都在单独的批处理中创建(如修理表
).这应该使ALTER TABLE
当你有很多索引时,速度会更快。
为MyISAM
表、键更新可以显式控制。使用修改表…禁用的钥匙
告诉MySQL停止更新非唯一索引。然后使用修改表…启用钥匙
重新创建丢失的索引。MyISAM
使用一种比逐个插入键要快得多的特殊算法来实现这一点,因此在执行批量插入操作之前禁用键应该会带来相当大的加速。使用修改表…禁用的钥匙
要求指数
除了前面提到的特权之外的其他特权。
后一个ALTER TABLE
语句,则可能需要运行该语句分析表
更新索引基数信息。看到第13.7.7.22节,“SHOW INDEX语句”.
的改变指数
操作允许索引可见或不可见。优化器不使用不可见索引。修改索引可见性适用于主键以外的索引(显式或隐式)。该特性与存储引擎无关(支持任何引擎)。有关更多信息,请参见第8.3.12节“隐形索引”.
外键和其他约束
的外键
而且参考文献
子句由InnoDB
而且NDB
存储引擎,实现添加[约束]
.看到第13.1.20.5节,“外键约束”.对于其他存储引擎,将解析子句,但忽略该子句。象征
]]外键[index_name
)(…)参考文献(…)
为ALTER TABLE
,不像创建表
,添加外键
忽略了index_name
如果给出并使用自动生成的外键名。作为一种变通方法,请包括约束
子句来指定外键名:
添加约束的名字外键(....)…
MySQL静默忽略内联参考文献
规范,其中引用被定义为列规范的一部分。MySQL只接受参考文献
子句定义为单独的一部分外键
规范。
分区InnoDB
表不支持外键。此限制不适用于NDB
表,包括显式分区由(线性)的关键
.有关更多信息,请参见第24.6.2节,“与存储引擎相关的分区限制”.
MySQL服务器和NDB集群都支持使用ALTER TABLE
删除外键。
ALTER TABLEtbl_name删除外键fk_symbol;
在同一空间中添加和删除外键ALTER TABLE
语句的支持修改表…算法=原地
但不是为了修改表…算法=复制
.
服务器禁止对可能导致引用完整性丢失的外键列的更改。一个变通方法就是使用修改表…删除外键
在更改列定义和修改表…添加外键
之后。禁止更改的例子包括:
对可能不安全的外键列的数据类型的更改。例如,改变
VARCHAR (20)
来VARCHAR (30)
是允许的,但是更改为VARCHAR (1024)
不是因为这会改变存储单个值所需的长度字节数。改变一个
零
列非空
在非严格模式下禁止转换零
值默认为非零
值,在引用的表中没有相应的值。该操作在严格模式下是允许的,但是如果需要任何这样的转换,则返回一个错误。
ALTER TABLE
更改内部生成的以字符串开头的外键约束名称和用户定义的外键约束名称”tbl_name
重命名new_tbl_name
tbl_name
_ibfk_”以反映新的表名。InnoDB
解释以字符串开头的外键约束名称”tbl_name
_ibfk_”作为内部生成的名称。
在MySQL 8.0.16之前,ALTER TABLE
只允许以下有限版本的检查
约束添加语法,它被解析并忽略:
添加校验(expr)
从MySQL 8.0.16开始,ALTER TABLE
许可证检查
添加、删除或修改现有表的约束条件:
添加一个新的
检查
约束:ALTER TABLEtbl_name增加约束[象征支票,支票expr)[[未]强制的];
约束语法元素的含义与for相同
创建表
.看到第13.1.20.6节,“检查约束”.删除现有的
检查
约束条件为象征
:ALTER TABLEtbl_name检查下降象征;
更改现有的
检查
约束条件为象征
执行:ALTER TABLEtbl_name改变检查象征[不]执行;
的检查下降
而且改变检查
子句是对标准SQL的MySQL扩展。
从MySQL 8.0.19开始,ALTER TABLE
允许使用更通用的(和SQL标准的)语法来删除和更改任何类型的现有约束,其中约束类型由约束名称确定:
删除已存在的名为
象征
:ALTER TABLEtbl_name下降的约束象征;
如果
sql_require_primary_key
系统变量已启用,则试图删除主键会产生错误。更改现有的约束是否命名为
象征
执行:ALTER TABLEtbl_name改变约束象征[不]执行;
只有
检查
可以将约束更改为不强制。所有其他约束类型都是强制的。
SQL标准指定所有类型的约束(主键、惟一索引、外键、检查)都属于同一个名称空间。在MySQL中,每个模式的每个约束类型都有自己的命名空间。因此,每种类型的约束的名称在每个模式中必须是唯一的,但是不同类型的约束可以有相同的名称。当多个约束具有相同的名称时,下降的约束
而且添加约束
是不明确的,会发生错误。在这种情况下,必须使用特定于约束的语法来修改约束。例如,使用删除主键
或DROP FOREIGN KEY删除主键或外键。
如果表更改导致违反强制的检查
约束时,会发生错误,而表不会被修改。发生错误的操作示例:
尝试添加
AUTO_INCREMENT
属性中使用的列检查
约束。试图添加强制的
检查
约束或强制一个非强制的检查
约束,其中现有行违反约束条件。控件中使用的列试图修改、重命名或删除
检查
约束,除非该约束也在同一语句中被删除。例外:如果检查
约束仅引用单个列,删除列将自动删除约束。
ALTER TABLE
内部生成和用户定义的更改tbl_name
重命名new_tbl_name
检查
以字符串开头的约束名称”tbl_name
_chk_”以反映新的表名。MySQL解释检查
以字符串开头的约束名称”tbl_name
_chk_”作为内部生成的名称。
更改字符集
更改表默认字符集和所有字符列(字符
,VARCHAR
,文本
)到一个新的字符集,使用如下语句:
ALTER TABLEtbl_name转换为字符集charset_name;
该语句还更改了所有字符列的排序规则。如果指定no核对
子句指示要使用哪种排序规则,则该语句对字符集使用默认排序规则。如果此排序规则不适合预期的表使用(例如,如果它将从区分大小写的排序规则更改为不区分大小写的排序规则),则显式指定一个排序规则。
对于数据类型为的列VARCHAR
或者其中一个文本
类型,转换为字符集
根据需要更改数据类型,以确保新列足够长,能够存储与原始列一样多的字符。例如,文本
列有两个长度字节,用于存储列中值的字节长度,最大值为65,535。对于一个latin1
文本
列,每个字符需要一个字节,因此列最多可以存储65,535个字符。如果将列转换为use utf8
,每个字符可能需要3个字节,最大可能的长度为3 × 65,535 = 196,605字节。这个长度不适合文本
列的长度字节,因此MySQL将数据类型转换为简单
,这是长度字节可以记录196,605值的最小字符串类型。同样,一个VARCHAR
列可以转换为简单
.
为避免更改刚才描述的类型的数据类型,请不要使用转换为字符集
.相反,使用修改
更改单个列。例如:
修改latin1_text_col文本字符集utf8;修改表VARCHAR表米)字符集utf8;
如果你指定转换为字符集二进制
,字符
,VARCHAR
,文本
列被转换为相应的二进制字符串类型(二进制
,VARBINARY
,团
).这意味着列不再有字符集和后续字符集转换为
操作不适用于它们。
如果charset_name
是默认的
在一个转换为字符集
方法命名的字符集character_set_database
使用系统变量。
的转换为
操作在原始字符集和命名字符集之间转换列值。这是不如果您在一个字符集中有一个列(比如latin1
),但是存储的值实际上使用了其他一些不兼容的字符集(比如use utf8
).在这种情况下,您必须对每个这样的列执行以下操作:
ALTER TABLE t1 CHANGE c1 c1 BLOBALTER TABLE t1 CHANGE c1 TEXT CHARACTER SET utf8
这样做的原因是,当您转换到或从时,没有转换团
列。
只更改默认的表的字符集,使用以下语句:
ALTER TABLEtbl_name默认字符集charset_name;
这个词默认的
是可选的。默认字符集是如果您没有为以后添加到表中的列指定字符集(例如,与修改表…添加一列
).
当foreign_key_checks
系统变量已启用,这是默认设置,不允许在包含外键约束中使用的字符串列的表上进行字符集转换。解决方法是禁用foreign_key_checks
在执行字符集转换之前。在重新启用外键约束之前,必须对涉及到的两个表执行转换foreign_key_checks
.如果你重新启用foreign_key_checks
在转换了其中一个表之后,一个删除级联
或更新级联
操作可能会损坏引用表中的数据,因为在这些操作期间发生了隐式转换(Bug #45290, Bug #74816)。
导入InnoDB表
一个InnoDB
表自己创建file-per-table表空间可以从备份或从另一个MySQL服务器实例导入丢弃TABLEPACE
而且导入表空间
条款。看到第15.6.1.3节“导入InnoDB表”.
MyISAM表的行顺序
命令
允许您以特定的顺序创建新表。当您知道大部分时间都是按一定顺序查询行时,此选项主要是有用的。通过在对表进行重大更改之后使用此选项,您可能能够获得更高的性能。在某些情况下,如果表按照您稍后希望对其排序的列排序,那么对MySQL来说排序可能会更容易。
在插入和删除之后,表不会保持指定的顺序。
命令
语法允许指定一个或多个列名进行排序,每个列名后面可选地跟随ASC
或DESC
分别表示升序或降序排序。默认为升序。只允许列名作为排序标准;随意表达是不允许的。这一条款应放在其他条款的最后。
命令
没有意义吗InnoDB
表,因为InnoDB
的顺序对表行进行排序聚集索引.
在分区表上使用时,修改表…命令
只对每个分区中的行排序。
分区选项
partition_options
表示可与已分区表一起用于重新分区、添加、删除、丢弃、导入、合并和分割分区以及执行分区维护的选项。
这是可能的ALTER TABLE
语句来包含分区的
或删除分区
子句添加到其他修改规范中,但是分区的
或删除分区
子句必须在任何其他规格之后指定。的添加分区
,删除分区
,丢弃分区
,进口分区
,合并分区
,重组分区
,交换分区
,分析分区
,检查分区
,修复分区
选项不能与其他alter规范组合在一起ALTER TABLE
,因为刚刚列出的选项作用于单独的分区。
有关分区选项的更多信息,请参见第13.1.20节," CREATE TABLE语句",第13.1.9.1节“ALTER TABLE Partition Operations”.的信息和示例修改表…交换分区
语句,看到第24.3.3节“与表交换分区和子分区”.