Chapter 13. SQL Statement Syntax

MySQL 5.0

Chapter 13. SQL Statement Syntax

This chapter describes the syntax for most of the SQL statements supported by MySQL. Additional statement descriptions can be found in the following chapters:

13.1. Data Definition Statements

13.1.1. ALTER DATABASE Syntax

ALTER {DATABASE | SCHEMA} []
     [, ] ...

:
    [DEFAULT] CHARACTER SET 
  | [DEFAULT] COLLATE 

enables you to change the overall characteristics of a database. These characteristics are stored in the file in the database directory. To use , you need the privilege on the database. is a synonym for as of MySQL 5.0.2.

The clause changes the default database character set. The 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.

13.1.2. ALTER TABLE Syntax

ALTER [IGNORE] TABLE 
     [, ] ...

:
    ADD [COLUMN]  [FIRST | AFTER  ]
  | ADD [COLUMN] (,...)
  | ADD {INDEX|KEY} [] [] (,...)
  | ADD [CONSTRAINT []]
        PRIMARY KEY [] (,...)
  | ADD [CONSTRAINT []]
        UNIQUE [INDEX|KEY] [] [] (,...)
  | ADD [FULLTEXT|SPATIAL] [INDEX|KEY] [] (,...)
  | ADD [CONSTRAINT []]
        FOREIGN KEY [] (,...)
        []
  | ALTER [COLUMN]  {SET DEFAULT  | DROP DEFAULT}
  | CHANGE [COLUMN]  
        [FIRST|AFTER ]
  | MODIFY [COLUMN]  [FIRST | AFTER ]
  | DROP [COLUMN] 
  | DROP PRIMARY KEY
  | DROP {INDEX|KEY} 
  | DROP FOREIGN KEY 
  | DISABLE KEYS
  | ENABLE KEYS
  | RENAME [TO] 
  | ORDER BY 
  | CONVERT TO CHARACTER SET  [COLLATE ]
  | [DEFAULT] CHARACTER SET  [COLLATE ]
  | DISCARD TABLESPACE
  | IMPORT TABLESPACE
  |  ...

:
     [()] [ASC | DESC]

:
    USING {BTREE | HASH}

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 statement. This includes modifications, for options such as , , and . (However, ignores the and table options.) Section 13.1.5, “ Syntax”, lists all table options. As of MySQL 5.0.23, to prevent inadvertent loss of data, cannot be used to change the storage engine of a table to or .

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 . See Section 13.5.4.25, “ Syntax”.

If you use to change a column specification but indicates that your column was not changed, it is possible that MySQL ignored your modification for one of the reasons described in Section 13.1.5.1, “Silent Column Specification Changes”.

In most cases, 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 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.

If you use RENAME TO without any other options, MySQL simply renames any files that correspond to the table . There is no need to create a temporary table. (You can also use the statement to rename tables. See Section 13.1.9, “ Syntax”.)

