MySql Alter Table

Drop Column:

alter table icecream drop column flavor ;

Drop Column is used to remove an entire column and all its data from a table.
Add Column:

alter table icecream add column flavor varchar (20) ;

Add Column is used to add a column to your existing table.
Change:

alter table icecream change taste flavor varchar (10) ;

Change is used to change the column name. In our example it changes "taste" to be "flavor".
Add Unique:

alter table icecream add unique (quantity)

Add unique adds a new column to your table only if it does not already exist.
Modify:

alter table icecream modify flavor VARCHAR(35) ;

Modify is used to change a column's size. In our example we increase the size of the "flavor" column to 35 characters.

MySQL官方参考手册 - ALTER TABLE语法

以下通过命令行说明:

这里是一个例子,显示了一些ALTER TABLE用法。我们以一个如下创建的表t1开始:

mysql> CREATE TABLE t1 (a INTEGER,b CHAR(10));

重命名表,从t1到t2:

mysql> ALTER TABLE t1 RENAME t2;

为了改变列a,从INTEGER改为TINYINT NOT NULL(名字一样),并且改变列b,从CHAR(10)改为CHAR(20),同时重命名它,从b改为c:

mysql> ALTER TABLE t2 MODIFY a TINYINT NOT NULL, CHANGE b c CHAR(20);

增加一个新TIMESTAMP列,名为d:

mysql> ALTER TABLE t2 ADD d TIMESTAMP;

在列d上增加一个索引,并且使列a为主键:

mysql> ALTER TABLE t2 ADD INDEX (d), ADD PRIMARY KEY (a);

删出列c:

mysql> ALTER TABLE t2 DROP COLUMN c;

增加一个新的AUTO_INCREMENT整数列,命名为c:

mysql> ALTER TABLE t2 ADD c INT UNSIGNED NOT NULL AUTO_INCREMENT,
ADD INDEX (c);

注意,我们索引了c,因为AUTO_INCREMENT柱必须被索引,并且另外我们声明c为NOT NULL,因为索引了的列不能是NULL。

当你增加一个AUTO_INCREMENT列时,自动地用顺序数字填入列值。

参考资料一:

Mysql ALTER TABLE 句法 6.5.4 ALTER TABLE 句法 
添加唯一
ALTER table justmusic add unique (musicsource)


ALTER TABLE 允许你改变一个现有表的结构。例如,你可以添加或删除列,创建或撤销索引,更改现有列的类型或将列或表自身更名。你也可以改变表的注释和表的类型。查看章节 6.5.3 CREATE TABLE 句法。 

如果你使用 ALTER TABLE 来改变一个列规约,但是 DESCRIBE tbl_name 显示你的列并没有被修改,这有可能是因为章节 6.5.3.1 隐式的列定义变化 描述的一个原因,使 MySQL 忽略了你的修改。例如,如果你尝试将一个 VARCHAR 列更改为 CHAR,而如果在这个表中包含其它的变长列,MySQL 将仍然使用 VARCHAR。 

ALTER TABLE 通过建立原初表的一个临时副本来工作。更改在副本上执行,然后原初表将被删除,临时表被换名。这样做使所有的修改自动地转向到没有任何更新失败的新表。当 ALTER TABLE 执行时,原初表可被其它客户端读取。更新与写入被延迟到新的表准备好。 

注意,如果你以除 RENAME 之外的其它选项使用 ALTER TABLE ,MySQL 将总是创建一个临时表,即使数据并不确实需要被复制(就像当你改变一个列名时)。我们计划不久来修正它,但是通常人们是不经常执行 ALTER TABLE的,所以在我们的 TODO 上,这个修正并不是急于处理的。对于 MyISAM 表,你可以将变量 myisam_sort_buffer_size 设置和高一点,以加速索引的重建部分(这是重建进程中最慢的部分)。 

为了使用 ALTER TABLE,你需要在这个表上有 ALTER、INSERT 和 CREATE 权限。 

IGNORE 是 MySQL 对 ANSI SQL92 的扩展。它用于控制当在新表中的唯一键上出现重复值时,ALTER TABLE 如何工作。如果 IGNORE 没有被指定,副本将被放弃并回退。如果 IGNORE 被指定,那么在唯一键上重复的记录行只有第一个记录行被使用;其它的均被删除。 

你可以在单个的 ALTER TABLE 语句中发出多个 ADD、ALTER、DROP 和 CHANGE 子句。这是 MySQL 对 ANSI SQL92 的扩展,ANSI SQL92 只允许在每个 ALTER TABLE 语句中一个子句。 

