添加和删除列
使用ADD向表中添加新列,使用DROP删除现有列。DROP col_name是对标准SQL的MySQL扩展。
若要在表行的特定位置添加列,请使用FIRST col_name 或者 AFTER col_name。默认情况是添加到最后。
如果表只包含一列,则不能删除该列。如果您想要删除表,请使用DROP TABLE语句。
如果从表中删除列,那么列也将从其所属的任何索引中删除。如果组成一个索引的所有列都被删除,那么这个索引也会被删除。如果使用CHANGE或MODIFY缩短存在索引的列,而结果列长度小于索引长度,MySQL会自动缩短索引。
对于ALTER TABLE ... ADD,如果列具有使用非确定性函数的表达式默认值,则语句可能会产生警告或错误。
重命名、重新定义和重新排序列
CHANGE、MODIFY、RENAME COLUMN 和 ALTER子句允许更改现有列的名称和定义。它们具有以下比较特征:
●CHANGE:
■ 可以重命名列并更改其定义。
■ 具有比MODIFY、RENAME COLUMN更多的功能,但以牺牲某些操作的便利性为代价。如果不重命名,CHANGE 需要对列进行两次命名,如果只重命名,则需要重新指定列定义。
■ 使用FIRST或AFTER,可以对列重新排序。
●MODIFY:
■ 可以更改列定义,但不能更改列的名称。
■ 更改列定义而不重命名比 CHANGE 更方便。
■ 使用FIRST或AFTER,可以对列重新排序。
●RENAME COLUMN:
■ 可以更改列名,但不能更改其定义。
■ 在不更改列定义的情况下重命名列比CHANGE更方便。
●ALTER:仅用于更改列的默认值。
CHANGE是对标准SQL的MySQL扩展。MODIFY和RENAME COLUMN是用于Oracle兼容性的MySQL扩展。
若要更改列名称和定义,请使用CHANGE,指定新旧名称和新定义。例如,要将一个INT NOT NULL列从a重命名为b,并更改其定义为使用BIGINT数据类型,同时保留NOT NULL属性,请这样做:
若要更改列定义但不更改其名称,请使用CHANGE或MODIFY。使用CHANGE,语法需要两个列名,因此必须两次指定相同的名称才能保持名称不变。例如,要更改b列的定义,可以这样做:
MODIFY更方便在不改变名称的情况下改变定义,因为它只需要列名一次:
若要更改列名,但不更改其定义,请使用CHANGE或RENAME COLUMN。对于CHANGE,语法需要列定义,因此要保持定义不变,必须重新指定列当前具有的定义。例如,要将一个INT NOT NULL列从b重命名为a,请这样做:
RENAME COLUMN更方便在不改变定义的情况下更改名称,因为它只需要新旧名称:
通常,不能将列重命名为表中已经存在的名称。但是,有时情况并非如此,比如交换名称或在循环中移动名称。如果一个表有名为a、b和c的列,这些是有效的操作:
对于使用CHANGE或MODIFY进行的列定义更改,定义必须包括数据类型和应该应用于新列的所有属性,而不是索引属性(如PRIMARY KEY 或 UNIQUE)。原始定义中出现但未为新定义指定的属性将不进行继承。假设一个列col1被定义为INT UNSIGNED DEFAULT 1 COMMENT 'my column',然后你按照如下方式修改该列,只打算将INT改为BIGINT:
该语句将数据类型从INT更改为BIGINT,但也删除了UNSIGNED、DEFAULT和COMMENT属性。为了保留它们,语句必须明确地包含它们:
对于使用CHANGE或MODIFY更改数据类型,MySQL尝试将现有的列值尽可能转换为新的类型。
警告
这种转换可能会导致数据的更改。例如,如果缩短字符串列,值可能会被截断。如果转换到新的数据类型会导致数据丢失,为了防止操作成功,请在使用ALTER TABLE之前启用严格SQL模式。
如果使用CHANGE或MODIFY缩短存在索引的列,而结果列长度小于索引长度,MySQL会自动缩短索引。
对于通过CHANGE或RENAME COLUMN重命名的列,MySQL自动将这些引用重命名为重命名列:
●引用旧列的索引,包括不可见的索引和禁用的MyISAM索引。
●引用旧列的外键。
对于通过CHANGE或RENAME COLUMN重命名的列,MySQL不会自动将这些引用重命名为重命名列:
●引用重命名列的生成列和分区表达式。必须如同ALTER TABLE语句中一样,使用CHANGE重新定义这些表达式。
●引用重命名列的视图和存储程序。必须手动更改这些对象的定义以引用新的列名。
若要对表中的列重新排序,请在CHANGE或MODIFY操作中使用FIRST和AFTER。
ALTER ... SET DEFAULT 或 ALTER ... DROP DEFAULT分别为列指定新的默认值或删除旧的默认值。如果旧的默认值被删除,并且列可以为NULL,那么新默认值为NULL。如果列不能为NULL, MySQL会分配一个默认值。
主键和索引
DROP PRIMARY KEY删除主键。如果没有主键,就会发生错误。
如果启用了sql_require_primary_key系统变量,尝试删除主键会产生错误。
如果在表中添加UNIQUE INDEX 或 PRIMARY KEY,MySQL会将其存储在任何非唯一索引之前,以便尽早检测重复键。
DROP INDEX删除索引。这是对标准SQL的MySQL扩展。要确定索引名称,请使用SHOW INDEX FROM tbl_name。
有些存储引擎允许在创建索引时指定索引类型。index_type说明符的语法是USING type_name。首选位置在列列表之后。在以后的MySQL版本中,将不再支持使用列列表之前的选项。
index_option值指定索引的其他选项。USING就是这样一个选项。
RENAME INDEX old_index_name TO new_index_name 重命名索引。这是对标准SQL的MySQL扩展。表的内容保持不变。old_index_name必须是表中未被ALTER TABLE语句删除的现有索引的名称。new_index_name是新的索引名,在应用了更改之后,它不能在结果表中索引名重复。两个索引名都不能是PRIMARY。
如果在MyISAM表上使用ALTER TABLE,那么将在单独的批处理中创建所有非惟一索引(如同REPAIR TABLE)。当有很多索引时,这会使ALTER TABLE更快。
对于MyISAM表,可以显式地控制键更新。使用ALTER TABLE ... DISABLE KEYS告诉MySQL停止更新非唯一索引。然后使用ALTER TABLE ... ENABLE KEYS 来重新创建丢失的索引。MyISAM使用一种特殊的算法来实现这一点,这种算法比逐个插入键要快得多,因此在执行批量插入操作之前禁用键应该会有相当大的速度提高。使用ALTER TABLE ... DISABLE KEYS除了前面提到的权限外,还需要INDEX权限。
虽然禁用了非惟一索引,但是对于SELECT和EXPLAIN等语句,它们会被忽略,否则它们将使用这些索引。
在使用ALTER TABLE语句之后,可能需要运行ANALYZE TABLE来更新索引基数信息。
ALTER INDEX操作允许将索引变为可见或不可见。优化器不使用不可见索引。索引可见性的修改适用于主键以外的索引(显式或隐式)。该特性与存储引擎无关(支持任何引擎)。