If you use any option to other than , 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 tables, you can speed up the index re-creation operation (which is the slowest part of the alteration process) by setting the system variable to a high value.

  • To use , you need , , and privileges for the table.

  • is a MySQL extension to standard SQL. It controls how works if there are duplicates on unique keys in the new table or if warnings occur when strict mode is enabled. If is not specified, the copy is aborted and rolled back if duplicate-key errors occur. If 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.

  • You can issue multiple , , , and clauses in a single statement, separated by commas. This is a MySQL extension to standard SQL, which allows only one of each clause per statement. For example, to drop multiple columns in a single statement, do this:

    ALTER TABLE t2 DROP COLUMN c, DROP COLUMN d;
    
  • , , and are MySQL extensions to standard SQL.

  • is an Oracle extension to .

  • The word is optional and can be omitted.

  • clauses use the same syntax for and as for . Note that this syntax includes the column name, not just its data type. See Section 13.1.5, “ Syntax”.

  • You can rename a column using a clause. To do so, specify the old and new column names and the type that the column currently has. For example, to rename an column from to , you can do this:

    ALTER TABLE t1 CHANGE a b INTEGER;
    

    If you want to change a column's type but not the name, 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 to change a column's type without renaming it:

    ALTER TABLE t1 MODIFY b BIGINT NOT NULL;
    
  • If you use or 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 or , 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 or . The default is to add the column last. You can also use and in or operations.

  • or 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 , the new default is . If the column cannot be , MySQL assigns a default value, as described in Section 11.1.4, “Data Type Default Values”.

  • removes an index. This is a MySQL extension to standard SQL. See Section 13.1.7, “ 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 instead.

  • drops the primary index. Note: In older versions of MySQL, if no primary index existed, would drop the first index in the table. This is not the case in MySQL 5.0, where trying to use on a table with no primary key results in an error.

    If you add a or 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 specifier is . For details about , see Section 13.1.4, “ Syntax”.

  • 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.

  • If you use on a table, all non-unique indexes are created in a separate batch (as for ). This should make much faster when you have many indexes.

    This feature can be activated explicitly. tells MySQL to stop updating non-unique indexes for a table. 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 requires the privilege in addition to the privileges mentioned earlier.

  • The and clauses are supported by the storage engine, which implements ]] FOREIGN KEY (...) REFERENCES ... (...). See Section 14.2.6.4, “ Constraints”. For other storage engines, the clauses are parsed but ignored. The clause is parsed but ignored by all storage engines. See Section 13.1.5, “ 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 statement. You must use separate statements.

  • supports the use of to drop foreign keys:

    ALTER TABLE  DROP FOREIGN KEY ;
    

    You cannot add a foreign key and drop a foreign key in separate clauses of a single statement. You must use separate statements.

    For more information, see Section 14.2.6.4, “ Constraints”.

  • Pending statements are lost if a table is write locked and is used to modify the table structure.

  • If you want to change the table default character set and all character columns (, , ) to a new character set, use a statement like this:

    ALTER TABLE  CONVERT TO CHARACTER SET ;
    

    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 ) but the stored values actually use some other, incompatible character set (like ). 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 columns.

    If you specify , the , , and columns are converted to their corresponding binary string types (, , ). This means that the columns no longer will have a character set and a subsequent operation will not apply to them.

    To change only the default character set for a table, use this statement:

    ALTER TABLE  DEFAULT CHARACTER SET ;
    

    The word 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 ).

  • For an table that is created with its own tablespace in an file, that file can be discarded and imported. To discard the file, use this statement:

    ALTER TABLE  DISCARD TABLESPACE;
    

    This deletes the current 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 file back into the table, copy it into the database directory, and then issue this statement:

    ALTER TABLE  IMPORT TABLESPACE;
    

    See Section 14.2.3.1, “Using Per-Table Tablespaces”.

With the C API function, you can find out how many rows were copied, and (when is used) how many rows were deleted due to duplication of unique key values. See Section 22.2.3.34, “.

Here are some examples that show uses of . Begin with a table that is created as shown here:

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

To rename the table from to :

ALTER TABLE t1 RENAME t2;

To change column from to (leaving the name the same), and to change column from to as well as renaming it from to :

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

To add a new column named :

ALTER TABLE t2 ADD d TIMESTAMP;

To add indexes on column and on column :

ALTER TABLE t2 ADD INDEX (d), ADD INDEX (a);

To remove column :

ALTER TABLE t2 DROP COLUMN c;

To add a new integer column named :

ALTER TABLE t2 ADD c INT UNSIGNED NOT NULL AUTO_INCREMENT,
  ADD PRIMARY KEY (c);

Note that we indexed (as a ), because columns must be indexed, and also that we declare as , because primary key columns cannot be .

When you add an column, column values are filled in with sequence numbers for you automatically. For tables, you can set the first sequence number by executing before or by using the table option. See Section 13.5.3, “ Syntax”.

From MySQL 5.0.3, you can use the table option for tables to set the sequence number for new rows if the value is greater than the maximum value in the column. 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.