CHANGE col_name、DROP col_name 和 DROP INDEX 是 MySQL 对 ANSI SQL92 的扩展。 

MODIFY is an Oracle extension to ALTER TABLE. 
可选词 COLUMN 只是一个无用词组,可被忽略。 

如果你使用 ALTER TABLE tbl_name RENAME TO new_name,并没有任何其它的选项,MySQL 将简单地重命名与表 tbl_name 的文件。这不需要创建临时表。查看章节 6.5.5 RENAME TABLE 句法。 

create_definition 子句使用与 CREATE TABLE 相同的 ADD 和 CHANGE 句法。注意,这些句法不仅包含列类型,还要包含列名。查看章节 6.5.3 CREATE TABLE 句法。 

你可以使用一个 CHANGE old_col_name create_definition 子句来重命名一个列。为了这样做,你必须指定旧的和新的列名,以及列当前的类型。例如,为了将一个 INTEGER 列 a 重命名为 b,你必须这样做: 
mysql> ALTER TABLE t1 CHANGE a b INTEGER; 

如果你希望改变一个列的类型而不是列名,CHANGE 句法仍然需要有两个列名,即使它们是一样的。例如: 
mysql> ALTER TABLE t1 CHANGE b b BIGINT NOT NULL; 

然后,到 MySQL 3.22.16a 时,你也可以使用 MODIFY 来改变一个列的类型而不需要重命名它: 
mysql> ALTER TABLE t1 MODIFY b BIGINT NOT NULL; 

如果你使用 CHANGE 或 MODIFY 缩短一个列,而该列上存在一个取列部分值的索引(举例来说,如果你有一个索引在一个 VARCHAR 列的前 10 个字符上),那么,你将不能使列短于索引的字符数目。 

当你使用 CHANGE 或 MODIFY 改变一个列类型时,MySQL 将尝试尽可能地将数据转换到新的类型。 

在 MySQL 3.22 或更新的版本中,你可以使用 FIRST 或 ADD ... AFTER col_name 在一个表中的某个特定位置添加一列。缺省是增加到最后一列。从 MySQL 4.0.1 开始,你也可以在 CHANGE 或 MODIFY 中使用关键词 FIRST 和 AFTER 。 

ALTER COLUMN 可以为一列指定一个新的缺省值或删除老的缺省值。如果老的缺省值被移除且列可以被设为 NULL,新的缺省值将是 NULL。如果该列不允许有 NULL值,MySQL 以章节 6.5.3 CREATE TABLE 句法 中的描述方式为该列赋于一个缺省值。 

DROP INDEX 移除一个索引。这是 MySQL 对 ANSI SQL92 的一个扩展。查看章节 6.5.8 DROP INDEX 句法。 

如果列被从一个表中移除,列也将从任何有它为组成部分的索引中被移除。如果组成一个索引的所有列均被移除了,那么,该索引也将被移除。 

如果一个表只包含一个列,那么该列不能被移除。如果你本就打算移除该表,请使用 DROP TABLE 代替。 

DROP PRIMARY KEY 移除主索引。如果这样的索引不存在,它将移除表中的第一个 UNIQUE 索引。(如果没有 PRIMARY KEY 被明确指定,MySQL 将第一个 UNIQUE 键标记为 PRIMARY KEY ) 如果你添加一个 UNIQUE INDEX 或 PRIMARY KEY 到一个表中,它将被存储在任何非 UNIQUE 索引之前,因而,MySQL 可以尽可能地检测出重复键。 

ORDER BY 允许你以指定的记录行顺序创建一个新表。注意,在插入与删除后,该表将不会保留这个顺序。在某些情况下,如果表在你以后希望排序的列上是有序的,这将使得 MySQL 排序时更加得容易。当你知道你主要查询的行以一个确定的次序时,这将是很有用的。在对表进行过大的改变后,通过使用这个选项,你可能会得到更高的性能。 

如果你在一个 MyISAM 表上使用 ALTER TABLE ,所有非唯一的索引将以一个分批方式创建(就像 REPAIR 一样)。当你有很多索引时,这可能使 ALTER TABLE 更快一点。 

从 MySQL 4.0 开始,上面的特性可明确地激活。ALTER TABLE ... DISABLE KEYS 使 MySQL 停止更新 MyISAM 表的非唯一索引。然后 ALTER TABLE ... ENABLE KEYS 可以被用来重建丢失的索引。因为 MySQL 以特殊的算法执行它,这将比一个接一个地插入索引要快得多,禁用键可以很大程序上的加速一个大批量的插入。 

