Skip to content
Open
16 changes: 14 additions & 2 deletions sql-statements/sql-statement-modify-column.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,24 @@ aliases: ['/docs-cn/dev/sql-statements/sql-statement-modify-column/','/docs-cn/d

`ALTER TABLE .. MODIFY COLUMN` 语句用于修改已有表上的列,包括列的数据类型和属性。若要同时重命名,可改用 [`CHANGE COLUMN`](/sql-statements/sql-statement-change-column.md) 语句。
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
`ALTER TABLE .. MODIFY COLUMN` 语句用于修改已有表上的列,包括列的数据类型和属性。若要同时重命名,可改用 [`CHANGE COLUMN`](/sql-statements/sql-statement-change-column.md) 语句。
`ALTER TABLE ... MODIFY COLUMN` 语句用于修改已有表上的列,包括列的数据类型和属性。若要同时重命名,可改用 [`CHANGE COLUMN`](/sql-statements/sql-statement-change-column.md) 语句。


从 v5.1.0 版本起,TiDB 开始支持 Reorg 类型变更,包括但不限于:
从 v5.1.0 起,TiDB 支持需要 Reorg-Data 的列类型变更。这类变更在执行过程中会重建表中现有的所有数据,包括读取原始数据、按照新的数据格式进行处理,以及重新写入表中。由于需要处理全表数据,Reorg-Data 操作通常较为耗时,其执行时间与表中的数据量成正比。
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
从 v5.1.0 起,TiDB 支持需要 Reorg-Data 的列类型变更。这类变更在执行过程中会重建表中现有的所有数据,包括读取原始数据、按照新的数据格式进行处理,以及重新写入表中。由于需要处理全表数据,Reorg-Data 操作通常较为耗时,其执行时间与表中的数据量成正比。
从 v5.1.0 起,TiDB 支持需要 [Reorg-Data](#reorg-data-change) 的列类型变更。在执行此类变更时,TiDB 会对表中的的全部现有数据进行重建,具体过程包括:读取原始表数据、按照新的列类型对数据进行转换,然后将转换后的数据重新写入表中。由于需要处理全表数据,Reorg-Data 操作通常耗时较长,其执行时间与表中的数据量成正比。


常见的需要 Reorg-Data 的列类型变更包括(但不限于):
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
常见的需要 Reorg-Data 的列类型变更包括(但不限于)
以下是一些常见的需要执行 Reorg-Data 的列类型变更示例



- 从 `VARCHAR` 转换为 `BIGINT`
- `DECIMAL` 精度修改
- 从 `VARCHAR(10)` 到 `VARCHAR(5)` 的长度压缩

从 v8.5.5 和 v9.0.0 起,针对部分原本需要 Reorg-Data 的列类型变更,TiDB 优化了执行效率。如果当前会话的 [SQL 模式](/sql-mode.md)为严格模式(即 `sql_mode` 值包含 `STRICT_TRANS_TABLES` 或 `STRICT_ALL_TABLES`),TiDB 在进行以下类型变更时,会预先检查类型转换过程中是否存在数据截断风险,若不存在数据截断风险,TiDB 将不再进行表数据重建,仅重建受影响的索引:

- 整数类型之间的变更(例如 `BIGINT` 到 `INT`)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这个场景下,是不是不需要重建索引?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

不需要。之前需要

- 字符串类型之间的变更(例如 `VARCHAR(200)` 到 `VARCHAR(100)`)
Comment on lines +20 to +23
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
从 v8.5.5 和 v9.0.0 起,针对部分原本需要 Reorg-Data 的列类型变更,TiDB 优化了执行效率。如果当前会话的 [SQL 模式](/sql-mode.md)为严格模式(即 `sql_mode` 值包含 `STRICT_TRANS_TABLES``STRICT_ALL_TABLES`),TiDB 在进行以下类型变更时,会预先检查类型转换过程中是否存在数据截断风险,若不存在数据截断风险,TiDB 将不再进行表数据重建,仅重建受影响的索引:
- 整数类型之间的变更(例如 `BIGINT``INT`
- 字符串类型之间的变更(例如 `VARCHAR(200)``VARCHAR(100)`
从 v8.5.5 和 v9.0.0 起,TiDB 优化了部分原本需要 Reorg-Data 的列类型变更。如果满足以下条件,TiDB 将仅重建受影响的索引,而不再重建表数据,从而提升执行效率:
- 当前会话的 [SQL 模式](/sql-mode.md)为严格模式,即 `sql_mode` 值包含 `STRICT_TRANS_TABLES``STRICT_ALL_TABLES`
- 类型转换过程中不存在数据截断风险
该优化适用于以下类型变更场景:
- 整数类型之间的变更(例如,从 `BIGINT` 变更为 `INT`
- 字符串类型之间的变更(例如,从 `VARCHAR(200)` 变更为 `VARCHAR(100)`


> **注意:**
>
> 当从 `VARCHAR` 转换为 `CHAR` 时,要求所有原数据的末尾均不包含空格;若存在不满足该条件的数据,TiDB 仍会执行 Reorg-Data,以确保转换后的数据符合 `CHAR` 类型的填充规则。

## 语法图

```ebnf+diagram
Expand Down Expand Up @@ -168,7 +180,7 @@ CREATE TABLE `t1` (
> ERROR 1406 (22001): Data Too Long, field len 4, data len 5
> ```
>
> - 由于和 Async Commit 功能兼容,DDL 在开始进入到 Reorg Data 前会有一定时间(约 2.5s)的等待处理:
> - 由于和 Async Commit 功能兼容,在关闭[元数据锁](/metadata-lock.md)的情况下,DDL 在开始进入到 Reorg-Data 前会有一定时间(约 2.5 秒)的等待处理:
>
> ```
> Query OK, 0 rows affected (2.52 sec)
Expand Down