With tables, if you do not change the column, the sequence number is not affected. If you drop an column and then add another column, the numbers are resequenced beginning with 1.

When replication is used, adding an 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 number. Assuming that you want to add an column to the table , the following statements produce a new table identical to but with an column:

CREATE TABLE t2 (id INT AUTO_INCREMENT PRIMARY KEY) 
SELECT * FROM t1 ORDER BY col1, col2;

This assumes that the table has columns and .

This set of statements will also produce a new table identical to , with the addition of an 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 must be referenced in the clause.

Regardless of the method used to create and populate the copy having the column, the final step is to drop the original table and then rename the copy:

DROP t1;
ALTER TABLE t2 RENAME t1;

See also Section A.7.1, “Problems with .

13.1.3. CREATE DATABASE Syntax

CREATE {DATABASE | SCHEMA} [IF NOT EXISTS] 
    [ [, ] ...]

:
    [DEFAULT] CHARACTER SET 
  | [DEFAULT] COLLATE 

creates a database with the given name. To use this statement, you need the privilege for the database. is a synonym for as of MySQL 5.0.2.

An error occurs if the database exists and you did not specify .

options specify database characteristics. Database characteristics are stored in the file in the database directory. The clause specifies the default database character set. The 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 statement creates only a directory under the MySQL data directory and the file. Rules for allowable database names are given in Section 9.2, “Database, Table, Index, Column, and Alias 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 .

You can also use the mysqladmin program to create databases. See Section 8.9, “mysqladmin — Client for Administering a MySQL Server”.

13.1.4. CREATE INDEX Syntax

CREATE [UNIQUE|FULLTEXT|SPATIAL] INDEX 
    []
    ON  (,...)

:
     [()] [ASC | DESC]

:
    USING {BTREE | HASH}

is mapped to an statement to create indexes. See Section 13.1.2, “ Syntax”. 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 . See Section 13.1.5, “ Syntax”. enables you to add indexes to existing tables.

A column list of the form creates a multiple-column index. Index values are formed by concatenating the values of the given columns.

For , , , and columns, indexes can be created that use only the leading part of column values, using () syntax to specify an index prefix length. and 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 characters of each column value for , , and columns, and the first bytes of each column value for , , and columns.

The statement shown here creates an index using the first 10 characters of the 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 column. Also, using partial columns for indexes can make the index file much smaller, which could save a lot of disk space and might also speed up operations.

Prefixes can be up to 1000 bytes long (767 bytes for tables). Note that prefix limits are measured in bytes, whereas the prefix length in statements is interpreted as number of characters for non-binary data types (, , ). Take this into account when specifying a prefix length for a column that uses a multi-byte character set.

A 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 values except for the storage engine. For other engines, a index allows multiple values for columns that can contain .

indexes are supported only for tables and can include only , , and columns. Indexing always happens over the entire column; partial indexing is not supported and any prefix length is ignored if specified. See Section 12.7, “Full-Text Search Functions”, for details of operation.

indexes are supported only for tables and can include only spatial columns that are defined as . Chapter 16, Spatial Extensions, describes the spatial data types.

In MySQL 5.0:

  • You can add an index on a column that can have values only if you are using the , , , or storage engine.

  • You can add an index on a or column only if you are using the , , or storage engine.

An specification can end with or . 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
/ ,

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);

is recognized as a synonym for . However, is the preferred form.

13.1.5. CREATE TABLE Syntax

CREATE [TEMPORARY] TABLE [IF NOT EXISTS] 
    (,...)
    [ ...]

Or:

CREATE [TEMPORARY] TABLE [IF NOT EXISTS] 
    [(,...)]
    [ ...]
    

Or:

CREATE [TEMPORARY] TABLE [IF NOT EXISTS] 
    { LIKE  | (LIKE ) }

