Table of Contents
ALTER DATABASE SyntaxALTER TABLE SyntaxALTER LOGFILE GROUP SyntaxALTER TABLESPACE SyntaxALTER SERVER SyntaxCREATE DATABASE SyntaxCREATE INDEX SyntaxCREATE TABLE SyntaxCREATE LOGFILE GROUP SyntaxCREATE TABLESPACE SyntaxCREATE SERVER SyntaxDROP DATABASE SyntaxDROP INDEX SyntaxDROP TABLE SyntaxDROP LOGFILE GROUP SyntaxDROP TABLESPACE SyntaxDROP SERVER SyntaxRENAME DATABASE SyntaxRENAME TABLE SyntaxThis chapter describes the syntax for most of the SQL statements supported by MySQL. Additional statement descriptions can be found in the following chapters:
The EXPLAIN statement is discussed in
Chapter 7, Optimization.
Statements for writing stored routines are covered in Chapter 18, Stored Procedures and Functions.
Statements for writing triggers are covered in Chapter 19, Triggers.
View-related statements are covered in Chapter 21, Views.
Statements for scheduling events are covered in Chapter 20, Event Scheduler.
ALTER DATABASE SyntaxALTER TABLE SyntaxALTER LOGFILE GROUP SyntaxALTER TABLESPACE SyntaxALTER SERVER SyntaxCREATE DATABASE SyntaxCREATE INDEX SyntaxCREATE TABLE SyntaxCREATE LOGFILE GROUP SyntaxCREATE TABLESPACE SyntaxCREATE SERVER SyntaxDROP DATABASE SyntaxDROP INDEX SyntaxDROP TABLE SyntaxDROP LOGFILE GROUP SyntaxDROP TABLESPACE SyntaxDROP SERVER SyntaxRENAME DATABASE SyntaxRENAME TABLE SyntaxALTER {DATABASE | SCHEMA} [db_name]
alter_specification [alter_specification] ...
alter_specification:
[DEFAULT] CHARACTER SET charset_name
| [DEFAULT] COLLATE collation_name
ALTER DATABASE enables you to change the
overall characteristics of a database. These characteristics are
stored in the db.opt file in the database
directory. To use ALTER DATABASE, you need
the ALTER privilege on the database.
ALTER SCHEMA is a synonym for ALTER
DATABASE.
The CHARACTER SET clause changes the default
database character set. The COLLATE clause
changes the default database collation.
Chapter 10, Character Set Support, discusses character set and collation
names.
The database name can be omitted, in which case the statement applies to the default database.
MySQL Enterprise In a production environment, alteration of a database is not a common occurrence and may indicate a security breach. Advisors provided as part of the MySQL Network Monitoring and Advisory Service automatically alert you when data definition statements are issued. For more information see, http://www.mysql.com/products/enterprise/advisors.html.
ALTER [IGNORE] TABLEtbl_namealter_specification[,alter_specification] ...alter_specification:table_option... | ADD [COLUMN]column_definition[FIRST | AFTERcol_name] | ADD [COLUMN] (column_definition,...) | ADD {INDEX|KEY} [index_name] [index_type] (index_col_name,...) | ADD [CONSTRAINT [symbol]] PRIMARY KEY [index_type] (index_col_name,...) | ADD [CONSTRAINT [symbol]] UNIQUE [INDEX|KEY] [index_name] [index_type] (index_col_name,...) | ADD FULLTEXT [INDEX|KEY] [index_name] (index_col_name,...) [WITH PARSERparser_name] | ADD SPATIAL [INDEX|KEY] [index_name] (index_col_name,...) | ADD [CONSTRAINT [symbol]] FOREIGN KEY [index_name] (index_col_name,...) [reference_definition] | ALTER [COLUMN]col_name{SET DEFAULTliteral| DROP DEFAULT} | CHANGE [COLUMN]old_col_namecolumn_definition[FIRST|AFTERcol_name] | MODIFY [COLUMN]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]new_tbl_name| ORDER BYcol_name[,col_name] ... | CONVERT TO CHARACTER SETcharset_name[COLLATEcollation_name] | [DEFAULT] CHARACTER SETcharset_name[COLLATEcollation_name] | DISCARD TABLESPACE | IMPORT TABLESPACE | PARTITION BYpartition_options| ADD PARTITION (partition_definition) | DROP PARTITIONpartition_names| COALESCE PARTITIONnumber| REORGANIZE PARTITIONpartition_namesINTO (partition_definitions) | ANALYZE PARTITIONpartition_names| CHECK PARTITIONpartition_names| OPTIMIZE PARTITIONpartition_names| REBUILD PARTITIONpartition_names| REPAIR PARTITIONpartition_names| REMOVE PARTITIONINGindex_col_name:col_name[(length)] [ASC | DESC]index_type: USING {BTREE | HASH}
ALTER TABLE enables you to change the
structure of an existing 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 the comment for the table and type of the table.
The syntax for many of the allowable alterations is similar to
clauses of the CREATE TABLE statement. See
Section 13.1.8, “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.5.4.31, “SHOW WARNINGS Syntax”.
In most cases, ALTER TABLE works by making a
temporary copy of the original table. The alteration is
performed on the copy, and then the original table is deleted
and the new one is renamed. While ALTER TABLE
is executing, the original table is readable by other clients.
Updates and writes to the table are stalled until the new table
is ready, and then are automatically redirected to the new table
without any failed updates.
In some cases, no temporary table is necessary:
If you use ALTER TABLE
without
any other options, MySQL simply renames any files that
correspond to the table tbl_name RENAME TO
new_tbl_nametbl_name.
(You can also use the RENAME TABLE
statement to rename tables. See
Section 13.1.19, “RENAME TABLE Syntax”.) Any privileges granted
specifically for the renamed table are not migrated to the
new name. They must be changed manually.
ALTER TABLE ... ADD PARTITION creates no
temporary table except for MySQL Cluster.
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 changed
partitions; unless LINEAR HASH/KEY was
used, this is much the same as creating a new table
(although the operation is done partition by partition).
REORGANIZE operations copy only changed
partitions and do not touch unchanged ones.
If other cases, MySQL creates a temporary table, even if the
data wouldn't strictly need to be copied (such as when you
change the name of a column). For MyISAM
tables, you can speed up the index re-creation operation (which
is the slowest part of the alteration process) by setting the
myisam_sort_buffer_size system variable to a
high value.
To use ALTER TABLE, you need
ALTER, INSERT, and
CREATE privileges for the 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.
table_option signifies a table
option of the kind that can be used in the CREATE
TABLE statement. (Section 13.1.8, “CREATE TABLE Syntax”,
lists all table options.) This includes options such as
ENGINE,
AUTO_INCREMENT, and
AVG_ROW_LENGTH. 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;
As of MySQL 5.1.11, 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
message is given 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 allows 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_nameDROP
, and
col_nameDROP INDEX are MySQL extensions to
standard SQL.
MODIFY is an Oracle extension to
ALTER TABLE.
The word COLUMN is optional and can be
omitted.
column_definition clauses use the
same syntax for ADD and
CHANGE as for CREATE
TABLE. Note that this syntax includes the column
name, not just its data type. See
Section 13.1.8, “CREATE TABLE Syntax”.
You can rename a column using a CHANGE
clause. To do so, specify the old and new column names and
the type that the column currently has. For example, to
rename an old_col_name
column_definitionINTEGER column from
a to b, you can do
this:
ALTER TABLE t1 CHANGE a b INTEGER;
If you want 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;
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.
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.
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_nameFIRST and AFTER in
CHANGE or MODIFY
operations.
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.1.4, “Data Type Default Values”.
DROP INDEX removes an index. This is a
MySQL extension to standard SQL. See
Section 13.1.13, “DROP INDEX Syntax”.
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 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 index.
Note: In older versions of MySQL, if no
primary index existed, DROP PRIMARY KEY
would drop the first UNIQUE index in the
table. This is not the case in MySQL 5.1, where
trying to use DROP PRIMARY KEY on a table
with no primary key results in an error.
If you add a UNIQUE INDEX or
PRIMARY KEY to a table, it is stored
before any non-unique index so that MySQL can detect
duplicate keys as early as possible.
Some storage engines allow you to specify an index type when
creating an index. The syntax for the
index_type specifier is
USING
. Before MySQL
5.1.10, type_nameUSING can be given only before
the index column list. As of 5.1.10, the preferred position
is after the column list. Use of the option before the
column list will no longer be recognized as of MySQL 5.3.
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 allows for 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 allowed as sort criteria; arbitrary
expressions are not allowed.
If you use ALTER TABLE on a
MyISAM table, all non-unique 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. ALTER
TABLE ... DISABLE KEYS tells MySQL to stop
updating non-unique indexes for a MyISAM
table. 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 non-unique indexes are disabled, they are ignored
for statements such as SELECT and
EXPLAIN that otherwise would use them.
ENABLE KEYS and DISABLE
KEYS were not supported for partitioned tables
prior to MySQL 5.1.11. (Bug#19502)
The FOREIGN KEY and
REFERENCES clauses are supported by the
InnoDB storage engine, which implements
ADD [CONSTRAINT
[. See
Section 14.5.6.4, “symbol]] FOREIGN KEY (...)
REFERENCES ... (...)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.8, “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.9.5, “MySQL Differences from Standard SQL”.
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.
InnoDB supports the use of ALTER
TABLE to drop foreign keys:
ALTER TABLEtbl_nameDROP FOREIGN KEYfk_symbol;
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 more information, see
Section 14.5.6.4, “FOREIGN KEY Constraints”.
Pending INSERT DELAYED statements are
lost if a table is write locked and ALTER
TABLE is used to modify the table structure.
If you want 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_nameCONVERT TO CHARACTER SETcharset_name;
Warning: The preceding
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.
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.
To change only the default character set for a table, use this statement:
ALTER TABLEtbl_nameDEFAULT 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 a new column which you add
to a table (for example, with ALTER TABLE ... ADD
column).
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 access
the table while the tablespace file is discarded results in
an error.
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;
A number of partitioning-related extensions to
ALTER TABLE were added in MySQL 5.1.5.
These can be used with partitioned tables for
repartitioning, for adding, dropping, merging, and splitting
partitions, and for performing partitioning maintenance.
Simply using a partition_options
clause with ALTER TABLE on a partitioned
table repartitions the table according to the partitioning
scheme defined by the
partition_options. This clause
always begins with PARTITION BY, and
follows the same syntax and other rules as apply to the
partition_options clause for
CREATE TABLE (see
Section 13.1.8, “CREATE TABLE Syntax”, for more detailed
information), and can also be used to partition an existing
table that is not already partitioned. For example, consider
a (non-partitioned) table defined as shown here:
CREATE TABLE t1 (
id INT,
year_col INT
);
This table can be partitioned by HASH,
using the id column as the partitioning
key, into 8 partitions by means of this statement:
ALTER TABLE t1
PARTITION BY HASH(id)
PARTITIONS 8;
The table that results from using an ALTER TABLE
... PARTITION BY statement must follow the same
rules as one created using CREATE TABLE ...
PARTITION BY. This includes the rules governing
the relationship between any unique keys (including any
primary key) that the table might have, and the column or
columns used in the partitioning expression, as discussed in
Partitioning
Limitations: Partitioning Keys and Unique Keys. The
CREATE TABLE ... PARTITION BY rules for
specifying the number of partitions also apply to
ALTER TABLE ... PARTITION BY.
ALTER TABLE ... PARTITION BY became
available in MySQL 5.1.6.
The partition_definition clause
for ALTER TABLE ADD PARTITION supports
the same options as the clause of the same name does for the
CREATE TABLE statement clause of the same
name. (See Section 13.1.8, “CREATE TABLE Syntax”, for the syntax
and description.) Suppose that you have the partitioned
table created as shown here:
CREATE TABLE t1 (
id INT,
year_col INT
)
PARTITION BY RANGE (year_col) (
PARTITION p0 VALUES LESS THAN (1991),
PARTITION p1 VALUES LESS THAN (1995),
PARTITION p2 VALUES LESS THAN (1999)
);
You can add a new partition p3 to this
table for storing values less then 2002
as follows:
ALTER TABLE t1 ADD PARTITION (PARTITION p3 VALUES LESS THAN (2002));
DROP PARTITION can be used to drop one or
more RANGE or LIST
partitions. This statement cannot be used with
HASH or KEY
partitions; instead, use COALESCE
PARTITION (see below). Any data that was stored in
the dropped partitions named in the
partition_names list is
discarded. For example, given the table
t1 defined previously, you can drop the
partitions named p0 and
p1 as shown here:
ALTER TABLE t1 DROP PARTITION p0, p1;
Note that DROP PARTITION does not work
with tables that use the NDB Cluster
storage engine. See
Section 16.3.1, “Management of RANGE and LIST
Partitions”, and
Section 15.14, “Known Limitations of MySQL Cluster”.
ADD PARTITION and DROP
PARTITION do not currently support IF
[NOT] EXISTS. It is also not possible to rename a
partition or a partitioned table. Instead, if you wish to
rename a partition, you must drop and re-create the
partition; if you wish to rename a partitioned table, you
must instead drop all partitions, rename the table, and then
add back the partitions that were dropped.
COALESCE PARTITION can be used with a
table that is partitioned by HASH or
KEY to reduce the number of partitions by
number. Suppose that you have
created table t2 using the following
definition:
CREATE TABLE t2 (
name VARCHAR (30),
started DATE
)
PARTITION BY HASH( YEAR(started) )
PARTITIONS 6;
You can reduce the number of partitions used by
t2 from 6 to 4 using the following
statement:
ALTER TABLE t2 COALESCE PARTITION 2;
The data contained in the last
number partitions will be merged
into the remaining partitions. In this case, partitions 4
and 5 will be merged into the first 4 partitions (the
partitions numbered 0, 1, 2, and 3.
To change some but not all the partitions used by a
partitioned table, you can use REORGANIZE
PARTITION. This statement can be used in several
ways:
To merge a set of partitions into a single partition.
This can be done by naming several partitions in the
partition_names list and
supplying a single definition for
partition_definition.
To split an existing partition into several partitions.
You can accomplish this by naming a single partition for
partition_names and providing
multiple
partition_definitions.
To change the ranges for a subset of partitions defined
using VALUES LESS THAN or the value
lists for a subset of partitions defined using
VALUES IN.
Note: For partitions that
have not been explicitly named, MySQL automatically provides
the default names p0,
p1, p2, and so on. As
of MySQL 5.1.7, the same is true with regard to
subpartitions.
For more detailed information about and examples of
ALTER TABLE ... REORGANIZE PARTITION
statements, see Section 16.3, “Partition Management”.
Several additional clauses provide partition maintenance and
repair functionality analogous to that implemented for
non-partitioned tables by statements such as CHECK
TABLE and REPAIR TABLE (which
are not supported for partitioned
tables). These include ANALYZE PARTITION,
CHECK PARTITION, OPTIMIZE
PARTITION, REBUILD PARTITION,
and REPAIR PARTITION. Each of these
options takes a partition_names
clause consisting of one or more names of partitions,
separated by commas. The partitions must already exist in
the table to be altered. For more information, and for
examples of these, see
Section 16.3.3, “Maintenance of Partitions”.
REMOVE PARTITIONING was introduced in
MySQL 5.1.8 for the purpose of removing a table's
partitioning without otherwise affecting the table or its
data. (Previously. this was done using the ENGINE
option.) This option can be combined with other
ALTER TABLE options such as those used to
add, drop, or rename drop columns or indexes.
In MySQL 5.1.7 and earlier, using the
ENGINE option with ALTER
TABLE caused any partitioning that a table might
have had to be removed. Beginning with MySQL 5.1.8, this
option merely changes the storage engine used by the table
and no longer affects partitioning in any way.
With the mysql_info() C API function, you can
find out how many rows were copied, and (when
IGNORE is used) how many rows were deleted
due to duplication of unique key values. See
Section 24.2.3.35, “mysql_info()”.
Here are some examples that show uses of ALTER
TABLE. Begin with a table t1 that
is created as shown here:
CREATE TABLE t1 (a INTEGER,b CHAR(10));
To rename the table from t1 to
t2:
ALTER TABLE t1 RENAME t2;
To change column a from
INTEGER to TINYINT NOT
NULL (leaving the name the same), and to change column
b from CHAR(10) to
CHAR(20) as well as renaming it from
b to c:
ALTER TABLE t2 MODIFY a TINYINT NOT NULL, CHANGE b c CHAR(20);
To add a new TIMESTAMP column named
d:
ALTER TABLE t2 ADD d TIMESTAMP;
To add indexes on column d and on column
a:
ALTER TABLE t2 ADD INDEX (d), ADD INDEX (a);
To remove column c:
ALTER TABLE t2 DROP COLUMN c;
To add a new AUTO_INCREMENT integer column
named c:
ALTER TABLE t2 ADD c INT UNSIGNED NOT NULL AUTO_INCREMENT, ADD PRIMARY KEY (c);
Note that we indexed c (as a PRIMARY
KEY), because AUTO_INCREMENT
columns must be indexed, and also that we declare
c as NOT NULL, because
primary key columns cannot be NULL.
When you add an AUTO_INCREMENT column, column
values are filled in with sequence numbers for you
automatically. For MyISAM tables, you can set
the first sequence number by executing SET
INSERT_ID= before
valueALTER TABLE or by using the
AUTO_INCREMENT=
table option. See Section 13.5.3, “valueSET Syntax”.
With MyISAM tables, if you do not change the
AUTO_INCREMENT column, the sequence number is
not affected. If you drop an AUTO_INCREMENT
column and then add another AUTO_INCREMENT
column, the numbers are resequenced beginning with 1.
When replication is used, adding an
AUTO_INCREMENT column to a table might not
produce the same ordering of the rows on the slave and the
master. This occurs because the order in which the rows are
numbered depends on the specific storage engine used for the
table and the order in which the rows were inserted. If it is
important to have the same order on the master and slave, the
rows must be ordered before assigning an
AUTO_INCREMENT number. Assuming that you want
to add an AUTO_INCREMENT column to the table
t1, the following statements produce a new
table t2 identical to t1
but with an AUTO_INCREMENT column:
CREATE TABLE t2 (id INT AUTO_INCREMENT PRIMARY KEY) SELECT * FROM t1 ORDER BY col1, col2;
This assumes that the table t1 has columns
col1 and col2.
This set of statements will also produce a new table
t2 identical to t1, with
the addition of an AUTO_INCREMENT column:
CREATE TABLE t2 LIKE t1; ALTER TABLE T2 ADD id INT AUTO_INCREMENT PRIMARY KEY; INSERT INTO t2 SELECT * FROM t1 ORDER BY col1, col2;
Important: To guarantee the
same ordering on both master and slave, all
columns of t1 must be referenced in the
ORDER BY clause.
Regardless of the method used to create and populate the copy
having the AUTO_INCREMENT column, the final
step is to drop the original table and then rename the copy:
DROP t1; ALTER TABLE t2 RENAME t1;
ALTER LOGFILE GROUPlogfile_groupADD UNDOFILE 'file' [INITIAL_SIZE [=]size] ENGINE [=]engine
This statement adds an UNDO file named
'file' to an existing log file group
logfile_group. An ALTER
LOGFILE GROUP statement has one and only one
ADD UNDOFILE clause. No DROP
UNDOFILE clause is supported.
The optional INITIAL_SIZE parameter sets the
UNDO file's initial size in bytes; if not
specified, the initial size default to 128M
(128 megabytes). You may optionally follow
size with a one-letter abbreviation
for an order of magnitude, similar to those used in
my.cnf. Generally, this is one of the
letters M (for megabytes) or
G (for gigabytes).
The ENGINE parameter (required) determines
the storage engine which is used by this log file group, with
engine being the name of the storage
engine. In MySQL 5.1, the only accepted values for
engine are NDB and
NDBCLUSTER.
Here is an example, which assumes that the log file group
lg_3 has already been created using
CREATE LOGFILE GROUP (see
Section 13.1.9, “CREATE LOGFILE GROUP Syntax”):
ALTER LOGFILE GROUP lg_3
ADD UNDOFILE 'undo_10.dat'
INITIAL_SIZE=32M
ENGINE=NDB;
When ALTER LOGFILE GROUP is used with
ENGINE = NDB, an UNDO log
file is created on each Cluster data node. You can verify that
the UNDO files were created and obtain
information about them by querying the
INFORMATION_SCHEMA.FILES table. For example:
mysql>SELECT FILE_NAME, LOGFILE_GROUP_NUMBER, EXTRA->FROM INFORMATION_SCHEMA.FILES->WHERE LOGFILE_GROUP_NAME = 'lg_3';+-------------+----------------------+----------------+ | FILE_NAME | LOGFILE_GROUP_NUMBER | EXTRA | +-------------+----------------------+----------------+ | newdata.dat | 0 | CLUSTER_NODE=3 | | newdata.dat | 0 | CLUSTER_NODE=4 | | undo_10.dat | 11 | CLUSTER_NODE=3 | | undo_10.dat | 11 | CLUSTER_NODE=4 | +-------------+----------------------+----------------+ 4 rows in set (0.01 sec)
(See Section 22.21, “The INFORMATION_SCHEMA FILES Table”.)
ALTER LOGFILE GROUP was added in MySQL 5.1.6.
In MySQL 5.1, it is useful only with Disk Data storage for MySQL
Cluster. See Section 15.12, “MySQL Cluster Disk Data Tables”.
ALTER TABLESPACEtablespaceADD DATAFILE 'file' [INITIAL_SIZE [=]size] ENGINE [=]engineALTER TABLESPACEtablespaceDROP DATAFILE 'file' ENGINE [=]engine
This statement can be used either to add a new data file, or to drop a data file from a tablespace.
The ADD DATAFILE variant allows you to
specify an initial size using an INITIAL_SIZE
clause, where size is measured in
bytes; the default value is 128M (128
megabytes). You may optionally follow this integer value with a
one-letter abbreviation for an order of magnitude, similar to
those used in my.cnf. Generally, this is
one of the letters M (for megabytes) or
G (for gigabytes).
Once a data file has been created, its size cannot be changed;
however, you can add more data files to the tablespace using
additional ALTER TABLESPACE ... ADD DATAFILE
statements.
Using DROP DATAFILE with ALTER
TABLESPACE drops the data file
'file' from the tablespace. This file
must already have been added to the tablespace using
CREATE TABLESPACE or ALTER
TABLESPACE; otherwise an error will result.
Both ALTER TABLESPACE ... ADD DATAFILE and
ALTER TABLESPACE ... DROP DATAFILE require an
ENGINE clause which specifies the storage
engine used by the tablespace. In MySQL 5.1, the only accepted
values for engine are
NDB and NDBCLUSTER.
When ALTER TABLESPACE ... ADD DATAFILE is
used with ENGINE = NDB, a data file is
created on each Cluster data node. You can verify that the data
files were created and obtain information about them by querying
the INFORMATION_SCHEMA.FILES table. For
example, the following query shows all data files belonging to
the tablespace named newts:
mysql>SELECT LOGFILE_GROUP_NAME, FILE_NAME, EXTRA->FROM INFORMATION_SCHEMA.FILES->WHERE TABLESPACE_NAME = 'newts' AND FILE_TYPE = 'DATAFILE';+--------------------+--------------+----------------+ | LOGFILE_GROUP_NAME | FILE_NAME | EXTRA | +--------------------+--------------+----------------+ | lg_3 | newdata.dat | CLUSTER_NODE=3 | | lg_3 | newdata.dat | CLUSTER_NODE=4 | | lg_3 | newdata2.dat | CLUSTER_NODE=3 | | lg_3 | newdata2.dat | CLUSTER_NODE=4 | +--------------------+--------------+----------------+ 2 rows in set (0.03 sec)
See Section 22.21, “The INFORMATION_SCHEMA FILES Table”.
ALTER TABLESPACE was added in MySQL 5.1.6. In
MySQL 5.1, it is useful only with Disk Data storage for MySQL
Cluster. See Section 15.12, “MySQL Cluster Disk Data Tables”.
ALTER SERVERserver_nameOPTIONS (option...)
Alters the server information for
,
adjusting the specified options as per the server_nameCREATE
SERVER command. See Section 13.1.11, “CREATE SERVER Syntax”.
The corresponding fields in the mysql.servers
table are updated accordingly. This statement requires the
SUPER privilege.
For example, to update the USER option:
ALTER SERVER s OPTIONS (USER 'sally');
ALTER SERVER does not cause an automatic
commit.
CREATE {DATABASE | SCHEMA} [IF NOT EXISTS] db_name
[create_specification [create_specification] ...]
create_specification:
[DEFAULT] CHARACTER SET charset_name
| [DEFAULT] COLLATE collation_name
CREATE DATABASE creates a database with the
given name. To use this statement, you need the
CREATE privilege for the database.
CREATE SCHEMA is a synonym for
CREATE DATABASE.
An error occurs if the database exists and you did not specify
IF NOT EXISTS.
create_specification options specify
database characteristics. Database characteristics are stored in
the db.opt file in the database directory.
The CHARACTER SET clause specifies the
default database character set. The COLLATE
clause specifies the default database collation.
Chapter 10, Character Set Support, discusses character set and collation
names.
A database in MySQL is implemented as a directory containing
files that correspond to tables in the database. Because there
are no tables in a database when it is initially created, the
CREATE DATABASE statement creates only a
directory under the MySQL data directory and the
db.opt file. Rules for allowable database
names are given in Section 9.2, “Identifiers”. If a database
name contains special characters, the name for the database
directory contains encoded versions of those characters as
described in Section 9.2.3, “Mapping of Identifiers to Filenames”.
If you manually create a directory under the data directory (for
example, with mkdir), the server considers it
a database directory and it shows up in the output of
SHOW DATABASES.
You can also use the mysqladmin program to create databases. See Section 8.10, “mysqladmin — Client for Administering a MySQL Server”.
CREATE [UNIQUE|FULLTEXT|SPATIAL] INDEXindex_name[index_type] ONtbl_name(index_col_name,...) [index_option...]index_col_name:col_name[(length)] [ASC | DESC]index_type: USING {BTREE | HASH}index_option: KEY_BLOCK_SIZEvalue|index_type| WITH PARSERparser_name
CREATE INDEX is mapped to an ALTER
TABLE statement to create indexes. See
Section 13.1.2, “ALTER TABLE Syntax”. CREATE INDEX
cannot be used to create a PRIMARY KEY; use
ALTER TABLE instead. For more information
about indexes, see Section 7.4.5, “How MySQL Uses Indexes”.
Normally, you create all indexes on a table at the time the
table itself is created with CREATE TABLE.
See Section 13.1.8, “CREATE TABLE Syntax”. CREATE
INDEX enables you to add indexes to existing tables.
A column list of the form (col1,col2,...)
creates a multiple-column index. Index values are formed by
concatenating the values of the given columns.
Indexes can be created that use only the leading part of column
values, using
syntax to specify an index prefix length:
col_name(length)
Prefixes can be specified for CHAR,
VARCHAR, BINARY, and
VARBINARY columns.
BLOB and TEXT columns
also can be indexed, but a prefix length
must be given.
Prefix lengths are given in characters for non-binary string
types and in bytes for binary string types. That is, index
entries consist of the first
length characters of each column
value for CHAR,
VARCHAR, and TEXT
columns, and the first length
bytes of each column value for BINARY,
VARBINARY, and BLOB
columns.
For spatial columns, prefix values can be given as described later in this section.
The statement shown here creates an index using the first 10
characters of the name column:
CREATE INDEX part_of_name ON customer (name(10));
If names in the column usually differ in the first 10
characters, this index should not be much slower than an index
created from the entire name column. Also,
using column prefixes for indexes can make the index file much
smaller, which could save a lot of disk space and might also
speed up INSERT operations.
Prefix lengths are storage engine-dependent (for example, a
prefix can be up to 1000 bytes long for
MyISAM tables, 767 bytes for
InnoDB tables). Note that prefix limits are
measured in bytes, whereas the prefix length in CREATE
INDEX statements is interpreted as number of
characters for non-binary data types (CHAR,
VARCHAR, TEXT). Take this
into account when specifying a prefix length for a column that
uses a multi-byte character set. For example,
utf8 columns require up to three index bytes
per character.
A UNIQUE index creates a constraint such that
all values in the index must be distinct. An error occurs if you
try to add a new row with a key value that matches an existing
row. For all engines, a UNIQUE index allows
multiple NULL values for columns that can
contain NULL. If you specify a prefix value
for a column in a UNIQUE index, the column
values must be unique within the prefix.
FULLTEXT indexes are supported only for
MyISAM tables and can include only
CHAR, VARCHAR, and
TEXT columns. Indexing always happens over
the entire column; column prefix indexing is not supported and
any prefix length is ignored if specified. See
Section 12.8, “Full-Text Search Functions”, for details of operation.
The MyISAM, InnoDB,
NDB, BDB, and
ARCHIVE storage engines support spatial
columns such as (POINT and
GEOMETRY.
(Chapter 17, Spatial Extensions, describes the spatial
data types.) However, support for spatial column indexing varies
among engines. Spatial and non-spatial indexes are available
according to the following rules.
Spatial indexes (created using SPATIAL
INDEX):
Available only for MyISAM tables.
Specifying a SPATIAL INDEX for other
storage engines results in an error.
Indexed columns must be NOT NULL.
In MySQL 5.1, column prefix lengths are prohibited. The full width of each column is indexed.
Non-spatial indexes (created with INDEX,
UNIQUE, or PRIMARY KEY):
Allowed for any storage engine that supports spatial columns
except ARCHIVE.
Columns can be NULL unless the index is a
primary key.
For each spatial column in a non-SPATIAL
index except POINT columns, a column
prefix length must be specified. (This is the same
requirement as for indexed BLOB columns.)
The prefix length is given in bytes.
The index type for a non-SPATIAL index
depends on the storage engine. Currently, B-tree is used.
In MySQL 5.1:
You can add an index on a column that can have
NULL values only if you are using the
MyISAM, InnoDB, or
MEMORY storage engine.
You can add an index on a BLOB or
TEXT column only if you are using the
MyISAM, or InnoDB
storage engine.
An index_col_name specification can
end with ASC or DESC.
These keywords are allowed for future extensions for specifying
ascending or descending index value storage. Currently, they are
parsed but ignored; index values are always stored in ascending
order.
Following the index column list, index options can be given. An
index_option value can be any of the
following:
KEY_BLOCK_SIZE
value
This option provides a hint to the storage engine about the
size to use for index key blocks. The engine is allowed to
change the value if necessary. A value of 0 indicates that
the default value should be used.
KEY_BLOCK_SIZE was added in MySQL 5.1.10.
index_type
Some storage engines allow you to specify an index type when creating an index. The allowable index type values supported by different storage engines are shown in the following table. Where multiple index types are listed, the first one is the default when no index type specifier is given.
| Storage Engine | Allowable Index Types |
MyISAM | BTREE |
InnoDB | BTREE |
MEMORY/HEAP | HASH, BTREE |
NDB | HASH |
If you specify an index type that is not legal for a given storage engine, but there is another index type available that the engine can use without affecting query results, the engine uses the available type.
Examples:
CREATE TABLE lookup (id INT) ENGINE = MEMORY; CREATE INDEX id_index USING BTREE ON lookup (id);
For indexes on NDB table columns, the
USING clause can be specified only for a
unique index or primary key. In such cases, the
USING HASH clause prevents the creation
of an implicit ordered index. Without USING
HASH, a statement defining a unique index or
primary key automatically results in the creation of a
HASH index in addition to the ordered
index, both of which index the same set of columns.
TYPE
is recognized as a synonym for type_nameUSING
. However,
type_nameUSING is the preferred form.
Note: Before MySQL 5.1.10, this option can be given only
before the ON
clause. Use of
the option in this position is deprecated as of 5.1.10;
support for it is to be dropped in a future MySQL release.
tbl_name
WITH PARSER
parser_name
This option can be used only with
FULLTEXT indexes. It associates a parser
plugin with the index if full-text indexing and searching
operations need special handling. See
Section 26.2, “The MySQL Plugin Interface”, for details on creating
plugins.
CREATE [TEMPORARY] TABLE [IF NOT EXISTS]tbl_name(create_definition,...) [table_option...] [partition_options]
Or:
CREATE [TEMPORARY] TABLE [IF NOT EXISTS]tbl_name[(create_definition,...)] [table_option...] [partition_options]select_statement
Or:
CREATE [TEMPORARY] TABLE [IF NOT EXISTS]tbl_name{ LIKEold_tbl_name| (LIKEold_tbl_name) }create_definition:column_definition| [CONSTRAINT [symbol]] PRIMARY KEY [index_type] (index_col_name,...) [index_option...] | {INDEX|KEY} [index_name] [index_type] (index_col_name,...) [index_option...] | [CONSTRAINT [symbol]] UNIQUE [INDEX|KEY] [index_name] [index_type] (index_col_name,...) [index_option...] | {FULLTEXT|SPATIAL} [INDEX|KEY] [index_name] (index_col_name,...) [index_option...] | [CONSTRAINT [symbol]] FOREIGN KEY [index_name] (index_col_name,...) [reference_definition] | CHECK (expr)column_definition:col_namedata_type[NOT NULL | NULL] [DEFAULTdefault_value] [AUTO_INCREMENT] [UNIQUE [KEY] | [PRIMARY] KEY] [COMMENT 'string'] [reference_definition]data_type: BIT[(length)] | TINYINT[(length)] [UNSIGNED] [ZEROFILL] | SMALLINT[(length)] [UNSIGNED] [ZEROFILL] | MEDIUMINT[(length)] [UNSIGNED] [ZEROFILL] | INT[(length)] [UNSIGNED] [ZEROFILL] | INTEGER[(length)] [UNSIGNED] [ZEROFILL] | BIGINT[(length)] [UNSIGNED] [ZEROFILL] | REAL[(length,decimals)] [UNSIGNED] [ZEROFILL] | DOUBLE[(length,decimals)] [UNSIGNED] [ZEROFILL] | FLOAT[(length,decimals)] [UNSIGNED] [ZEROFILL] | DECIMAL(length,decimals) [UNSIGNED] [ZEROFILL] | NUMERIC(length,decimals) [UNSIGNED] [ZEROFILL] | DATE | TIME | TIMESTAMP | DATETIME | YEAR | CHAR(length) [CHARACTER SETcharset_name] [COLLATEcollation_name] | VARCHAR(length) [CHARACTER SETcharset_name] [COLLATEcollation_name] | BINARY(length) | VARBINARY(length) | TINYBLOB | BLOB | MEDIUMBLOB | LONGBLOB | TINYTEXT [BINARY] [CHARACTER SETcharset_name] [COLLATEcollation_name] | TEXT [BINARY] [CHARACTER SETcharset_name] [COLLATEcollation_name] | MEDIUMTEXT [BINARY] [CHARACTER SETcharset_name] [COLLATEcollation_name] | LONGTEXT [BINARY] [CHARACTER SETcharset_name] [COLLATEcollation_name] | ENUM(value1,value2,value3,...) [CHARACTER SETcharset_name] [COLLATEcollation_name] | SET(value1,value2,value3,...) [CHARACTER SETcharset_name] [COLLATEcollation_name] |spatial_typeindex_col_name:col_name[(length)] [ASC | DESC]index_type: USING {BTREE | HASH}index_option: KEY_BLOCK_SIZEvalue|index_type| WITH PARSERparser_namereference_definition: REFERENCEStbl_name[(index_col_name,...)] [MATCH FULL | MATCH PARTIAL | MATCH SIMPLE] [ON DELETEreference_option] [ON UPDATEreference_option]reference_option: RESTRICT | CASCADE | SET NULL | NO ACTIONtable_option: [TABLESPACEtablespace_nameSTORAGE DISK] ENGINE [=]engine_name| AUTO_INCREMENT [=]value| AVG_ROW_LENGTH [=]value| [DEFAULT] CHARACTER SETcharset_name| CHECKSUM [=] {0 | 1} | COLLATEcollation_name| COMMENT [=] 'string' | CONNECTION [=] 'connect_string' | DATA DIRECTORY [=] 'absolute path to directory' | DELAY_KEY_WRITE [=] {0 | 1} | INDEX DIRECTORY [=] 'absolute path to directory' | INSERT_METHOD [=] { NO | FIRST | LAST } | KEY_BLOCK_SIZE [=]value| MAX_ROWS [=]value| MIN_ROWS [=]value| PACK_KEYS [=] {0 | 1 | DEFAULT} | PASSWORD [=] 'string' | ROW_FORMAT [=] {DEFAULT|DYNAMIC|FIXED|COMPRESSED|REDUNDANT|COMPACT} | UNION [=] (tbl_name[,tbl_name]...)partition_options: PARTITION BY [LINEAR] HASH(expr) | [LINEAR] KEY(column_list) | RANGE(expr) | LIST(expr) [PARTITIONSnum] [SUBPARTITION BY [LINEAR] HASH(expr) | [LINEAR] KEY(column_list) [SUBPARTITIONSnum] ] [(partition_definition[,partition_definition] ...)]partition_definition: PARTITIONpartition_name[VALUES {LESS THAN (expr) |MAXVALUE| IN (value_list)}] [[STORAGE] ENGINE [=]engine_name] [COMMENT [=]'comment_text'] [DATA DIRECTORY [=] ''] [INDEX DIRECTORY [=] 'data_dir'] [MAX_ROWS [=]index_dirmax_number_of_rows] [MIN_ROWS [=]min_number_of_rows] [TABLESPACE [=] (tablespace_name)] [NODEGROUP [=]node_group_id] [(subpartition_definition[,subpartition_definition] ...)]subpartition_definition: SUBPARTITIONlogical_name[[STORAGE] ENGINE [=]engine_name] [COMMENT [=]'comment_text'] [DATA DIRECTORY [=] ''] [INDEX DIRECTORY [=] 'data_dir'] [MAX_ROWS [=]index_dirmax_number_of_rows] [MIN_ROWS [=]min_number_of_rows] [TABLESPACE [=] (tablespace_name)] [NODEGROUP [=]node_group_id]select_statement:[IGNORE | REPLACE] [AS] SELECT ... (Some legal select statement)
CREATE TABLE creates a table with the given
name. You must have the CREATE privilege for
the table.
Rules for allowable table names are given in Section 9.2, “Identifiers”. By default, the table is created in the default database. An error occurs if the table exists, if there is no default database, or if the database does not exist.
The table name can be specified as
db_name.tbl_name to create the table
in a specific database. This works regardless of whether there
is a default database, assuming that the database exists. If you
use quoted identifiers, quote the database and table names
separately. For example, write
`mydb`.`mytbl`, not
`mydb.mytbl`.
You can use the TEMPORARY keyword when
creating a table. A TEMPORARY table is
visible only to the current connection, and is dropped
automatically when the connection is closed. This means that two
different connections can use the same temporary table name
without conflicting with each other or with an existing
non-TEMPORARY table of the same name. (The
existing table is hidden until the temporary table is dropped.)
To create temporary tables, you must have the CREATE
TEMPORARY TABLES privilege.
Note: CREATE
TABLE does not automatically commit the current active
transaction if you use the TEMPORARY keyword.
The keywords IF NOT EXISTS prevent an error
from occurring if the table exists. However, there is no
verification that the existing table has a structure identical
to that indicated by the CREATE TABLE
statement. Note: If you use IF NOT
EXISTS in a CREATE TABLE ... SELECT
statement, any rows selected by the SELECT
part are inserted regardless of whether the table already
exists.
MySQL represents each table by an .frm
table format (definition) file in the database directory. The
storage engine for the table might create other files as well.
In the case of MyISAM tables, the storage
engine creates data and index files. Thus, for each
MyISAM table
tbl_name, there are three disk files:
| File | Purpose |
| Table format (definition) file |
| Data file |
| Index file |
Chapter 14, Storage Engines and Table Types, describes what files each storage engine creates to represent tables. If a table name contains special characters, the names for the table files contain encoded versions of those characters as described in Section 9.2.3, “Mapping of Identifiers to Filenames”.
data_type represents the data type is
a column definition. spatial_type
represents a spatial data type. The data type syntax shown is
representative only. For a full description of the syntax
available for specfiying column data types, as well as
information about the properties of each type, see
Chapter 11, Data Types, and
Chapter 17, Spatial Extensions.
Some attributes do not apply to all data types.
AUTO_INCREMENT applies only to integer types.
DEFAULT does not apply to the
BLOB or TEXT types.
If neither NULL nor NOT
NULL is specified, the column is treated as though
NULL had been specified.
An integer column can have the additional attribute
AUTO_INCREMENT. When you insert a value
of NULL (recommended) or
0 into an indexed
AUTO_INCREMENT column, the column is set
to the next sequence value. Typically this is
, where
value+1value is the largest value for
the column currently in the table.
AUTO_INCREMENT sequences begin with
1.
To retrieve an AUTO_INCREMENT value after
inserting a row, use the LAST_INSERT_ID()
SQL function or the mysql_insert_id() C
API function. See Section 12.11.3, “Information Functions”,
and Section 24.2.3.37, “mysql_insert_id()”.
If the NO_AUTO_VALUE_ON_ZERO SQL mode is
enabled, you can store 0 in
AUTO_INCREMENT columns as
0 without generating a new sequence
value. See Section 5.2.6, “SQL Modes”.
Note: There can be only one
AUTO_INCREMENT column per table, it must
be indexed, and it cannot have a DEFAULT
value. An AUTO_INCREMENT column works
properly only if it contains only positive values. Inserting
a negative number is regarded as inserting a very large
positive number. This is done to avoid precision problems
when numbers “wrap” over from positive to
negative and also to ensure that you do not accidentally get
an AUTO_INCREMENT column that contains
0.
For MyISAM tables, you can specify an
AUTO_INCREMENT secondary column in a
multiple-column key. See
Section 3.6.9, “Using AUTO_INCREMENT”.
To make MySQL compatible with some ODBC applications, you
can find the AUTO_INCREMENT value for the
last inserted row with the following query:
SELECT * FROMtbl_nameWHEREauto_colIS NULL
For information about InnoDB and
AUTO_INCREMENT, see
Section 14.5.6.3, “How AUTO_INCREMENT Columns Work in
InnoDB”.
Character data types (CHAR,
VARCHAR, TEXT) can
include CHARACTER SET and
COLLATE attributes to specify the
character set and collation for the column. For details, see
Chapter 10, Character Set Support. CHARSET is a
synonym for CHARACTER SET. Example:
CREATE TABLE t (c CHAR(20) CHARACTER SET utf8 COLLATE utf8_bin);
MySQL 5.1 interprets length specifications in
character column definitions in characters. (Versions before
MySQL 4.1 interpreted them in bytes.) Lengths for
BINARY and VARBINARY
are in bytes.
The DEFAULT clause specifies a default
value for a column. With one exception, the default value
must be a constant; it cannot be a function or an
expression. This means, for example, that you cannot set the
default for a date column to be the value of a function such
as NOW() or
CURRENT_DATE. The exception is that you
can specify CURRENT_TIMESTAMP as the
default for a TIMESTAMP column. See
Section 11.3.1.1, “TIMESTAMP Properties as of MySQL 4.1”.
If a column definition includes no explicit
DEFAULT value, MySQL determines the
default value as described in
Section 11.1.4, “Data Type Default Values”.
BLOB and TEXT columns
cannot be assigned a default value.
A comment for a column can be specified with the
COMMENT option, up to 255 characters
long. The comment is displayed by the SHOW CREATE
TABLE and SHOW FULL COLUMNS
statements.
KEY is normally a synonym for
INDEX. The key attribute PRIMARY
KEY can also be specified as just
KEY when given in a column definition.
This was implemented for compatibility with other database
systems.
A UNIQUE index creates a constraint such
that all values in the index must be distinct. An error
occurs if you try to add a new row with a key value that
matches an existing row. For all engines, a
UNIQUE index allows multiple
NULL values for columns that can contain
NULL.
A PRIMARY KEY is a unique index where all
key columns must be defined as NOT NULL.
If they are not explicitly declared as NOT
NULL, MySQL declares them so implicitly (and
silently). A table can have only one PRIMARY
KEY. If you do not have a PRIMARY
KEY and an application asks for the
PRIMARY KEY in your tables, MySQL returns
the first UNIQUE index that has no
NULL columns as the PRIMARY
KEY.
In InnoDB tables, having a long
PRIMARY KEY wastes a lot of space. (See
Section 14.5.13, “InnoDB Table and Index Structures”.)
In the created table, a PRIMARY KEY is
placed first, followed by all UNIQUE
indexes, and then the non-unique indexes. This helps the
MySQL optimizer to prioritize which index to use and also
more quickly to detect duplicated UNIQUE
keys.
A PRIMARY KEY can be a multiple-column
index. However, you cannot create a multiple-column index
using the PRIMARY KEY key attribute in a
column specification. Doing so only marks that single column
as primary. You must use a separate PRIMARY
KEY( clause.
index_col_name,
...)
If a PRIMARY KEY or
UNIQUE index consists of only one column
that has an integer type, you can also refer to the column
as _rowid in SELECT
statements.
In MySQL, the name of a PRIMARY KEY is
PRIMARY. For other indexes, if you do not
assign a name, the index is assigned the same name as the
first indexed column, with an optional suffix
(_2, _3,
...) to make it unique. You can see index
names for a table using SHOW INDEX FROM
. See
Section 13.5.4.17, “tbl_nameSHOW INDEX Syntax”.
Some storage engines allow you to specify an index type when
creating an index. The syntax for the
index_type specifier is
USING
.
type_name
Example:
CREATE TABLE lookup (id INT, INDEX USING BTREE (id)) ENGINE = MEMORY;
Before MySQL 5.1.10, USING can be given
only before the index column list. As of 5.1.10, the
preferred position is after the column list. Use of the
option before the column list will no longer be recognized
as of MySQL 5.3.
index_option values specify
additional options for an index. USING is
one such option. For details about allowable
index_option values, see
Section 13.1.7, “CREATE INDEX Syntax”.
For more information about indexes, see Section 7.4.5, “How MySQL Uses Indexes”.
In MySQL 5.1, only the
MyISAM, InnoDB, and
MEMORY storage engines support indexes on
columns that can have NULL values. In
other cases, you must declare indexed columns as
NOT NULL or an error results.
For CHAR, VARCHAR,
BINARY, and VARBINARY
columns, indexes can be created that use only the leading
part of column values, using
syntax to specify an index prefix length.
col_name(length)BLOB and TEXT columns
also can be indexed, but a prefix length
must be given. Prefix lengths are given
in characters for non-binary string types and in bytes for
binary string types. That is, index entries consist of the
first length characters of each
column value for CHAR,
VARCHAR, and TEXT
columns, and the first length
bytes of each column value for BINARY,
VARBINARY, and BLOB
columns. Indexing only a prefix of column values like this
can make the index file much smaller. See
Section 7.4.3, “Column Indexes”.
Only the MyISAM and
InnoDB storage engines support indexing
on BLOB and TEXT
columns. For example:
CREATE TABLE test (blob_col BLOB, INDEX(blob_col(10)));
Prefixes can be up to 1000 bytes long (767 bytes for
InnoDB tables). Note that prefix limits
are measured in bytes, whereas the prefix length in
CREATE TABLE statements is interpreted as
number of characters for non-binary data types
(CHAR, VARCHAR,
TEXT). Take this into account when
specifying a prefix length for a column that uses a
multi-byte character set.
An index_col_name specification
can end with ASC or
DESC. These keywords are allowed for
future extensions for specifying ascending or descending
index value storage. Currently, they are parsed but ignored;
index values are always stored in ascending order.
When you use ORDER BY or GROUP
BY on a TEXT or
BLOB column in a
SELECT, the server sorts values using
only the initial number of bytes indicated by the
max_sort_length system variable. See
Section 11.4.3, “The BLOB and TEXT Types”.
You can create special FULLTEXT indexes,
which are used for full-text searches. Only the
MyISAM storage engine supports
FULLTEXT indexes. They can be created
only from CHAR,
VARCHAR, and TEXT
columns. Indexing always happens over the entire column;
column prefix indexing is not supported and any prefix
length is ignored if specified. See
Section 12.8, “Full-Text Search Functions”, for details of operation.
A WITH PARSER clause can be specified as
an index_option value to
associate a parser plugin with the index if full-text
indexing and searching operations need special handling.
This clause is legal only for FULLTEXT
indexes. See Section 26.2, “The MySQL Plugin Interface”, for details on
creating plugins.
You can create SPATIAL indexes on spatial
data types. Spatial types are supported only for
MyISAM tables and indexed columns must be
declared as NOT NULL. See
Chapter 17, Spatial Extensions.
InnoDB tables support checking of foreign
key constraints. See Section 14.5, “The InnoDB Storage Engine”. Note that the
FOREIGN KEY syntax in
InnoDB is more restrictive than the
syntax presented for the CREATE TABLE
statement at the beginning of this section: The columns of
the referenced table must always be explicitly named.
InnoDB supports both ON
DELETE and ON UPDATE actions on
foreign keys. For the precise syntax, see
Section 14.5.6.4, “FOREIGN KEY Constraints”.
For other storage engines, MySQL Server parses and ignores
the FOREIGN KEY and
REFERENCES syntax in CREATE
TABLE statements. The CHECK
clause is parsed but ignored by all storage engines. See