使用 C API 函数 mysql_info(),你可以找出有多少记录被拷贝,以及(当 IGNORE 被使用时)有多少记录因唯一键值重复而被删除。 

FOREIGN KEY、CHECK 和 REFERENCES 子句实际上不做任何事情,除了对于 InnoDB 类型的表,它支持 ADD CONSTRAINT FOREIGN KEY (...) REFERENCES ... (...)。注意,InnoDB 不允许一个 index_name 被指定。查看章节 7.5 InnoDB 表。对于其它类型的表,这个句法仅仅为了兼容而提供,以更容易地从其它 SQL 服务器移植代码和更容易地运行以引用创建表的应用程序。查看章节 1.8.4 MySQL 与 ANSI SQL92 相比不同的差别。 
这里是一个例子,显示了 ALTER TABLE 的一些用法。我们以一个按如下方式创建一个表 t1 开始: 

mysql> CREATE TABLE t1 (a INTEGER,b CHAR(10)); 

为了将表 t1 重命名为 t2: 

mysql> ALTER TABLE t1 RENAME t2; 

为了将列 a 从 INTEGER 改变为 TINYINT NOT NULL(列名不变),并将列 b 从 CHAR(10) 改变为 CHAR(20) ,同时也将 b 重命名为 c: 

mysql> ALTER TABLE t2 MODIFY a TINYINT NOT NULL, CHANGE b c CHAR(20); 

添加一个名为 d 的 TIMESTAMP c列: 

mysql>

ALTER TABLE t2 ADD d TIMESTAMP; 

在列 d 上增加一个索引,将列 a 设为主键: 

mysql> ALTER TABLE t2 ADD INDEX (d), ADD PRIMARY KEY (a); 

移除列 c: 

mysql> ALTER TABLE t2 DROP COLUMN c; 

添加一个名为 c 的 AUTO_INCREMENT 整型列: 

mysql> ALTER TABLE t2 ADD c INT UNSIGNED NOT NULL AUTO_INCREMENT, 
ADD INDEX (c); 

注意,我们索引了 c,因为 AUTO_INCREMENT 列必须被索引,同样我们声明列 c 为 NOT NULL,因为被索引的列不能有 NULL。 

当你添加一个 AUTO_INCREMENT 列时,列值会自动地以序列值填充。通过在 ALTER TABLE 或使用 AUTO_INCREMENT = # 表选项之前执行 SET INSERT_ID=# ,你可以设置第一个序列数字。查看章节 5.5.6 SET 句法。 

对于 MyISAM 表,如果你不改变 AUTO_INCREMENT 列,序列值将不会被影响。如果你移除一个AUTO_INCREMENT 列,并添加另一个 AUTO_INCREMENT 列,值将再次从 1 开始。