:
    
  | [CONSTRAINT []] PRIMARY KEY [] (,...)
  | {INDEX|KEY} [] [] (,...)
  | [CONSTRAINT []] UNIQUE [INDEX|KEY]
      [] [] (,...)
  | {FULLTEXT|SPATIAL} [INDEX|KEY] [] (,...)
  | [CONSTRAINT []] FOREIGN KEY
      [] (,...) []
  | CHECK ()

:
      [NOT NULL | NULL] [DEFAULT ]
      [AUTO_INCREMENT] [UNIQUE [KEY] | [PRIMARY] KEY]
      [COMMENT ''] []

:
    BIT[()]
  | TINYINT[()] [UNSIGNED] [ZEROFILL]
  | SMALLINT[()] [UNSIGNED] [ZEROFILL]
  | MEDIUMINT[()] [UNSIGNED] [ZEROFILL]
  | INT[()] [UNSIGNED] [ZEROFILL]
  | INTEGER[()] [UNSIGNED] [ZEROFILL]
  | BIGINT[()] [UNSIGNED] [ZEROFILL]
  | REAL[(,)] [UNSIGNED] [ZEROFILL]
  | DOUBLE[(,)] [UNSIGNED] [ZEROFILL]
  | FLOAT[(,)] [UNSIGNED] [ZEROFILL]
  | DECIMAL(,) [UNSIGNED] [ZEROFILL]
  | NUMERIC(,) [UNSIGNED] [ZEROFILL]
  | DATE
  | TIME
  | TIMESTAMP
  | DATETIME
  | YEAR
  | CHAR()
      [CHARACTER SET ] [COLLATE ]
  | VARCHAR()
      [CHARACTER SET ] [COLLATE ]
  | BINARY()
  | VARBINARY()
  | TINYBLOB
  | BLOB
  | MEDIUMBLOB
  | LONGBLOB
  | TINYTEXT [BINARY]
      [CHARACTER SET ] [COLLATE ]
  | TEXT [BINARY]
      [CHARACTER SET ] [COLLATE ]
  | MEDIUMTEXT [BINARY]
      [CHARACTER SET ] [COLLATE ]
  | LONGTEXT [BINARY]
      [CHARACTER SET ] [COLLATE ]
  | ENUM(,,,...)
      [CHARACTER SET ] [COLLATE ]
  | SET(,,,...)
      [CHARACTER SET ] [COLLATE ]
  | 

:
     [()] [ASC | DESC]

:
    USING {BTREE | HASH}

:
    REFERENCES  [(,...)]
      [MATCH FULL | MATCH PARTIAL | MATCH SIMPLE]
      [ON DELETE ]
      [ON UPDATE ]

:
    RESTRICT | CASCADE | SET NULL | NO ACTION

:
    {ENGINE|TYPE} [=] 
  | AUTO_INCREMENT [=] 
  | AVG_ROW_LENGTH [=] 
  | [DEFAULT] CHARACTER SET 
  | CHECKSUM [=] {0 | 1}
  | COLLATE 
  | COMMENT [=] ''
  | CONNECTION [=] ''
  | DATA DIRECTORY [=] ''
  | DELAY_KEY_WRITE [=] {0 | 1}
  | INDEX DIRECTORY [=] ''
  | INSERT_METHOD [=] { NO | FIRST | LAST }
  | MAX_ROWS [=] 
  | MIN_ROWS [=] 
  | PACK_KEYS [=] {0 | 1 | DEFAULT}
  | PASSWORD [=] ''
  | ROW_FORMAT [=] {DEFAULT|DYNAMIC|FIXED|COMPRESSED|REDUNDANT|COMPACT}
  | UNION [=] ([,]...)


    [IGNORE | REPLACE] [AS] SELECT ...   ()

creates a table with the given name. You must have the privilege for the table.

Rules for allowable table names are given in Section 9.2, “Database, Table, Index, Column, and Alias 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 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 , not .

You can use the keyword when creating a table. A 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- table of the same name. (The existing table is hidden until the temporary table is dropped.) To create temporary tables, you must have the privilege.

