Table of Contents
This chapter describes the syntax for most of the SQL statements supported by MySQL. Additional statement descriptions can be found in the following chapters:
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 20, Views.
ALTER {DATABASE | SCHEMA} [db_name]
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 as of MySQL 5.0.2.
The CHARACTER SET clause changes the default
database character set. The COLLATE clause
changes the default database collation.
Section 9.1, “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 Enterprise Monitor 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]col_namecolumn_definition[FIRST | AFTERcol_name] | ADD [COLUMN] (col_namecolumn_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|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_namenew_col_namecolumn_definition[FIRST|AFTERcol_name] | MODIFY [COLUMN]col_namecolumn_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 TABLESPACEindex_col_name:col_name[(length)] [ASC | DESC]index_type: USING {BTREE | HASH | RTREE}
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 12.1.5, “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 12.5.4.28, “SHOW WARNINGS Syntax”.
If you use ALTER TABLE to change a column
specification but DESCRIBE
indicates that
your column was not changed, it is possible that MySQL ignored
your modification for one of the reasons described in
Section 12.1.5.1, “Silent Column Specification Changes”.
tbl_name
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. The temporary table is created in
the database directory of the new table. This can be different
from the database directory of the original table if
ALTER TABLE is renaming the table to a
different database.
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 12.1.9, “RENAME TABLE Syntax”.) Any privileges granted
specifically for the renamed table are not migrated to the new
name. They must be changed manually.
If you use any option to ALTER TABLE other
than RENAME, MySQL always 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.
For information on troubleshooting ALTER
TABLE, see Section B.1.7.1, “Problems with ALTER TABLE”.
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, such as
ENGINE,
AUTO_INCREMENT, or
AVG_ROW_LENGTH.
(Section 12.1.5, “CREATE TABLE Syntax”, lists all table options.)
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;
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.6, “SQL Modes”.
As of MySQL 5.0.23, 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, you can use ALTER TABLE
... AUTO_INCREMENT =
as of MySQL
5.0.3, but if the value is less than the current
maximum value in the column, no error occurs and the current
sequence value is not changed.
value
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. See Section 12.1.5, “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_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.
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.6, “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_nameFIRST 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 10.1.4, “Data Type Default Values”.
DROP INDEX removes an index. This is a
MySQL extension to standard SQL. See
Section 12.1.7, “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 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.
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
. For details
about type_nameUSING, see
Section 12.1.4, “CREATE INDEX Syntax”.
After an ALTER TABLE statement, it may be
necessary to run ANALYZE TABLE to update
index cardinality information. See
Section 12.5.4.13, “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 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.
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. The same is true for
BDB tables that contain a user-defined
PRIMARY KEY.
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 for a
MyISAM table. ALTER TABLE ...
DISABLE KEYS tells MySQL to stop updating
non-unique 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 non-unique indexes are disabled, they are ignored
for statements such as SELECT and
EXPLAIN that otherwise would use them.
If ALTER TABLE for an
InnoDB table results in changes to column
values (for example, because a column is truncated),
InnoDB's FOREIGN KEY
constraint checks do not notice possible violations caused
by changing the values.
The FOREIGN KEY and
REFERENCES clauses are supported by the
InnoDB storage engine, which implements
ADD [CONSTRAINT
[. See
Section 13.2.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 12.1.5, “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”.
The inline REFERENCES specifications
where the references are defined as part of the column
specification are silently ignored by
InnoDB. InnoDB only accepts
REFERENCES clauses defined as part of a
separate FOREIGN KEY specification.
InnoDB supports the use of ALTER
TABLE to drop foreign keys:
ALTER TABLEtbl_nameDROP FOREIGN KEYfk_symbol;
For more information, see
Section 13.2.6.4, “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 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;
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;
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
3 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_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 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, and (when
IGNORE is used) how many rows were deleted
due to duplication of unique key values. See
Section 23.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 an index on column d and a
UNIQUE index on column a:
ALTER TABLE t2 ADD INDEX (d), ADD UNIQUE (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 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 12.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;
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;
CREATE {DATABASE | SCHEMA} [IF NOT EXISTS] db_name
[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 as of MySQL 5.0.2.
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.
Section 9.1, “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 8.2, “Schema Object Names”.
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 4.5.2, “mysqladmin — Client for Administering a MySQL Server”.
CREATE [UNIQUE|FULLTEXT|SPATIAL] INDEXindex_name[index_type] ONtbl_name(index_col_name,...)index_col_name:col_name[(length)] [ASC | DESC]index_type: USING {BTREE | HASH | RTREE}
CREATE INDEX is mapped to an ALTER
TABLE statement to create indexes. See
Section 12.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 12.1.5, “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. This constraint does not apply to NULL
values except for the BDB storage engine. For
other 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.
MySQL Enterprise. Lack of proper indexes can greatly reduce performance. Subscribe to the MySQL Enterprise Monitor for notification of inefficient use of indexes. For more information see http://www.mysql.com/products/enterprise/advisors.html.
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 11.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.0, the full width of each column is
indexed by default, but column prefix lengths are allowed.
However, as of MySQL 5.0.40, the length is not displayed in
SHOW CREATE TABLE output.
mysqldump uses that statement. As of that
version, if a table with SPATIAL indexes
containing prefixed columns is dumped and reloaded, the
index is created with no prefixes. (The full column 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.0:
You can add an index on a column that can have
NULL values only if you are using the
MyISAM, InnoDB,
BDB, or MEMORY storage
engine.
You can add an index on a BLOB or
TEXT column only if you are using the
MyISAM, BDB, 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.
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, RTREE |
InnoDB | BTREE |
MEMORY/HEAP | HASH, BTREE |
NDB | HASH |
The RTREE index type is allowable only for
SPATIAL indexes.
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.
CREATE [TEMPORARY] TABLE [IF NOT EXISTS]tbl_name(create_definition,...) [table_option...]
Or:
CREATE [TEMPORARY] TABLE [IF NOT EXISTS]tbl_name[(create_definition,...)] [table_option...]select_statement
Or:
CREATE [TEMPORARY] TABLE [IF NOT EXISTS]tbl_name{ LIKEold_tbl_name| (LIKEold_tbl_name) }
create_definition:col_namecolumn_definition| [CONSTRAINT [symbol]] PRIMARY KEY [index_type] (index_col_name,...) | {INDEX|KEY} [index_name] [index_type] (index_col_name,...) | [CONSTRAINT [symbol]] UNIQUE [INDEX|KEY] [index_name] [index_type] (index_col_name,...) | {FULLTEXT|SPATIAL} [INDEX|KEY] [index_name] (index_col_name,...) | [CONSTRAINT [symbol]] FOREIGN KEY [index_name] (index_col_name,...)reference_definition| CHECK (expr)column_definition:data_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 | RTREE}reference_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: {ENGINE|TYPE} [=]engine_name| AUTO_INCREMENT [=]value| AVG_ROW_LENGTH [=]value| [DEFAULT] CHARACTER SETcharset_name| CHECKSUM [=] {0 | 1} | [DEFAULT] 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 } | 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]...)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 8.2, “Schema Object Names”. 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.
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.
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 13, Storage Engines, describes what files each storage engine creates to represent tables.
data_type represents the data type in
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 specifying column data types, as well as
information about the properties of each type, see
Chapter 10, 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 11.10.3, “Information Functions”, and
Section 23.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.1.6, “SQL Modes”.
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 and BDB
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 13.2.6.3, “How AUTO_INCREMENT Handling Works 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
Section 9.1, “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.0 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 10.3.1.1, “TIMESTAMP Properties”.
If a column definition includes no explicit
DEFAULT value, MySQL determines the
default value as described in
Section 10.1.4, “Data Type Default Values”.
BLOB and TEXT columns
cannot be assigned a default value.
CREATE TABLE fails if a date-valued
default is not correct according to the
NO_ZERO_IN_DATE SQL mode, even if strict
SQL mode is not enabled. For example, c1 DATE
DEFAULT '2010-00-00' causes CREATE
TABLE to fail with Invalid default value
for 'c1'.
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. This constraint does not apply to
NULL values except for the
BDB storage engine. For other 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 13.2.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 12.5.4.13, “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;
For details about USING, see
Section 12.1.4, “CREATE INDEX Syntax”.
For more information about indexes, see Section 7.4.5, “How MySQL Uses Indexes”.
In MySQL 5.0, only the
MyISAM, InnoDB,
BDB, 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, BDB,
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 10.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 11.8, “Full-Text Search Functions”, for details of operation.
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 13.2, “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 13.2.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
Section 1.8.5.4, “Foreign Keys”.
The inline REFERENCES specifications
where the references are defined as part of the column
specification are silently ignored by
InnoDB. InnoDB only accepts
REFERENCES clauses when specified as
part of a separate FOREIGN KEY
specification.
There is a hard limit of 4096 columns per table, but the effective maximum may be less for a given table and depends on the factors discussed in Section F.7.2, “The Maximum Number of Columns Per Table”.
The ENGINE table option specifies the storage
engine for the table. TYPE is a synonym, but
ENGINE is the preferred option name.
The ENGINE table option takes the storage
engine names shown in the following table.
| Storage Engine | Description |
ARCHIVE | The archiving storage engine. See
Section 13.8, “The ARCHIVE Storage Engine”. |
BDB | Transaction-safe tables with page locking. Also known as
BerkeleyDB. See
Section 13.5, “The BDB (BerkeleyDB) Storage
Engine”. |
CSV | Tables that store rows in comma-separated values format. See
Section 13.9, “The CSV Storage Engine”. |
EXAMPLE | An example engine. See Section 13.6, “The EXAMPLE Storage Engine”. |
FEDERATED | Storage engine that accesses remote tables. See
Section 13.7, “The FEDERATED Storage Engine”. |
HEAP | This is a synonym for MEMORY. |
ISAM (OBSOLETE) | Not available in MySQL 5.0. If you are upgrading to MySQL
5.0 from a previous version, you should
convert any existing ISAM tables to
MyISAM before
performing the upgrade. |
InnoDB | Transaction-safe tables with row locking and foreign keys. See
Section 13.2, “The InnoDB Storage Engine”. |
MEMORY | The data for this storage engine is stored only in memory. See
Section 13.4, “The MEMORY (HEAP) Storage Engine”. |
MERGE | A collection of MyISAM tables used as one table. Also
known as MRG_MyISAM. See
Section 13.3, “The MERGE Storage Engine”. |
MyISAM | The binary portable storage engine that is the default storage engine
used by MySQL. See
Section 13.1, “The MyISAM Storage Engine”. |
NDBCLUSTER | Clustered, fault-tolerant, memory-based tables. Also known as
NDB. See
Chapter 16, MySQL Cluster. |
If a storage engine is specified that is not available, MySQL
uses the default engine instead. Normally, this is
MyISAM. For example, if a table definition
includes the ENGINE=BDB option but the MySQL
server does not support BDB tables, the table
is created as a MyISAM table. This makes it
possible to have a replication setup where you have
transactional tables on the master but tables created on the
slave are non-transactional (to get more speed). In MySQL
5.0, a warning occurs if the storage engine
specification is not honored.
Engine substitution can be controlled by the setting of the
NO_ENGINE_SUBSTITUTION SQL mode, as described
in Section 5.1.6, “SQL Modes”.
The other table options are used to optimize the behavior of the
table. In most cases, you do not have to specify any of them.
These options apply to all storage engines unless otherwise
indicated. Options that do not apply to a given storage engine
may be accepted and remembered as part of the table definition.
Such options then apply if you later use ALTER
TABLE to convert the table to use a different storage
engine.
AUTO_INCREMENT
The initial AUTO_INCREMENT value for the
table. In MySQL 5.0, this works for
MyISAM and MEMORY
tables. It is also supported for InnoDB
as of MySQL 5.0.3. To set the first auto-increment value for
engines that do not support the
AUTO_INCREMENT table option, insert a
“dummy” row with a value one less than the
desired value after creating the table, and then delete the
dummy row.
For engines that support the
AUTO_INCREMENT table option in
CREATE TABLE statements, you can also use
ALTER TABLE to
reset the tbl_name
AUTO_INCREMENT = NAUTO_INCREMENT value. The value
cannot be set lower than the maximum value currently in the
column.
AVG_ROW_LENGTH
An approximation of the average row length for your table. You need to set this only for large tables with variable-size rows.
When you create a MyISAM table, MySQL
uses the product of the MAX_ROWS and
AVG_ROW_LENGTH options to decide how big
the resulting table is. If you don't specify either option,
the maximum size for a table is 256TB of data by default
(4GB before MySQL 5.0.6). (If your operating system does not
support files that large, table sizes are constrained by the
file size limit.) If you want to keep down the pointer sizes
to make the index smaller and faster and you don't really
need big files, you can decrease the default pointer size by
setting the myisam_data_pointer_size
system variable, which was added in MySQL 4.1.2. (See
Section 5.1.3, “System Variables”.) If you want all
your tables to be able to grow above the default limit and
are willing to have your tables slightly slower and larger
than necessary, you can increase the default pointer size by
setting this variable. Setting the value to 7 allows table
sizes up to 65,536TB.
[DEFAULT] CHARACTER SET
Specify a default character set for the table.
CHARSET is a synonym for
CHARACTER SET. If the character set name
is DEFAULT, the database character set is
used.
CHECKSUM
Set this to 1 if you want MySQL to maintain a live checksum
for all rows (that is, a checksum that MySQL updates
automatically as the table changes). This makes the table a
little slower to update, but also makes it easier to find
corrupted tables. The CHECKSUM TABLE
statement reports the checksum. (MyISAM
only.)
[DEFAULT] COLLATE
Specify a default collation for the table.
COMMENT
A comment for the table, up to 60 characters long.
CONNECTION
The connection string for a FEDERATED
table. This option is available as of MySQL 5.0.13; before
that, use a COMMENT option for the
connection string.
DATA DIRECTORY, INDEX
DIRECTORY
By using DATA
DIRECTORY='
or directory'INDEX
DIRECTORY='
you can specify where the directory'MyISAM storage
engine should put a table's data file and index file. The
directory must be the full pathname to the directory, not a
relative path.
These options work only when you are not using the
--skip-symbolic-links option. Your
operating system must also have a working, thread-safe
realpath() call. See
Section 7.6.1.2, “Using Symbolic Links for Tables on Unix”, for more
complete information.
If a MyISAM table is created with no
DATA DIRECTORY option, the
.MYD file is created in the database
directory. By default, if MyISAM finds an
existing .MYD file in this case, it
overwrites it. The same applies to .MYI
files for tables created with no INDEX
DIRECTORY option. As of MySQL 5.0.48, to suppress
this behavior, start the server with the
--keep_files_on_create option, in which
case MyISAM will not overwrite existing
files and returns an error instead.
If a MyISAM table is created with a
DATA DIRECTORY or INDEX
DIRECTORY option and an existing
.MYD or .MYI file
is found, MyISAM always returns an error. It will not
overwrite a file in the specified directory.
DELAY_KEY_WRITE
Set this to 1 if you want to delay key updates for the table
until the table is closed. See the description of the
delay_key_write system variable in
Section 5.1.3, “System Variables”.
(MyISAM only.)
INSERT_METHOD
If you want to insert data into a MERGE
table, you must specify with
INSERT_METHOD the table into which the
row should be inserted. INSERT_METHOD is
an option useful for MERGE tables only.
Use a value of FIRST or
LAST to have inserts go to the first or
last table, or a value of NO to prevent
inserts. See Section 13.3, “The MERGE Storage Engine”.
MAX_ROWS
The maximum number of rows you plan to store in the table. This is not a hard limit, but rather a hint to the storage engine that the table must be able to store at least this many rows.
MIN_ROWS
The minimum number of rows you plan to store in the table.
PACK_KEYS
PACK_KEYS takes effect only with
MyISAM tables. Set this option to 1 if
you want to have smaller indexes. This usually makes updates
slower and reads faster. Setting the option to 0 disables
all packing of keys. Setting it to
DEFAULT tells the storage engine to pack
only long CHAR,
VARCHAR, BINARY, or
VARBINARY columns.
If you do not use PACK_KEYS, the default
is to pack strings, but not numbers. If you use
PACK_KEYS=1, numbers are packed as well.
When packing binary number keys, MySQL uses prefix compression:
Every key needs one extra byte to indicate how many bytes of the previous key are the same for the next key.
The pointer to the row is stored in high-byte-first order directly after the key, to improve compression.
This means that if you have many equal keys on two
consecutive rows, all following “same” keys
usually only take two bytes (including the pointer to the
row). Compare this to the ordinary case where the following
keys takes storage_size_for_key +
pointer_size (where the pointer size is usually
4). Conversely, you get a significant benefit from prefix
compression only if you have many numbers that are the same.
If all keys are totally different, you use one byte more per
key, if the key is not a key that can have
NULL values. (In this case, the packed
key length is stored in the same byte that is used to mark
if a key is NULL.)
PASSWORD
This option is unused. If you have a need to scramble your
.frm files and make them unusable to
any other MySQL server, please contact our sales department.
ROW_FORMAT
Defines how the rows should be stored. For
MyISAM tables, the option value can be
FIXED or DYNAMIC for
static or variable-length row format.
myisampack sets the type to
COMPRESSED. See
Section 13.1.3, “MyISAM Table Storage Formats”.
Starting with MySQL 5.0.3, for InnoDB
tables, rows are stored in compact format
(ROW_FORMAT=COMPACT) by default. The
non-compact format used in older versions of MySQL can still
be requested by specifying
ROW_FORMAT=REDUNDANT.
During CREATE TABLE, if you specify a
row format that the engine does support, the table will be
created using the storage engines default row format. The
information reported in this column in response to
SHOW TABLE STATUS is the actual row
format used. This may differ from the value in the
Create_options column because the
original CREATE TABLE definition is
retained during creation.
RAID_TYPE
RAID support has been removed as of MySQL
5.0. For information on RAID, see
http://dev.mysql.com/doc/refman/4.1/en/create-table.html.
UNION
UNION is used when you want to access a
collection of identical MyISAM tables as
one. This works only with MERGE tables.
See Section 13.3, “The MERGE Storage Engine”.
You must have SELECT,
UPDATE, and DELETE
privileges for the tables you map to a
MERGE table.
Formerly, all tables used had to be in the same database
as the MERGE table itself. This
restriction no longer applies.
The original CREATE TABLE statement,
including all specifications and table options are stored by
MySQL when the table is created. The information is retained
so that if you change storage engines, collations or other
settings using an ALTER TABLE statement,
the original table options specified are retained. This allows
you to change between InnoDB and
MyISAM table types even though the row
formats supported by the two engines are different.
Because the text of the original statement is retained, but
due to the way that certain values and options may be silently
reconfigured (such as the ROW_FORMAT), the
active table definition (accessible through
DESCRIBE or with SHOW TABLE
STATUS and the table creation string (accessible
through SHOW CREATE TABLE) will report
different values.
You can create one table from another by adding a
SELECT statement at the end of the
CREATE TABLE statement:
CREATE TABLEnew_tblSELECT * FROMorig_tbl;
MySQL creates new columns for all elements in the
SELECT. For example:
mysql>CREATE TABLE test (a INT NOT NULL AUTO_INCREMENT,->PRIMARY KEY (a), KEY(b))->ENGINE=MyISAM SELECT b,c FROM test2;
This creates a MyISAM table with three
columns, a, b, and
c. Notice that the columns from the
SELECT statement are appended to the right
side of the table, not overlapped onto it. Take the following
example:
mysql>SELECT * FROM foo;+---+ | n | +---+ | 1 | +---+ mysql>CREATE TABLE bar (m INT) SELECT n FROM foo;Query OK, 1 row affected (0.02 sec) Records: 1 Duplicates: 0 Warnings: 0 mysql>SELECT * FROM bar;+------+---+ | m | n | +------+---+ | NULL | 1 | +------+---+ 1 row in set (0.00 sec)
For each row in table foo, a row is inserted
in bar with the values from
foo and default values for the new columns.
In a table resulting from CREATE TABLE ...
SELECT, columns named only in the CREATE
TABLE part come first. Columns named in both parts or
only in the SELECT part come after that. The
data type of SELECT columns can be overridden
by also specifying the column in the CREATE
TABLE part.
If any errors occur while copying the data to the table, it is automatically dropped and not created.
CREATE TABLE ... SELECT does not
automatically create any indexes for you. This is done
intentionally to make the statement as flexible as possible. If
you want to have indexes in the created table, you should
specify these before the SELECT statement:
mysql> CREATE TABLE bar (UNIQUE (n)) SELECT n FROM foo;
Some conversion of data types might occur. For example, the
AUTO_INCREMENT attribute is not preserved,
and VARCHAR columns can become
CHAR columns.
When creating a table with CREATE ... SELECT,
make sure to alias any function calls or expressions in the
query. If you do not, the CREATE statement
might fail or result in undesirable column names.
CREATE TABLE artists_and_works SELECT artist.name, COUNT(work.artist_id) AS number_of_works FROM artist LEFT JOIN work ON artist.id = work.artist_id GROUP BY artist.id;
You can also explicitly specify the data type for a generated column:
CREATE TABLE foo (a TINYINT NOT NULL) SELECT b+1 AS a FROM bar;
Use LIKE to create an empty table based on
the definition of another table, including any column attributes
and indexes defined in the original table:
CREATE TABLEnew_tblLIKEorig_tbl;
The copy is created using the same version of the table storage
format as the original table. The SELECT
privilege is required on the original table.
CREATE TABLE ... LIKE does not preserve any
DATA DIRECTORY or INDEX
DIRECTORY table options that were specified for the
original table, or any foreign key definitions.
You can precede the SELECT by
IGNORE or REPLACE to
indicate how to handle rows that duplicate unique key values.
With IGNORE, new rows that duplicate an
existing row on a unique key value are discarded. With
REPLACE, new rows replace rows that have the
same unique key value. If neither IGNORE nor
REPLACE is specified, duplicate unique key
values result in an error.
To ensure that the binary log can be used to re-create the
original tables, MySQL does not allow concurrent inserts during
CREATE TABLE ... SELECT.
In some cases, MySQL silently changes column specifications
from those given in a CREATE TABLE or
ALTER TABLE statement. These might be
changes to a data type, to attributes associated with a data
type, or to an index specification.
Some silent column specification changes include modifications to attribute or index specifications:
TIMESTAMP display sizes are discarded.
Also note that TIMESTAMP columns are
NOT NULL by default.
Columns that are part of a PRIMARY KEY
are made NOT NULL even if not declared
that way.
Trailing spaces are automatically deleted from
ENUM and SET member
values when the table is created.
MySQL maps certain data types used by other SQL database vendors to MySQL types. See Section 10.7, “Using Data Types from Other Database Engines”.
If you include a USING clause to
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.
Possible data type changes are given in the following list. These occur only up to the versions listed. After that, an error occurs if a column cannot be created using the specified data type.
Before MySQL 5.0.3, VARCHAR columns
with a length less than four are changed to
CHAR.
Before MySQL 5.0.3, if any column in a table has a
variable length, the entire row becomes variable-length as
a result. Therefore, if a table contains any
variable-length columns (VARCHAR,
TEXT, or BLOB), all
CHAR columns longer than three
characters are changed to VARCHAR
columns. This does not affect how you use the columns in
any way; in MySQL, VARCHAR is just a
different way to store characters. MySQL performs this
conversion because it saves space and makes table
operations faster. See Chapter 13, Storage Engines.
Before MySQL 5.0.3, a CHAR or
VARCHAR column with a length
specification greater than 255 is converted to the
smallest TEXT type that can hold values
of the given length. For example,
VARCHAR(500) is converted to
TEXT, and
VARCHAR(200000) is converted to
MEDIUMTEXT. Similar conversions occur
for BINARY and
VARBINARY, except that they are
converted to a BLOB type.
Note that these conversions result in a change in behavior with regard to treatment of trailing spaces.
As of MySQL 5.0.3, a CHAR or
BINARY column with a length
specification greater than 255 is not silently converted.
Instead, an error occurs. From MySQL 5.0.6 on, silent
conversion of VARCHAR and
VARBINARY columns with a length
specification greater than 65535 does not occur if strict
SQL mode is enabled. Instead, an error occurs.
Before MySQL 5.0.10, for a specification of
DECIMAL(,
if M,D)M is not larger than
D, it is adjusted upward. For
example, DECIMAL(10,10) becomes
DECIMAL(11,10). As of MySQL 5.0.10,
DECIMAL(10,10) is created as specified.
To see whether MySQL used a data type other than the one you
specified, issue a DESCRIBE or
SHOW CREATE TABLE statement after creating
or altering the table.
Certain other data type changes can occur if you compress a table using myisampack. See Section 13.1.3.3, “Compressed Table Characteristics”.
DROP {DATABASE | SCHEMA} [IF EXISTS] db_name
DROP DATABASE drops all tables in the
database and deletes the database. Be very
careful with this statement! To use DROP
DATABASE, you need the DROP
privilege on the database. DROP SCHEMA is a
synonym for DROP DATABASE as of MySQL 5.0.2.
When a database is dropped, user privileges on the database
are not automatically dropped. See
Section 12.5.1.3, “GRANT Syntax”.
IF EXISTS is used to prevent an error from
occurring if the database does not exist.
If you use DROP DATABASE on a symbolically
linked database, both the link and the original database are
deleted.
DROP DATABASE returns the number of tables
that were removed. This corresponds to the number of
.frm files removed.
The DROP DATABASE statement removes from the
given database directory those files and directories that MySQL
itself may create during normal operation:
All files with these extensions:
.BAK | .DAT | .HSH | .MRG |
.MYD | .MYI | .TRG | .TRN |
.db | .frm | .ibd | .ndb |
All subdirectories with names that consist of two hex digits
00-ff. These are
subdirectories used for RAID tables.
(These directories are not removed as of MySQL 5.0, when
support for RAID tables was removed. You
should convert any existing RAID tables
and remove these directories manually before upgrading to
MySQL 5.0. See Section 2.4.17.2, “Upgrading from MySQL 4.1 to 5.0”.)
The db.opt file, if it exists.
If other files or directories remain in the database directory
after MySQL removes those just listed, the database directory
cannot be removed. In this case, you must remove any remaining
files or directories manually and issue the DROP
DATABASE statement again.
You can also drop databases with mysqladmin. See Section 4.5.2, “mysqladmin — Client for Administering a MySQL Server”.
DROP INDEXindex_nameONtbl_name
DROP INDEX drops the index named
index_name from the table
tbl_name. This statement is mapped to
an ALTER TABLE statement to drop the index.
See Section 12.1.2, “ALTER TABLE Syntax”.
DROP [TEMPORARY] TABLE [IF EXISTS]
tbl_name [, tbl_name] ...
[RESTRICT | CASCADE]
DROP TABLE removes one or more tables. You
must have the DROP privilege for each table.
All table data and the table definition are
removed, so be careful
with this statement! If any of the tables named in the argument
list do not exist, MySQL returns an error indicating by name
which non-existing tables it was unable to drop, but it also
drops all of the tables in the list that do exist.
When a table is dropped, user privileges on the table are
not automatically dropped. See
Section 12.5.1.3, “GRANT Syntax”.
Use IF EXISTS to prevent an error from
occurring for tables that do not exist. A
NOTE is generated for each non-existent table
when using IF EXISTS. See
Section 12.5.4.28, “SHOW WARNINGS Syntax”.
RESTRICT and CASCADE are
allowed to make porting easier. In MySQL 5.0, they
do nothing.
DROP TABLE automatically commits the
current active transaction, unless you use the
TEMPORARY keyword.
The TEMPORARY keyword has the following
effects:
The statement drops only TEMPORARY
tables.
The statement does not end an ongoing transaction.
No access rights are checked. (A
TEMPORARY table is visible only to the
client that created it, so no check is necessary.)
Using TEMPORARY is a good way to ensure that
you do not accidentally drop a non-TEMPORARY
table.
RENAME TABLEtbl_nameTOnew_tbl_name[,tbl_name2TOnew_tbl_name2] ...
This statement renames one or more tables.
The rename operation is done atomically, which means that no
other thread can access any of the tables while the rename is
running. For example, if you have an existing table
old_table, you can create another table
new_table that has the same structure but is
empty, and then replace the existing table with the empty one as
follows (assuming that backup_table does not
already exist):
CREATE TABLE new_table (...); RENAME TABLE old_table TO backup_table, new_table TO old_table;
If the statement renames more than one table, renaming
operations are done from left to right. If you want to swap two
table names, you can do so like this (assuming that
tmp_table does not already exist):
RENAME TABLE old_table TO tmp_table,
new_table TO old_table,
tmp_table TO new_table;
As long as two databases are on the same filesystem, you can use
RENAME TABLE to move a table from one
database to another:
RENAME TABLEcurrent_db.tbl_nameTOother_db.tbl_name;
Beginning with MySQL 5.0.2, if there are any triggers associated
with a table which is moved to a different database using
RENAME TABLE, then the statement fails with
the error Trigger in wrong schema.
As of MySQL 5.0.14, RENAME TABLE also works
for views, as long as you do not try to rename a view into a
different database.
Any privileges granted specifically for the renamed table or view are not migrated to the new name. They must be changed manually.
When you execute RENAME, you cannot have any
locked tables or active transactions. You must also have the
ALTER and DROP privileges
on the original table, and the CREATE and
INSERT privileges on the new table.
If MySQL encounters any errors in a multiple-table rename, it does a reverse rename for all renamed tables to return everything to its original state.