参考资料二:

  ALTER TABLE 通过更改、添加、除去列和约束,或者通过启用或禁用约束和触发器来更改表的定义。
  它有好几种子形式:
  ADD COLUMN
  这种形式用和 CREATE TABLE 里一样的语法向表中增加一个新的字段。
  DROP COLUMN
  这种形式从表中删除一个字段。请注意,和这个字段相关的索引和表约束也会被自动删除。 如果任何表之外的对象依赖于这个字段, 你必须说 CASCADE,比如,外键参考,视图等等。
  ALTER COLUMN TYPE
  这种类型改变表中一个字段的类型。该字段涉及的索引和简单的表约束将被自动地转换为使用新的字段类型, 方法是重新分析最初提供的表达式。可选的 USING 子句声明如何从旧的字段值里计算新的字段值; 如果省略,那么缺省的转换就是从旧类型向新类型的赋值转换。如果从旧数据类型到新类型没有隐含或者赋值的转换, 那么必须提供一个 USING。
  SET/DROP DEFAULT
  这种形式为一个字段设置或者删除缺省值。请注意缺省值只应用于随后的 INSERT 命令; 它们不会导致已经在表中的行的数值的修改。我们也可以为视图创建缺省, 这个时候它们是在视图的 ON INSERT 规则应用之前插入 INSERT 语句中去的。
  SET/DROP NOT NULL
  这些形式修改一个字段是否标记为允许 NULL 值或者是拒绝 NULL 值。 如果表在字段中包含非空值,那么你只可以 SET NOT NULL。
  SET STATISTICS
  这个形式为随后的 ANALYZE 操作设置每字段的统计收集目标(default_statistics_target)。 目标的范围可以在 0 到 1000 之内设置;另外,把他设置为 -1 则表示重新恢复到使用系统缺省的统计目标。 有关 PostgreSQL 查询规划器使用的统计信息的更多信息,
  SET STORAGE
  这种形式为一个字段设置存储模式。这个设置控制这个字段是内联保存还是保存在一个附属的表里,以及数据是否要压缩。 PLAIN 必需用于定长的数值,比如 integer,并且是内联的,不压缩的。 MAIN 用于内联,可压缩的数据。 EXTERNAL 用于外部保存,不压缩的数据, 而 EXTENDED 用于外部的压缩数据。 EXTENDED 是大多数支持非 PLAIN 存储的数据之缺省。 使用 EXTERNAL 将令在 text 字段上的子字串操作更快, 付出的代价是增加了存储空间。 请注意 SET STORAGE 本身并不改变表上的任何东西, 只是设置将来的表操作时,建议使用的策略。
  ADD TABLE_CONSTRAINT
  这个形式给表增加一个新的约束,用的语法和 CREATE TABLE 一样。
  DROP CONSTRAINT
  这个形式删除一个表上的约束。 目前,在表上的约束不要求有唯一的名字,因此可能有多个约束匹配声明的名字。 所有这样的约束都将被删除。
  CLUSTER
  这种形式为将来的 CLUSTER 选项选择缺省索引。它实际上并不重新对表建簇。
  SET WITHOUT CLUSTER
  这种形式从表中删除最新使用的 CLUSTER 索引。 这样会影响将来那些没有声明索引的建簇操作。
  SET WITHOUT OIDS
  这种形式从表中删除 oid 系统字段。 它和 DROP COLUMN oid RESTRICT 完全相同, 只不过是如果表上已经没有 oid 字段了,那么它不会报告错误。
  请注意,不存在某种 ALTER TABLE 的变种可以在删除了 OID 之后再把它们恢复回来。
  OWNER
  这个形式改变表,索引,序列或者视图的所有者为指定所有者。
  SET TABLESPACE
  这种形式把表的表空间修改为指定的表空间并且把与表相关的数据文件移动到新的表空间去。 如果在表上呦索引,则不会移动。但是他们可以通过额外的 SET TABLESPACE 命令移动。参阅 CREATE TABLESPACE。
  RENAME
  RENAME 形式改变一个表(或者一个索引,序列,或者视图)的名字, 或者是表中独立字段的名字。它们对存储的数据没有影响。
  除了 RENAME 之外所有动作都可以捆绑再一个多次修改的列表中同时施用。 比如,我们可以在一个命令里增加几个字段和/或修改几个字段的类型。 对于大表,这么做特别有用,因为只需要对该表做一次处理。
  要使用 ALTER TABLE,你必需拥有该表; 除了 ALTER TABLE OWNER 之外,它只能由超级用户执行。

参数

  table
  试图更改的现存表(可能有模式修饰)的名称。 如果声明了 ONLY,则只更改该表。 如果没有声明 ONLY,则该表及其所有后代表(如果有)都被更新。 我们可以在表名字后面附加一个 * 表示后代表都被扫描,但是在目前的版本里,这是缺省行为。 (在7.1之前的版本,ONLY 是缺省的行为。)缺省可以通过改变配置选项 sql_inheritance 来改变。
  column
  现存或新的字段名称。
  new_column
  现存字段的新名称。
  new_name
  表的新名称。
  type
  新字段的类型,或者现存字段的新类型。
  table_constraint
  表的新的约束定义。
  constraint_name
  要删除的现有约束的名字。
  index_name
  要标记为建簇的表上面的索引名字。
  CASCADE
  自动删除依赖于被依赖字段或者约束的对象(比如,引用该字段的视图)。
  RESTRICT
  如果字段或者约束还有任何依赖的对象,则拒绝删除该字段。 这是缺省行为。
  new_owner
  该表的新所有者的用户名。
  tablespace_name
  这个表将要移动往的表空间名字。