The keywords 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 statement. Note: If you use in a statement, any rows selected by the part are inserted regardless of whether the table already exists.

MySQL represents each table by an table format (definition) file in the database directory. The storage engine for the table might create other files as well. In the case of tables, the storage engine creates data and index files. Thus, for each table , there are three disk files:

File Purpose
.frm Table format (definition) file
.MYD Data file
.MYI Index file

Chapter 14, Storage Engines and Table Types, describes what files each storage engine creates to represent tables.

represents the data type is a column definition. represents a spatial data type. For general information on the properties of data types other than the spatial types, see Chapter 11, Data Types. For information about spatial data types, see Chapter 16, Spatial Extensions.

Some attributes do not apply to all data types. applies only to integer types. does not apply to the or types.

  • If neither nor is specified, the column is treated as though had been specified.

  • An integer column can have the additional attribute . When you insert a value of (recommended) or into an indexed column, the column is set to the next sequence value. Typically this is +1, where is the largest value for the column currently in the table. sequences begin with .

    To retrieve an value after inserting a row, use the SQL function or the C API function. See Section 12.9.3, “Information Functions”, and Section 22.2.3.36, “.

    If the SQL mode is enabled, you can store in columns as without generating a new sequence value. See Section 5.2.5, “The Server SQL Mode”.

    Note: There can be only one column per table, it must be indexed, and it cannot have a value. An 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 column that contains .

    For and tables, you can specify an secondary column in a multiple-column key. See Section 3.6.9, “Using .

    To make MySQL compatible with some ODBC applications, you can find the value for the last inserted row with the following query:

    SELECT * FROM  WHERE  IS NULL
    

    For information about and , see Section 14.2.6.3, “How Columns Work in .

  • The attribute is an alias for .

  • Character data types (, , ) can include and attributes to specify the character set and collation for the column. For details, see Chapter 10, Character Set Support. is a synonym for . 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 and are in bytes.

  • The 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 or . The exception is that you can specify as the default for a column. See Section 11.3.1.1, “ Properties as of MySQL 4.1”.

    If a column definition includes no explicit value, MySQL determines the default value as described in Section 11.1.4, “Data Type Default Values”.

    and columns cannot be assigned a default value.

  • A comment for a column can be specified with the option, up to 255 characters long. The comment is displayed by the and statements.

  • is normally a synonym for . The key attribute can also be specified as just when given in a column definition. This was implemented for compatibility with other database systems.

  • A 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 values except for the storage engine. For other engines, a index allows multiple values for columns that can contain .

  • A is a unique index where all key columns must be defined as . If they are not explicitly declared as , MySQL declares them so implicitly (and silently). A table can have only one . If you do not have a and an application asks for the in your tables, MySQL returns the first index that has no columns as the .

    In tables, having a long wastes a lot of space. (See Section 14.2.13, “ Table and Index Structures”.)

  • In the created table, a is placed first, followed by all 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 keys.

  • A can be a multiple-column index. However, you cannot create a multiple-column index using the key attribute in a column specification. Doing so only marks that single column as primary. You must use a separate , ...) clause.

  • If a or index consists of only one column that has an integer type, you can also refer to the column as in statements.

  • In MySQL, the name of a is . 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 (, , ) to make it unique. You can see index names for a table using . See Section 13.5.4.13, “ Syntax”.

  • Some storage engines allow you to specify an index type when creating an index. The syntax for the specifier is .

    Example:

    CREATE TABLE lookup
      (id INT, INDEX USING BTREE (id))
      ENGINE = MEMORY;
    

    For details about , see Section 13.1.4, “ Syntax”.

    For more information about indexes, see Section 7.4.5, “How MySQL Uses Indexes”.

  • In MySQL 5.0, only the , , , and storage engines support indexes on columns that can have values. In other cases, you must declare indexed columns as or an error results.

  • For , , , and columns, indexes can be created that use only the leading part of column values, using () syntax to specify an index prefix length. and 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 characters of each column value for , , and columns, and the first bytes of each column value for , , and 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 , , and storage engines support indexing on and columns. For example:

    CREATE TABLE test (blob_col BLOB, INDEX(blob_col(10)));
    

    Prefixes can be up to 1000 bytes long (767 bytes for tables). Note that prefix limits are measured in bytes, whereas the prefix length in statements is interpreted as number of characters for non-binary data types (, , ). Take this into account when specifying a prefix length for a column that uses a multi-byte character set.

  • An specification can end with or . 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 or on a or column in a , the server sorts values using only the initial number of bytes indicated by the system variable. See Section 11.4.3, “The and Types”.

  • You can create special indexes, which are used for full-text searches. Only the storage engine supports indexes. They can be created only from , , and columns. Indexing always happens over the entire column; partial indexing is not supported and any prefix length is ignored if specified. See Section 12.7, “Full-Text Search Functions”, for details of operation.

  • You can create indexes on spatial data types. Spatial types are supported only for tables and indexed columns must be declared as . See Chapter 16, Spatial Extensions.

  • tables support checking of foreign key constraints. See Section 14.2, “The Storage Engine”. Note that the syntax in is more restrictive than the syntax presented for the statement at the beginning of this section: The columns of the referenced table must always be explicitly named. supports both and actions on foreign keys. For the precise syntax, see Section 14.2.6.4, “ Constraints”.

    For other storage engines, MySQL Server parses and ignores the and syntax in statements. The clause is parsed but ignored by all storage engines. See Section 1.9.5.5, “Foreign Keys”.

  • For tables, each column takes one bit extra, rounded up to the nearest byte. The maximum row length in bytes can be calculated as follows:

    row length = 1
                 + ()
                 + ( +  + 7)/8
                 + ()
    

    is 1 for tables with static row format. Static tables use a bit in the row record for a flag that indicates whether the row has been deleted. is 0 for dynamic tables because the flag is stored in the dynamic row header.

    These calculations do not apply for tables, for which storage size is no different for columns than for columns.

