Spec-Zone .ru
спецификации, руководства, описания, API
|
ALTER [IGNORE] TABLEtbl_name
[alter_specification
[,alter_specification
] ...] [partition_options
]alter_specification
:table_options
| ADD [COLUMN]col_name
column_definition
[FIRST | AFTERcol_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
| ALGORITHM [=] {DEFAULT|INPLACE|COPY} | ALTER [COLUMN]col_name
{SET DEFAULTliteral
| DROP DEFAULT} | CHANGE [COLUMN]old_col_name
new_col_name
column_definition
[FIRST|AFTERcol_name
] | LOCK [=] {DEFAULT|NONE|SHARED|EXCLUSIVE} | MODIFY [COLUMN]col_name
column_definition
[FIRST | AFTERcol_name
] | DROP [COLUMN]col_name
| DROP PRIMARY KEY | DROP {INDEX|KEY}index_name
| DROP FOREIGN KEYfk_symbol
| DISABLE KEYS | ENABLE KEYS | RENAME [TO|AS]new_tbl_name
| ORDER BYcol_name
[,col_name
] ... | CONVERT TO CHARACTER SETcharset_name
[COLLATEcollation_name
] | [DEFAULT] CHARACTER SET [=]charset_name
[COLLATE [=]collation_name
] | DISCARD TABLESPACE | IMPORT TABLESPACE | FORCE | ADD PARTITION (partition_definition
) | DROP PARTITIONpartition_names
| TRUNCATE PARTITION {partition_names
| ALL} | COALESCE PARTITIONnumber
| REORGANIZE PARTITIONpartition_names
INTO (partition_definitions
) | EXCHANGE PARTITIONpartition_name
WITH TABLEtbl_name
| ANALYZE PARTITION {partition_names
| ALL} | CHECK PARTITION {partition_names
| ALL} | OPTIMIZE PARTITION {partition_names
| ALL} | REBUILD PARTITION {partition_names
| ALL} | REPAIR PARTITION {partition_names
| ALL} | REMOVE PARTITIONINGindex_col_name
:col_name
[(length
)] [ASC | DESC]index_type
: USING {BTREE | HASH}index_option
: KEY_BLOCK_SIZE [=]value
|index_type
| WITH PARSERparser_name
| COMMENT 'string
'table_options
:table_option
[[,]table_option
] ... (seeCREATE TABLE
options)partition_options
: (seeCREATE TABLE
options)
ALTER
TABLE
changes the structure of a table. For example, you can add or delete columns, create or destroy
indexes, change the type of existing columns, or rename columns or the table itself. You can also change
characteristics such as the storage engine used for the table or the table comment.
Partitioning-related clauses for ALTER TABLE
can be used with partitioned tables for repartitioning, for adding, dropping, merging, and splitting partitions,
and for performing partitioning maintenance. It is possible for an ALTER TABLE
statement to contain a PARTITION BY
or REMOVE PARTITIONING
clause in an addition to other alter specifications, but the
PARTITION BY
or REMOVE PARTITIONING
clause must be
specified last after any other specifications. The ADD PARTITION
, DROP PARTITION
, COALESCE PARTITION
, REORGANIZE PARTITION
, ANALYZE PARTITION
, CHECK PARTITION
, and REPAIR PARTITION
options cannot
be combined with other alter specifications in a single ALTER TABLE
, since the
options just listed act on individual partitions. For more information, see Section
13.1.7.1, "ALTER TABLE
Partition Operations".
Following the table name, specify the alterations to be made. If none are given, ALTER TABLE
does nothing.
The syntax for many of the permissible alterations is similar to clauses of the CREATE TABLE
statement. See Section
13.1.17, "CREATE TABLE
Syntax", for more information.
Some operations may result in warnings if attempted on a table for which the storage engine does not support the
operation. These warnings can be displayed with SHOW WARNINGS
. See Section
13.7.5.41, "SHOW WARNINGS
Syntax".
For information on troubleshooting ALTER
TABLE
, see Section C.5.7.1, "Problems with ALTER TABLE
".
In most cases, ALTER TABLE
makes a temporary copy of the original table. MySQL waits for other
operations that are modifying the table, then proceeds. It incorporates the alteration into the copy, deletes
the original table, and renames the new one. While ALTER
TABLE
is executing, the original table is readable by other sessions (with the exception noted
shortly). Updates and writes to the table that begin after the ALTER TABLE
operation begins are stalled until the new table is ready, then
are automatically redirected to the new table without any failed updates. The temporary table is created in the
database directory of the new table. This can differ from the database directory of the original table for ALTER TABLE
operations that rename the table to a different database.
The exception referred to earlier is that ALTER
TABLE
blocks reads (not just writes) at the point where it is ready to install a new version of the
table .frm
file, discard the old file, and clear outdated table structures from
the table and table definition caches. At this point, it must acquire an exclusive lock. To do so, it waits for
current readers to finish, and blocks new reads (and writes).
For MyISAM
tables, you can speed up index re-creation (the slowest part of the
alteration process) by setting the myisam_sort_buffer_size
system variable to a high value.
For some operations, an in-place ALTER TABLE
is possible that does not require a temporary table:
For ALTER TABLE
without any other options, MySQL
simply renames any files that correspond to the table tbl_name
RENAME TO new_tbl_name
tbl_name
without making a copy. (You can also use the RENAME TABLE
statement to rename tables. See Section
13.1.32, "RENAME TABLE
Syntax".) Any privileges granted
specifically for the renamed table are not migrated to the new name. They must be changed manually.
Alterations that modify only table metadata and not table data can be made
immediately by altering the table's .frm
file and not touching table
contents. The following changes are fast alterations that can be made this way:
Renaming a column, except for the InnoDB
storage engine before MySQL 5.6.6.
Changing the default value of a column (except for NDB
tables; see Limitations
of MySQL Cluster online operations).
Changing the definition of an ENUM
or SET
column by adding new enumeration or set members to the
end of the list of valid member values, as long as
the storage size of the data type does not change. For example, adding a member to a SET
column that has 8 members changes the required
storage per value from 1 byte to 2 bytes; this will require a table copy. Adding members in
the middle of the list causes renumbering of existing members, which requires a table copy.
ALTER TABLE
with ADD
PARTITION
, DROP PARTITION
, COALESCE
PARTITION
, REBUILD PARTITION
, or REORGANIZE
PARTITION
does not create any temporary tables (except when used with NDB
tables); however, these operations can and do create temporary
partition files.
ADD
or DROP
operations for RANGE
or LIST
partitions are immediate
operations or nearly so. ADD
or COALESCE
operations for HASH
or KEY
partitions copy
data between all partitions, unless LINEAR HASH
or LINEAR KEY
was used; this is effectively the same as creating a new
table, although the ADD
or COALESCE
operation is performed partition by partition. REORGANIZE
operations
copy only changed partitions and do not touch unchanged ones.
Renaming an index, except for InnoDB
.
You can force an ALTER TABLE
operation that would otherwise not require a table
copy to use the temporary table method (as supported in MySQL 5.0) by setting the old_alter_table
system variable to ON
, or
specifying ALGORITHM=COPY
as one of the alter_specification
clauses. If there is a conflict between the old_alter_table
setting and an ALGORITHM
clause with a value other than DEFAULT
,
the ALGORITHM
clause takes precedence. (ALGORITHM =
DEFAULT
is the same a specifying no ALGORITHM
clause at all.)
Specifying ALGORITHM=INPLACE
makes the operation use the in-place technique for
clauses and storage engines that support it, and fail with an error otherwise, thus avoiding a lengthy table
copy if you try altering a table that uses a different storage engine than you expect. See Section
5.5, "Online DDL for InnoDB
Tables" for information about online DDL for
InnoDB
tables.
MySQL Cluster also supports online ALTER TABLE
operations using an ONLINE
keyword supported only by MySQL Cluster; see Section
13.1.7.2, "ALTER TABLE
Online Operations in MySQL Cluster", for the exact
syntax and other particulars.
You can control the level of concurrent reading and writing of the table while it is being altered, using the
LOCK
clause. Specifying a non-default value for this clause lets you require a
certain amount of concurrent access or exclusivity during the alter operation, and halts the operation if the
requested degree of locking is not available. The parameters for the LOCK
clause
are:
LOCK = DEFAULT
LOCK = NONE
LOCK = SHARED
LOCK = EXCLUSIVE
As of MySQL 5.6.3, you can also use ALTER TABLE
to perform a "null" alter operation that rebuilds the table. Previously the tbl_name
FORCEFORCE
option was recognized but ignored.
For NDB
tables, operations that add and drop indexes on variable-width columns occur online, without any table copying
and without blocking concurrent DML actions for most of their duration. See Section
13.1.7.2, "ALTER TABLE
Online Operations in MySQL Cluster".
To use ALTER
TABLE
, you need ALTER
, CREATE
, and INSERT
privileges for the table. Renaming a table requires ALTER
and DROP
on the old table,
ALTER
, CREATE
, and INSERT
on the new table.
IGNORE
is a MySQL extension to standard SQL. It
controls how ALTER TABLE
works if there are duplicates on unique keys in the new
table or if warnings occur when strict mode is enabled. If IGNORE
is not
specified, the copy is aborted and rolled back if duplicate-key errors occur. If IGNORE
is specified, only the first row is used of rows with duplicates on a unique key. The other conflicting
rows are deleted. Incorrect values are truncated to the closest matching acceptable value.
Pending INSERT
DELAYED
statements are lost if a table is write locked and ALTER TABLE
is used to modify the table structure.
table_option
signifies a table option of
the kind that can be used in the CREATE
TABLE
statement, such as ENGINE
, AUTO_INCREMENT
,
AVG_ROW_LENGTH
, or MAX_ROWS
. For a list of all
table options and descriptions of each, see Section 13.1.17,
"CREATE TABLE
Syntax". However, ALTER TABLE
ignores the DATA DIRECTORY
and INDEX DIRECTORY
table options.
For example, to convert a table to be an InnoDB
table, use this
statement:
ALTER TABLE t1 ENGINE = InnoDB;
See Section 5.4.3, "Converting Tables from
MyISAM
to InnoDB
" for considerations
when switching tables to the InnoDB
storage engine.
When you specify an ENGINE
clause, ALTER TABLE
rebuilds the table. This is true even if the table
already has the specified storage engine.
The outcome of attempting to change a table's storage engine is affected by whether the desired
storage engine is available and the setting of the NO_ENGINE_SUBSTITUTION
SQL mode, as described in Section
5.1.7, "Server SQL Modes".
To prevent inadvertent loss of data, ALTER
TABLE
cannot be used to change the storage engine of a table to MERGE
or BLACKHOLE
.
To change the value of the AUTO_INCREMENT
counter to be used for new
rows, do this:
ALTER TABLE t2 AUTO_INCREMENT = value
;
You cannot reset the counter to a value less than or equal to any that have already been used. For
MyISAM
, if the value is less than or equal to the maximum value
currently in the AUTO_INCREMENT
column, the value is reset to the
current maximum plus one. For InnoDB
, if the
value is less than the current maximum value in the column, no error occurs and the current
sequence value is not changed.
You can issue multiple ADD
, ALTER
,
DROP
, and CHANGE
clauses in a single ALTER TABLE
statement, separated by commas. This is a MySQL extension
to standard SQL, which permits only one of each clause per ALTER TABLE
statement. For example, to drop multiple columns in a
single statement, do this:
ALTER TABLE t2 DROP COLUMN c, DROP COLUMN d;
CHANGE
, col_name
DROP
, and col_name
DROP INDEX
are MySQL extensions to standard SQL.
The word COLUMN
is optional and can be omitted.
column_definition
clauses use the same
syntax for ADD
and CHANGE
as for CREATE TABLE
. See Section
13.1.17, "CREATE TABLE
Syntax".
You can rename a column using a CHANGE
clause. To do so, specify the old and
new column names and the definition that the column currently has. For example, to rename an old_col_name
new_col_name
column_definition
INTEGER
column from a
to b
, you can do this:
ALTER TABLE t1 CHANGE a b INTEGER;
To change a column's type but not the name, CHANGE
syntax still
requires an old and new column name, even if they are the same. For example:
ALTER TABLE t1 CHANGE b b BIGINT NOT NULL;
You can also use MODIFY
to change a column's type without renaming it:
ALTER TABLE t1 MODIFY b BIGINT NOT NULL;
MODIFY
is an extension to ALTER TABLE
for Oracle compatibility.
When you use CHANGE
or MODIFY
, column_definition
must include the data type and all
attributes that should apply to the new column, other than index attributes such as PRIMARY KEY
or UNIQUE
. Attributes
present in the original definition but not specified for the new definition are not carried forward.
Suppose that a column col1
is defined as INT
UNSIGNED DEFAULT 1 COMMENT 'my column'
and you modify the column as follows:
ALTER TABLE t1 MODIFY col1 BIGINT;
The resulting column will be defined as BIGINT
, but will not include
the attributes UNSIGNED DEFAULT 1 COMMENT 'my column'
. To retain them,
the statement should be:
ALTER TABLE t1 MODIFY col1 BIGINT UNSIGNED DEFAULT 1 COMMENT 'my column';
When you change a data type using CHANGE
or MODIFY
, MySQL tries to convert existing column values to the new type as well
as possible.
This conversion may result in alteration of data. For example, if you shorten a string
column, values may be truncated. To prevent the operation from succeeding if conversions to the
new data type would result in loss of data, enable strict SQL mode before using ALTER TABLE
(see Section
5.1.7, "Server SQL Modes").
To add a column at a specific position within a table row, use FIRST
or AFTER
. The default is to add the column last. You
can also use col_name
FIRST
and AFTER
in CHANGE
or MODIFY
operations to reorder
columns within a table.
ALTER ... SET DEFAULT
or
ALTER ... DROP DEFAULT
specify a new default value for a column or remove
the old default value, respectively. If the old default is removed and the column can be NULL
, the new default is NULL
. If the column
cannot be NULL
, MySQL assigns a default value as described in Section
11.5, "Data Type Default Values".
DROP INDEX
removes an index. This is a MySQL extension to standard SQL.
See Section
13.1.24, "DROP INDEX
Syntax". If you are unsure of the index name,
use SHOW INDEX FROM
.
tbl_name
If columns are dropped from a table, the columns are also removed from any index of
which they are a part. If all columns that make up an index are dropped, the index is dropped as well.
If you use CHANGE
or MODIFY
to shorten a
column for which an index exists on the column, and the resulting column length is less than the index
length, MySQL shortens the index automatically.
If a table contains only one column, the column cannot be dropped. If what you
intend is to remove the table, use DROP
TABLE
instead.
DROP PRIMARY KEY
drops the primary key. If there is
no primary key, an error occurs. For information about the performance characteristics of primary keys,
especially for InnoDB
tables, see Section
8.3.2, "Using Primary Keys".
If you add a UNIQUE INDEX
or PRIMARY KEY
to a table, MySQL stores it before any nonunique index to permit detection of duplicate keys as
early as possible.
Some storage engines permit you to specify an index type when creating an index.
The syntax for the index_type
specifier is USING
. For details
about type_name
USING
, see Section 13.1.13, "CREATE INDEX
Syntax". The preferred position is after the column
list. Support for use of the option before the column list will be removed in a future MySQL release.
index_option
values specify additional options for an
index. USING
is one such option. For details about permissible index_option
values, see Section
13.1.13, "CREATE INDEX
Syntax".
After an ALTER
TABLE
statement, it may be necessary to run ANALYZE TABLE
to update index cardinality information. See Section
13.7.5.23, "SHOW INDEX
Syntax".
ORDER BY
enables you to create the new table with the rows in a specific order. Note that the table does not
remain in this order after inserts and deletes. This option is useful primarily when you know that you
are mostly to query the rows in a certain order most of the time. By using this option after major
changes to the table, you might be able to get higher performance. In some cases, it might make sorting
easier for MySQL if the table is in order by the column that you want to order it by later.
ORDER BY
syntax permits one or more column names to be specified for
sorting, each of which optionally can be followed by ASC
or DESC
to indicate ascending or descending sort order, respectively.
The default is ascending order. Only column names are permitted as sort criteria; arbitrary
expressions are not permitted. This clause should be given last after any other clauses.
ORDER BY
does not make sense for InnoDB
tables that contain a user-defined clustered index (PRIMARY KEY
or
NOT NULL UNIQUE
index). InnoDB
always
orders table rows according to such an index if one is present.
When used on a partitioned table, ALTER TABLE ... ORDER BY
orders rows within each partition only.
If you use ALTER TABLE
on a MyISAM
table, all nonunique
indexes are created in a separate batch (as for REPAIR TABLE
). This should make ALTER TABLE
much faster when you have many indexes.
This feature can be activated explicitly for a MyISAM
table. ALTER TABLE ... DISABLE KEYS
tells MySQL to stop updating nonunique
indexes. ALTER TABLE ... ENABLE KEYS
then should be used to re-create
missing indexes. MySQL does this with a special algorithm that is much faster than inserting keys
one by one, so disabling keys before performing bulk insert operations should give a considerable
speedup. Using ALTER TABLE ... DISABLE KEYS
requires the INDEX
privilege in addition to the privileges mentioned earlier.
While the nonunique indexes are disabled, they are ignored for statements such as SELECT
and EXPLAIN
that otherwise would use them.
Before MySQL 5.6.7, using ALTER TABLE
to change the definition of a foreign key column could cause
a loss of referential integrity. For example, changing a foreign key column that contained NULL
values to be NOT NULL
caused the NULL
values to be the empty string. Similarly, an ALTER TABLE IGNORE
that removed rows in a parent table could break
referential integrity.
As of 5.6.7, the server prohibits changes to foreign key columns with the potential to cause loss of
referential integrity. A workaround is to use ALTER TABLE ... DROP FOREIGN KEY
before changing the column
definition and ALTER TABLE ... ADD
FOREIGN KEY
afterward.
The FOREIGN KEY
and REFERENCES
clauses are supported
by the InnoDB
and NDB
storage engines, which
implement ADD [CONSTRAINT [
.
See Section 5.4.5, "symbol
]]
FOREIGN KEY [index_name
] (...) REFERENCES ... (...)InnoDB
and FOREIGN KEY
Constraints". For
other storage engines, the clauses are parsed but ignored. The CHECK
clause
is parsed but ignored by all storage engines. See Section
13.1.17, "CREATE TABLE
Syntax". The reason for accepting but
ignoring syntax clauses is for compatibility, to make it easier to port code from other SQL servers, and
to run applications that create tables with references. See Section
1.8.5, "MySQL Differences from Standard SQL".
For ALTER TABLE
, unlike CREATE TABLE
, ADD FOREIGN KEY
ignores
index_name
if given and uses an automatically generated
foreign key name. As a workaround, include the CONSTRAINT
clause to
specify the foreign key name:
ADD CONSTRAINT name
FOREIGN KEY (....) ...
The inline REFERENCES
specifications where the references
are defined as part of the column specification are silently ignored. MySQL only accepts REFERENCES
clauses defined as part of a separate FOREIGN KEY
specification.
Partitioned InnoDB
tables do not support foreign keys.
This restriction does not apply to NDB
tables, including those
explicitly partitioned by [LINEAR] KEY
. See Section
18.6.2, "Partitioning Limitations Relating to Storage Engines", for more information.
The InnoDB
and NDB
storage engines support the use of ALTER TABLE
to drop foreign keys:
ALTER TABLEtbl_name
DROP FOREIGN KEYfk_symbol
;
For more information, see Section 5.4.5, "InnoDB
and FOREIGN KEY
Constraints".
You cannot add a foreign key and drop a foreign key in separate clauses of a single
ALTER TABLE
statement. You must use separate statements.
For an InnoDB
table that is created with its own tablespace in an .ibd
file, that file can be discarded and imported. To discard the .ibd
file, use this statement:
ALTER TABLE tbl_name
DISCARD TABLESPACE;
This deletes the current .ibd
file, so be sure that you have a backup
first. Attempting to modify the table contents while the tablespace file is discarded results in an
error. You can perform the DDL operations listed in Section
5.5, "Online DDL for InnoDB
Tables" while the tablespace file
is discarded.
To import the backup .ibd
file back into the table, copy it into the
database directory, and then issue this statement:
ALTER TABLE tbl_name
IMPORT TABLESPACE;
The tablespace file need not necessarily have been created on the server into which it is imported later. In MySQL 5.6, importing a tablespace file from another server works if the both servers have GA (General Availablility) status and their versions are within the same series. Otherwise, the file must have been created on the server into which it is imported.
To change the table default character
set and all character columns (CHAR
, VARCHAR
, TEXT
) to a new character set, use a statement like this:
ALTER TABLEtbl_name
CONVERT TO CHARACTER SETcharset_name
;
For a column that has a data type of VARCHAR
or one of the TEXT
types, CONVERT TO CHARACTER SET
will change the data type as necessary to ensure that the new column is long enough to store as many
characters as the original column. For example, a TEXT
column has two length bytes, which store the byte-length of
values in the column, up to a maximum of 65,535. For a latin1
TEXT
column, each character requires a single byte, so the column
can store up to 65,535 characters. If the column is converted to utf8
,
each character might require up to three bytes, for a maximum possible length of 3 × 65,535 =
196,605 bytes. That length will not fit in a TEXT
column's length bytes, so MySQL will convert the data type
to MEDIUMTEXT
, which is the smallest string type for which the
length bytes can record a value of 196,605. Similarly, a VARCHAR
column might be converted to MEDIUMTEXT
.
To avoid data type changes of the type just described, do not use CONVERT TO
CHARACTER SET
. Instead, use MODIFY
to change individual columns.
For example:
ALTER TABLE t MODIFY latin1_text_col TEXT CHARACTER SET utf8;ALTER TABLE t MODIFY latin1_varchar_col VARCHAR(M
) CHARACTER SET utf8;
If you specify CONVERT TO CHARACTER SET binary
, the CHAR
, VARCHAR
, and TEXT
columns are converted to their corresponding binary string types
(BINARY
, VARBINARY
,
BLOB
). This means that the columns no longer will have a
character set and a subsequent CONVERT TO
operation will not apply to
them.
If charset_name
is DEFAULT
,
the database character set is used.
The CONVERT TO
operation converts column values between
the character sets. This is not what you want if you have
a column in one character set (like latin1
) but the stored values
actually use some other, incompatible character set (like utf8
). In
this case, you have to do the following for each such column:
ALTER TABLE t1 CHANGE c1 c1 BLOB;ALTER TABLE t1 CHANGE c1 c1 TEXT CHARACTER SET utf8;
The reason this works is that there is no conversion when you convert to or from BLOB
columns.
To change only the default character set for a table, use this statement:
ALTER TABLEtbl_name
DEFAULT CHARACTER SETcharset_name
;
The word DEFAULT
is optional. The default character set is the
character set that is used if you do not specify the character set for columns that you add to a
table later (for example, with ALTER TABLE ... ADD column
).
With the mysql_info()
C API function, you can find out how many rows were copied by ALTER
TABLE
, and (when IGNORE
is used) how many rows were deleted due to
duplication of unique key values. See Section 22.8.7.35, "mysql_info()
".