注意

  COLUMN 关键字是多余的,可以省略。
  如果用 ADD COLUMN 增加一个字段,那么所有表中现有行都初始化为该字段的缺省值 (如果没有声明 DEFAULT 子句,那么就是 NULL)。
  用一个非空缺省增加一个字段或者是改变一个字段的现有类型会要求整个表的重写。 对于大表来说,这个操作可能会花很长时间;并且它还临时需要两倍的磁盘空间。
  增加一个 CHECK 或者 NOT NULL 约束要求扫描该表以保证现有的行复合约束要求。
  提供在一个 ALTER TABLE 里面声明多个修改的主要原因是原先需要的对表的多次扫描和重写可以组合成一个回合。
  DROP COLUMN 命令并不是物理上把字段删除, 而只是简单地把它标记为 SQL 操作中不可见的。随后对该表的插入和更新将在该字段存储一个 NULL。 因此,删除一个字段是很快的,但是它不会立即缩减你的表在磁盘上的大小,因为被删除了的字段占据的空间还没有回收。 这些空间将随着现有的行的更新而得到回收。
  ALTER TYPE 要求重写整个表的特性有时候是一个优点, 因为重写的过程消除了任何表中的没用的空间。比如,要想立刻回收被一个已经删除的字段占据的空间, 最快的方法是:
  ALTER TABLE table ALTER COLUMN anycol TYPE anytype;
  这里 anycol 是任何在表中还存在的字段,而 anytype 是和该字段的原类型一样的类型。 这样的结果是在表上没有任何可见的语意的变化,但是这个命令强迫重写,这样就删除了不再使用的数据。
  ALTER TYPE 的 USING 选项实际上可以声明涉及该行旧值的任何表达式; 也就是说,它可以引用除了正在被转换的字段之外其它的字段。这样,我们就可以用 ALTER TYPE 语法做非常普遍性的转换。因为这个灵活性,USING 表达式并没有施用于该字段的缺省值(如果有的话); 结果可能不是缺省表达式要求的常量表达式。 这就意味着如果从旧类型到新类型如果没有隐含或者赋值转换的话, 那么即使存在 USING 子句的情况下, ALTER TYPE 也可能无法把缺省值转换成新的类型。 在这种情况下,我们应该用 DROP DEFAULT 先删除缺省, 执行 ALTER TYPE,然后使用 SET DEFAULT 增加一个合适的新缺省。 类似的考虑也适用于涉及该字段的索引和约束。
  如果表有任何后代表,那么如果不在后代表上做同样的修改的话, 就不允许在父表上增加,重命名或者修改一个字段的类型,也就是说, ALTER TABLE ONLY将被拒绝。这样就保证了后代表总是有和父表匹配的字段。
  一个递归DROP COLUMN 操作将只有在后代表并不从任何其它父表中继承该字段并且从来没有独立定义该字段的时候才能删除一个后代表的字段。 一个非递归的DROP COLUMN(也就是,ALTER TABLE ONLY ... DROP COLUMN)从来不会删除任何后代字段, 而是把他们标记为独立定义的,而不是继承的。
  不允许更改系统表结构的任何部分。

例子

  向表中增加一个 varchar 列:
  ALTER TABLE distributors ADD COLUMN address varchar(30);
  从表中删除一个字段:
  ALTER TABLE distributors DROP COLUMN address RESTRICT;
  在一个操作中修改两个现有字段的类型:
  ALTER TABLE distributors
  ALTER COLUMN address TYPE varchar(80),
  ALTER COLUMN name TYPE varchar(100);
  使用一个 USING 子句, 把一个包含 UNIX 时间戳的 integer 字段转化成 timestamp with time zone:
  ALTER TABLE foo
  ALTER COLUMN foo_timestamp TYPE timestamp with time zone
  USING
  timestamp with time zone 'epoch' + foo_timestamp * interval '1 second';
  对现存字段改名:
  ALTER TABLE distributors RENAME COLUMN address TO city;
  更改现存表的名字:
  ALTER TABLE distributors RENAME TO suppliers;
  给一个字段增加一个非空约束:
  ALTER TABLE distributors ALTER COLUMN street SET NOT NULL;
  从一个字段里删除一个非空约束:
  ALTER TABLE distributors ALTER COLUMN street DROP NOT NULL;
  给一个表增加一个检查约束:
  ALTER TABLE distributors ADD CONSTRAINT zipchk CHECK (char_length(zipcode) = 5);
  删除一个表和它的所有子表的监查约束:
  ALTER TABLE distributors DROP CONSTRAINT zipchk;
  向表中增加一个外键约束:
  ALTER TABLE distributors ADD CONSTRAINT distfk FOREIGN KEY (address) REFERENCES addresses(address) MATCH FULL;
  给表增加一个(多字段)唯一约束:
  ALTER TABLE distributors ADD CONSTRAINT dist_id_zipcode_key UNIQUE (dist_id, zipcode);
  给一个表增加一个自动命名的主键约束,要注意的是一个表只能有一个主键:
  ALTER TABLE distributors ADD PRIMARY KEY (dist_id);
  把表移动到另外一个表空间:
  ALTER TABLE distributors SET TABLESPACE fasttablespace;

你可能感兴趣的:(mysql)