The table option specifies the storage engine for the table. is a synonym, but is the preferred option name.

The table option takes the storage engine names shown in the following table.

Storage Engine Description
The archiving storage engine. See Section 14.8, “The Storage Engine”.
Transaction-safe tables with page locking. Also known as . See Section 14.5, “The () Storage Engine”.
Tables that store rows in comma-separated values format. See Section 14.9, “The Storage Engine”.
An example engine. See Section 14.6, “The Storage Engine”.
Storage engine that accesses remote tables. See Section 14.7, “The Storage Engine”.
This is a synonym for .
(OBSOLETE) Not available in MySQL 5.0. If you are upgrading to MySQL 5.0 from a previous version, you should convert any existing tables to before performing the upgrade.
Transaction-safe tables with row locking and foreign keys. See Section 14.2, “The Storage Engine”.
The data for this storage engine is stored only in memory. See Section 14.4, “The () Storage Engine”.
A collection of tables used as one table. Also known as . See Section 14.3, “The Storage Engine”.
The binary portable storage engine that is the default storage engine used by MySQL. See Section 14.1, “The Storage Engine”.
Clustered, fault-tolerant, memory-based tables. Also known as . See Chapter 15, MySQL Cluster.

If a storage engine is specified that is not available, MySQL uses the default engine instead. Normally, this is . For example, if a table definition includes the option but the MySQL server does not support tables, the table is created as a 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.

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 to convert the table to use a different storage engine.

  • The initial value for the table. In MySQL 5.0, this works for and tables. It is also supported for as of MySQL 5.0.3. To set the first auto-increment value for engines that do not support the 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 table option in statements, you can also use AUTO_INCREMENT = to reset the value.

  • 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 table, MySQL uses the product of the and options to decide how big the resulting table is. If you don't specify either option, the maximum size for a table is 65,536TB of data (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 system variable, which was added in MySQL 4.1.2. (See Section 5.2.2, “Server 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.

  • Specify a default character set for the table. is a synonym for .

  • 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 statement reports the checksum. ( only.)

  • Specify a default collation for the table.

  • A comment for the table, up to 60 characters long.

  • The connection string for a table. This option is available as of MySQL 5.0.13; before that, use a option for the connection string.

  • ,

    By using ' or ' you can specify where the 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 option. Your operating system must also have a working, thread-safe call. See Section 7.6.1.2, “Using Symbolic Links for Tables on Unix”, for more complete information.

  • Set this to 1 if you want to delay key updates for the table until the table is closed. See the description of the system variable in Section 5.2.2, “Server System Variables”. ( only.)

  • If you want to insert data into a table, you must specify with the table into which the row should be inserted. is an option useful for tables only. Use a value of or to have inserts go to the first or last table, or a value of to prevent inserts. See Section 14.3, “The Storage Engine”.

  • 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.

  • The minimum number of rows you plan to store in the table.

  • takes effect only with 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 tells the storage engine to pack only long or columns.

    If you do not use , the default is to pack strings, but not numbers. If you use , 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 (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 values. (In this case, the packed key length is stored in the same byte that is used to mark if a key is .)

  • Encrypt the file with a password. This option does nothing in the standard MySQL version.

  • Defines how the rows should be stored. For tables, the option value can be or for static or variable-length row format. myisampack sets the type to . See Section 14.1.3, “ Table Storage Formats”.

    Starting with MySQL 5.0.3, for tables, rows are stored in compact format () by default. The non-compact format used in older versions of MySQL can still be requested by specifying .

  • support has been removed as of MySQL 5.0. For information on , see http://dev.mysql.com/doc/refman/4.1/en/create-table.html.

  • is used when you want to access a collection of identical tables as one. This works only with tables. See Section 14.3, “The Storage Engine”.

    You must have , , and privileges for the tables you map to a table. (Note: Formerly, all tables used had to be in the same database as the table itself. This restriction no longer applies.)

You can create one table from another by adding a statement at the end of the statement:

CREATE TABLE  SELECT * FROM ;

MySQL creates new columns for all elements in the . For example:

mysql> 
    ->        
    ->        

This creates a table with three columns, , , and . Notice that the columns from the statement are appended to the right side of the table, not overlapped onto it. Take the following example:

mysql> 
+---+
| n |
+---+
| 1 |
+---+

mysql> 
Query OK, 1 row affected (0.02 sec)
Records: 1  Duplicates: 0  Warnings: 0

mysql> 
+------+---+
| m    | n |
+------+---+
| NULL | 1 |
+------+---+
1 row in set (0.00 sec)

For each row in table , a row is inserted in with the values from and default values for the new columns.

In a table resulting from , columns named only in the part come first. Columns named in both parts or only in the part come after that. The data type of columns can be overridden by also specifying the column in the part.

If any errors occur while copying the data to the table, it is automatically dropped and not created.

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 statement:

mysql> 

Some conversion of data types might occur. For example, the attribute is not preserved, and columns can become columns.

When creating a table with , make sure to alias any function calls or expressions in the query. If you do not, the 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 to create an empty table based on the definition of another table, including any column attributes and indexes defined in the original table:

CREATE TABLE  LIKE ;

does not preserve any or table options that were specified for the original table, or any foreign key definitions.

You can precede the by or to indicate how to handle rows that duplicate unique key values. With , new rows that duplicate an existing row on a unique key value are discarded. With , new rows replace rows that have the same unique key value. If neither nor 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 .

13.1.5.1. Silent Column Specification Changes

In some cases, MySQL silently changes column specifications from those given in a or statement. These might be changes to a data type, to attributes associated with a data type, or to an index specification.

Possible data type changes are given in the following list. These occur prior to MySQL 5.0.3. As of 5.0.3, an error occurs if a column cannot be created using the specified data type.

  • columns with a length less than four are changed to .

  • 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 (, , or ), all columns longer than three characters are changed to columns. This does not affect how you use the columns in any way; in MySQL, is just a different way to store characters. MySQL performs this conversion because it saves space and makes table operations faster. See Chapter 14, Storage Engines and Table Types.

  • Before MySQL 5.0.3, a or column with a length specification greater than 255 is converted to the smallest type that can hold values of the given length. For example, is converted to , and is converted to . Note that this conversion results in a change in behavior with regard to treatment of trailing spaces.

    Similar conversions occur for and , except that they are converted to a type.

    Starting with MySQL 5.0.3, a or 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 and columns with a length specification greater than 65,535 does not occur if strict SQL mode is enabled. Instead, an error occurs.

  • For a specification of ,), if is not larger than , it is adjusted upward. For example, becomes .

