diff --git a/mysql-compatibility.md b/mysql-compatibility.md index 8494633d9151a..4a1cc5854dda4 100644 --- a/mysql-compatibility.md +++ b/mysql-compatibility.md @@ -89,17 +89,16 @@ See also: [TiDB SQL Grammar](https://pingcap.github.io/sqlgram/#functioncallkeyw ### DDL -In TiDB, all supported DDL changes are performed online. The MySQL DDL assertions `ALGORITHM=INSTANT` and `ALGORITHM=INPLACE` can also be used to assert which algorithm will be used to modify the table (which might differ from MySQL). - -The following major restrictions apply to DDL versus MySQL: +In TiDB, all supported DDL changes are performed online. Compared with DDL operations in MySQL, the DDL operations in TiDB have the following major restrictions: * Multiple operations cannot be completed in a single `ALTER TABLE` statement. For example, it is not possible to add multiple columns or indexes in a single statement. Otherwise, the `Unsupported multi schema change` error might be output. * Different types of indexes (`HASH|BTREE|RTREE|FULLTEXT`) are not supported, and will be parsed and ignored when specified. * Adding/Dropping the primary key is unsupported unless [`alter-primary-key`](/tidb-configuration-file.md#alter-primary-key) is enabled. * Changing the field type to its superset is unsupported. For example, TiDB does not support changing the field type from `INTEGER` to `VARCHAR`, or from `TIMESTAMP` to `DATETIME`. Otherwise, the error information `Unsupported modify column: type %d not match origin %d` might be output. * Change/Modify data type does not currently support "lossy changes", such as changing from BIGINT to INT. -* Change/Modify decimal columns does not support changing the prevision. +* Change/Modify decimal columns does not support changing the precision. * Change/Modify integer columns does not permit changing the `UNSIGNED` attribute. +* The `ALGORITHM={INSTANT,INPLACE,COPY}` syntax functions only as an assertion in TiDB, and does not modify the `ALTER` algorithm. See [`ALTER TABLE`](/sql-statements/sql-statement-alter-table.md) for further details. * Table Partitioning supports Hash, Range, and `Add`/`Drop`/`Truncate`/`Coalesce`. The other partition operations are ignored. The `Warning: Unsupported partition type, treat as normal table` error might be output. The following Table Partition syntaxes are not supported: - `PARTITION BY LIST` - `PARTITION BY KEY` diff --git a/sql-statements/sql-statement-alter-database.md b/sql-statements/sql-statement-alter-database.md index 22e731433b6f6..3901c206b441e 100644 --- a/sql-statements/sql-statement-alter-database.md +++ b/sql-statements/sql-statement-alter-database.md @@ -8,7 +8,7 @@ aliases: ['/docs/stable/sql-statements/sql-statement-alter-database/','/docs/v4. `ALTER DATABASE` is used to specify or modify the default character set and collation of the current database. `ALTER SCHEMA` has the same effect as `ALTER DATABASE`. -## 语法图 +## Synopsis **AlterDatabaseStmt:** @@ -20,15 +20,19 @@ aliases: ['/docs/stable/sql-statements/sql-statement-alter-database/','/docs/v4. ## Examples +Modify the test database schema to use the utf8mb4 character set: + +{{< copyable "sql" >}} + +```sql +ALTER DATABASE test DEFAULT CHARACTER SET = utf8mb4; +``` + ```sql -ALTER {DATABASE | SCHEMA} [db_name] - alter_specification ... -alter_specification: - [DEFAULT] CHARACTER SET [=] charset_name - | [DEFAULT] COLLATE [=] collation_name +Query OK, 0 rows affected (0.00 sec) ``` -The `alter_specification` option specifies the `CHARACTER SET` and `COLLATE` of a specified database. Currently, TiDB only supports some character sets and collations. See [Character Set and Collation Support](/character-set-and-collation.md) for details. +Currently, TiDB only supports some character sets and collations. See [Character Set and Collation Support](/character-set-and-collation.md) for details. ## MySQL compatibility diff --git a/sql-statements/sql-statement-alter-table.md b/sql-statements/sql-statement-alter-table.md index ebc153c7ec1bc..f72ca98780de9 100644 --- a/sql-statements/sql-statement-alter-table.md +++ b/sql-statements/sql-statement-alter-table.md @@ -27,15 +27,31 @@ This statement modifies an existing table to conform to a new table structure. T ## Examples +Create a table with some initial data: + +{{< copyable "sql" >}} + +```sql +CREATE TABLE t1 (id INT NOT NULL PRIMARY KEY AUTO_INCREMENT, c1 INT NOT NULL); +INSERT INTO t1 (c1) VALUES (1),(2),(3),(4),(5); +``` + ```sql -mysql> CREATE TABLE t1 (id INT NOT NULL PRIMARY KEY AUTO_INCREMENT, c1 INT NOT NULL); Query OK, 0 rows affected (0.11 sec) -mysql> INSERT INTO t1 (c1) VALUES (1),(2),(3),(4),(5); Query OK, 5 rows affected (0.03 sec) Records: 5 Duplicates: 0 Warnings: 0 +``` -mysql> EXPLAIN SELECT * FROM t1 WHERE c1 = 3; +The following query requires a full table scan because the column c1 is not indexed: + +{{< copyable "sql" >}} + +```sql +EXPLAIN SELECT * FROM t1 WHERE c1 = 3; +``` + +```sql +-------------------------+----------+-----------+---------------+--------------------------------+ | id | estRows | task | access object | operator info | +-------------------------+----------+-----------+---------------+--------------------------------+ @@ -44,11 +60,20 @@ mysql> EXPLAIN SELECT * FROM t1 WHERE c1 = 3; | └─TableFullScan_5 | 10000.00 | cop[tikv] | table:t1 | keep order:false, stats:pseudo | +-------------------------+----------+-----------+---------------+--------------------------------+ 3 rows in set (0.00 sec) +``` + +The statement [`ALTER TABLE .. ADD INDEX`](/sql-statements/sql-statement-add-index.md) can be used to add an index on the table t1. `EXPLAIN` confirms that the original query now uses an index range scan, which is more efficient: + +{{< copyable "sql" >}} + +```sql +ALTER TABLE t1 ADD INDEX (c1); +EXPLAIN SELECT * FROM t1 WHERE c1 = 3; +``` -mysql> ALTER TABLE t1 ADD INDEX (c1); +```sql Query OK, 0 rows affected (0.30 sec) -mysql> EXPLAIN SELECT * FROM t1 WHERE c1 = 3; +------------------------+---------+-----------+------------------------+---------------------------------------------+ | id | estRows | task | access object | operator info | +------------------------+---------+-----------+------------------------+---------------------------------------------+ @@ -58,12 +83,65 @@ mysql> EXPLAIN SELECT * FROM t1 WHERE c1 = 3; 2 rows in set (0.00 sec) ``` +TiDB supports the ability to assert that DDL changes will use a particular `ALTER` algorithm. This is only an assertion, and does not change the actual algorithm which will be used to modify the table. It can be useful if you only want to permit instant DDL changes during the peak hours of your cluster: + +{{< copyable "sql" >}} + +```sql +ALTER TABLE t1 DROP INDEX c1, ALGORITHM=INSTANT; +``` + +```sql +Query OK, 0 rows affected (0.24 sec) +``` + +Using the `ALGORITHM=INSTANT` assertion on an operation that requires the `INPLACE` algorithm results in a statement error: + +{{< copyable "sql" >}} + +```sql +ALTER TABLE t1 ADD INDEX (c1), ALGORITHM=INSTANT; +``` + +```sql +ERROR 1846 (0A000): ALGORITHM=INSTANT is not supported. Reason: Cannot alter table by INSTANT. Try ALGORITHM=INPLACE. +``` + +However, using the `ALGORITHM=COPY` assertion for an `INPLACE` operation generates a warning instead of an error. This is because TiDB interprets the assertion as _this algorithm or better_. This behavior difference is useful for MySQL compatibility because the algorithm TiDB uses might differ from MySQL: + +{{< copyable "sql" >}} + +```sql +ALTER TABLE t1 ADD INDEX (c1), ALGORITHM=COPY; +SHOW WARNINGS; +``` + +```sql +Query OK, 0 rows affected, 1 warning (0.25 sec) + ++-------+------+---------------------------------------------------------------------------------------------+ +| Level | Code | Message | ++-------+------+---------------------------------------------------------------------------------------------+ +| Error | 1846 | ALGORITHM=COPY is not supported. Reason: Cannot alter table by COPY. Try ALGORITHM=INPLACE. | ++-------+------+---------------------------------------------------------------------------------------------+ +1 row in set (0.00 sec) +``` + ## MySQL compatibility -* All of the data types except spatial types are supported. For other unsupported cases, refer to: [compatibility of DDL statements with MySQL](/mysql-compatibility.md#ddl). +The following major restrictions apply to `ALTER TABLE` in TiDB: + +* Multiple operations cannot be completed in a single `ALTER TABLE` statement. + +* Lossy changes such as changing from `BIGINT` to `INT` are currently not supported. + +* Spatial data types are not supported. + +For further restrictions, see [MySQL Compatibility](/mysql-compatibility.md#ddl). ## See also +* [MySQL Compatibility](/mysql-compatibility.md#ddl) * [ADD COLUMN](/sql-statements/sql-statement-add-column.md) * [DROP COLUMN](/sql-statements/sql-statement-drop-column.md) * [ADD INDEX](/sql-statements/sql-statement-add-index.md)