Other silent column specification changes include changes to attribute or index specifications:

  • display sizes are discarded. Note that columns have changed considerably in recent versions of MySQL prior to 5.0; for a description of these changes, see the MySQL 3.23, 4.0, 4.1 Reference Manual.

  • Columns that are part of a are made even if not declared that way.

  • Trailing spaces are automatically deleted from and member values when the table is created.

  • MySQL maps certain data types used by other SQL database vendors to MySQL types. See Section 11.7, “Using Data Types from Other Database Engines”.

  • If you include a 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.

To see whether MySQL used a data type other than the one you specified, issue a or statement after creating or altering the table.

Certain other data type changes can occur if you compress a table using myisampack. See Section 14.1.3.3, “Compressed Table Characteristics”.

13.1.6. DROP DATABASE Syntax

DROP {DATABASE | SCHEMA} [IF EXISTS] 

drops all tables in the database and deletes the database. Be very careful with this statement! To use , you need the privilege on the database. is a synonym for as of MySQL 5.0.2.

is used to prevent an error from occurring if the database does not exist.

If you use on a symbolically linked database, both the link and the original database are deleted.

returns the number of tables that were removed. This corresponds to the number of files removed.

The statement removes from the given database directory those files and directories that MySQL itself may create during normal operation:

  • All files with these extensions:

  • All subdirectories with names that consist of two hex digits -. These are subdirectories used for tables. (These directories are not removed as of MySQL 5.0, when support for tables was removed. You should convert any existing tables and remove these directories manually before upgrading to MySQL 5.0. See Section 2.11.2, “Upgrading from MySQL 4.1 to 5.0”.)

  • The 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 statement again.

You can also drop databases with mysqladmin. See Section 8.9, “mysqladmin — Client for Administering a MySQL Server”.

13.1.7. DROP INDEX Syntax

DROP INDEX  ON 

drops the index named from the table . This statement is mapped to an statement to drop the index. See Section 13.1.2, “ Syntax”.

13.1.8. DROP TABLE Syntax

DROP [TEMPORARY] TABLE [IF EXISTS]
     [, ] ...
    [RESTRICT | CASCADE]

removes one or more tables. You must have the 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.

Use to prevent an error from occurring for tables that do not exist. A is generated for each non-existent table when using . See Section 13.5.4.25, “ Syntax”.

and are allowed to make porting easier. For the moment, they do nothing.

Note: automatically commits the current active transaction, unless you use the keyword.

The keyword has the following effects:

  • The statement drops only tables.

  • The statement does not end an ongoing transaction.

  • No access rights are checked. (A table is visible only to the client that created it, so no check is necessary.)

Using is a good way to ensure that you do not accidentally drop a non- table.

13.1.9. RENAME TABLE Syntax

RENAME TABLE  TO 
    [,  TO ] ...

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 , you can create another table that has the same structure but is empty, and then replace the existing table with the empty one as follows (assuming that 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 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 to move a table from one database to another:

RENAME TABLE  TO 

As of MySQL 5.0.14, also works for views, as long as you do not try to rename a view into a different database.

When you execute , you cannot have any locked tables or active transactions. You must also have the and privileges on the original table, and the and 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.