首批通过分布式安全可靠测评,为关键业务系统打造
更改表
更新时间:2026-07-03 13:00:42
表创建成功后,您可以使用 ALTER TABLE 语句对表进行修改。
更改表的 Collation 和字符集
创建表时,如果未明确定义表的 Collation 和字符集,则默认使用数据库的字符集和字符序,数据库的 Collation 和字符集的详细介绍信息请参见 数据库级字符集和字符序。
表创建后,您可以修改表的 Collation 和字符集设置。 语句如下:
ALTER TABLE table_name [[DEFAULT] CHARACTER SET [=] charset_name] [COLLATE [=] collation_name];
OceanBase 数据库中表的 Collation 和字符集的详细介绍信息请参见 表级字符集和字符序。
注意
修改表的 Collation 和字符集设置仅影响后续添加的字符类型的列的数据保存方式,已有字符类型的列的数据保存方式不会被修改。
示例:
创建表
tbl1。obclient> CREATE TABLE tbl1 (c1 int, c2 varchar(32), c3 varchar(32), PRIMARY KEY(c1), UNIQUE KEY uk1(c2));修改表的 Collation 和字符集。
obclient> ALTER TABLE tbl1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_bin;如果表中已有数据,您可以修改表中已有数据的 Collation 和字符集,并将表的 Collation 和字符集也修改为对应的设置。示例如下:
obclient> ALTER TABLE tbl1 CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_bin;
更改表结构
OceanBase 数据库支持增加列、修改列及其属性、删除列等。
增加列
在表中增加列,但不支持直接增加主键列。如果需要增加主键列,可以先增加列后再为列添加主键。添加主键的相关操作请参见 定义列的约束类型。
假设有一表 test,其表结构如下所示。
+-------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| c1 | int(11) | NO | PRI | NULL | |
| c2 | varchar(50) | YES | | NULL | |
+-------+-------------+------+-----+---------+-------+
2 rows in set
添加任意列
c3。obclient> ALTER TABLE test ADD c3 int;修改后,执行语句
DESCRIBE test查询表结构,结果如下。+-------+-------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +-------+-------------+------+-----+---------+-------+ | c1 | int(11) | NO | PRI | NULL | | | c2 | varchar(50) | YES | | NULL | | | c3 | int(11) | YES | | NULL | | +-------+-------------+------+-----+---------+-------+ 3 rows in set在
c1列后面指定添加c4列。obclient> ALTER TABLE test ADD COLUMN c4 INT NULL AFTER c1;修改后,执行语句
DESCRIBE test查询表结构,结果如下。+-------+-------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +-------+-------------+------+-----+---------+-------+ | c1 | int(11) | NO | PRI | NULL | | | c4 | int(11) | YES | | NULL | | | c2 | varchar(50) | YES | | NULL | | | c3 | int(11) | NO | | NULL | | +-------+-------------+------+-----+---------+-------+ 4 rows in set在
c1列前面指定添加c6列。obclient> ALTER TABLE test ADD COLUMN c6 INT NULL BEFORE c1;修改后,执行语句
DESCRIBE test查询表结构,结果如下。+-------+-------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +-------+-------------+------+-----+---------+-------+ | c6 | int(11) | YES | | NULL | | | c1 | int(11) | NO | PRI | NULL | | | c4 | int(11) | YES | | NULL | | | c2 | varchar(50) | YES | | NULL | | | c3 | int(11) | NO | | NULL | | +-------+-------------+------+-----+---------+-------+ 5 rows in set显示的字段解释如下:
Field:字段信息为列名。Type:该列的数据类型。Null:表示该列是否允许为空,NO表示不允许为空,YES表示允许为空。key:字段信息显示为PRI代表改列为主键列。
修改列属性
支持重命名列、修改列类型、列的默认值和修改列的 Skip Index 属性。
重命名列
使用 RENAME COLUMN 关键字重命名列时,需要注意以下事项:
如果待重命名的列上有索引或者外键约束,列名可以修改成功,并且索引定义和外键约束会自动级联修改。
如果待重命名的列被视图或存储过程引用,列名可以修改成功,但需要手动修改视图或存储过程的定义。
不支持同时进行重命名列和删除列的操作。
不支持同时进行重命名列与修改分区(增加分区、删除分区等)的操作。
假设有一表 test,其表结构如下所示。
+-------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| c1 | int(11) | NO | PRI | NULL | |
| c2 | varchar(50) | YES | | NULL | |
+-------+-------------+------+-----+---------+-------+
2 rows in set
将表 test 的 c2 列重命名为 c 的示例如下。
obclient> ALTER TABLE test RENAME COLUMN c2 TO c;
修改后,执行语句 DESCRIBE test 查询表结构,结果如下。
+-------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| c1 | int(11) | NO | PRI | NULL | |
| c | varchar(50) | YES | | NULL | |
+-------+-------------+------+-----+---------+-------+
2 rows in set
注意,以下场景下,重命名列会失败:
目标列名在当前表中已存在。
有一个特殊场景,如果重命名的列出现了循环的场景,可以重命名成功。例如,本示例中,将原
c1列重命名为c2,同时将原c2列重命名为c1,执行语句ALTER TABLE test RENAME COLUMN c1 TO c2, rename column c2 TO c1;,可以重命名成功。待重命名的列被生成列表达式引用。
待重命名的列被分区表达式引用。
待重命名的列被 CHECK 约束引用。
修改列类型
OceanBase 数据库中 MySQL 模式下列类型的转换规则及详细信息请参见 列类型变更规则。
假设有一表 test,其表结构如下所示。
+-------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| c1 | int(11) | NO | PRI | NULL | |
| c2 | varchar(50) | YES | | NULL | |
+-------+-------------+------+-----+---------+-------+
2 rows in set
将表 test 的 c2 列修改为 CHAR 类型的示例如下。
obclient> ALTER TABLE test MODIFY c2 CHAR(60);
修改后,执行语句 DESCRIBE test 查询表结构,结果如下。
+-------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| c1 | int(11) | NO | PRI | NULL | |
| c2 | char(60) | YES | | NULL | |
+-------+-------------+------+-----+---------+-------+
2 rows in set
修改列名同时修改列类型
假设有一表 test,其表结构如下所示。
+-------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| c1 | int(11) | NO | PRI | NULL | |
| c2 | varchar(50) | YES | | NULL | |
+-------+-------------+------+-----+---------+-------+
2 rows in set
将表 test 的 c2 列重命名为 c 并将其数据类型修改为 CHAR 类型的示例如下。
obclient> ALTER TABLE test CHANGE COLUMN c2 c CHAR(60);
修改后,执行语句 DESCRIBE test 查询表结构,结果如下。
+-------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| c1 | int(11) | NO | PRI | NULL | |
| c | char(60) | YES | | NULL | |
+-------+-------------+------+-----+---------+-------+
2 rows in set
修改列的默认值
修改列的 default 值为 2 的示例如下:
obclient> ALTER TABLE test CHANGE COLUMN c c2 varchar(50) DEFAULT 2;
修改后,执行语句 DESCRIBE test 查询表结构,结果如下。
+-------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| c1 | int(11) | NO | PRI | NULL | |
| c2 | varchar(50) | YES | | 2 | |
+-------+-------------+------+-----+---------+-------+
2 rows in set
或者您也可以通过以下语句修改列的默认值。
ALTER TABLE table_name ALTER [COLUMN] column_name {SET DEFAULT const_value | DROP DEFAULT}
修改列的 Skip Index 属性
OceanBase 数据库支持使用 ALTER TABLE 语句添加、修改和删除 Skip Index 属性。
更多有关 Skip Index 的信息,请参见 列 Skip Index 属性。
示例如下:
使用下面 SQL 语句创建表
test_skidx。CREATE TABLE test_skidx( col1 INT SKIP_INDEX(MIN_MAX, SUM), col2 FLOAT SKIP_INDEX(MIN_MAX), col3 VARCHAR(1024) SKIP_INDEX(MIN_MAX), col4 CHAR(10) );修改表
test_skidx中列col2的 Skip Index 属性为SUMSkip Index 类型。ALTER TABLE test_skidx MODIFY COLUMN col2 FLOAT SKIP_INDEX(SUM);建表后新增列的 Skip Index 属性。为表
test_skidx中列col4增加的MIN_MAXSkip Index 类型。ALTER TABLE test_skidx MODIFY COLUMN col4 CHAR(10) SKIP_INDEX(MIN_MAX);建表后删除列的 Skip Index 属性。删除表
test_skidx中列col1的 Skip Index 属性。ALTER TABLE test_skidx MODIFY COLUMN col1 INT SKIP_INDEX();或
ALTER TABLE test_skidx MODIFY COLUMN col1 INT;
修改列的 Collation 和字符集
如果添加列时,未在各个列的定义中指定列的字符集和字符序,则各个列将默认使用表的字符集和字符序。您可以根据业务需要,修改各个列的 Collation 和字符集设置。
假设有表 tbl1 的建表语句如下。
obclient> CREATE TABLE tbl1 (c1 int, c2 varchar(32), c3 varchar(32), PRIMARY KEY(c1), UNIQUE KEY uk1(c2));
修改表 tbl1 中 c2 列的 Collation 的示例如下:
obclient> ALTER TABLE tbl1 MODIFY COLUMN c2 varchar(32) COLLATE utf8mb4_bin;
OceanBase 数据库中,列的 Collation 和字符集的详细介绍信息请参见 列级字符集和字符序。
删除列
支持删除表中的普通列和含索引的列,但不允许删除主键列。
假设有一表 test,其表结构如下所示。
+-------+----------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+----------+------+-----+---------+-------+
| c1 | int(11) | NO | PRI | NULL | |
| c | char(60) | YES | | NULL | |
+-------+----------+------+-----+---------+-------+
2 rows in set
删除表中的普通列。
假设有一表
test,其表结构如下所示。+-------+----------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +-------+----------+------+-----+---------+-------+ | c1 | int(11) | NO | PRI | NULL | | | c | char(60) | YES | | NULL | | +-------+----------+------+-----+---------+-------+ 2 rows in set执行以下语句,删除
c列。obclient> ALTER TABLE test DROP c;删除后,执行语句
DESCRIBE test查询表结构,结果如下。+-------+---------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +-------+---------+------+-----+---------+-------+ | c1 | int(11) | NO | PRI | NULL | | +-------+---------+------+-----+---------+-------+ 1 row in set删除表中含索引的列。
假设有一表
test,其表结构如下所示。+-------+-------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +-------+-------------+------+-----+---------+-------+ | c1 | int(11) | NO | PRI | NULL | | | c2 | varchar(32) | YES | MUL | NULL | | | c3 | varchar(32) | YES | | NULL | | +-------+-------------+------+-----+---------+-------+ 3 rows in set执行以下语句,删除
c2列。obclient> ALTER TABLE test DROP c2;删除后,执行语句
DESCRIBE test查询表结构,结果如下。+-------+-------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +-------+-------------+------+-----+---------+-------+ | c1 | int(11) | NO | PRI | NULL | | | c3 | varchar(32) | YES | | NULL | | +-------+-------------+------+-----+---------+-------+ 2 rows in set
删除多列
删除多列的 SQL 语法如下:
ALTER TABLE table_name DROP COLUMN column_name1, DROP COLUMN column_name2, ...;
示例如下:
创建测试表
test_tbl5。CREATE TABLE test_tbl5 ( col1 NUMBER(38), col2 VARCHAR(50), col3 NUMBER(38), col4 NUMBER(38), col5 NUMBER(38), col6 NUMBER(38), col7 NUMBER(38), PRIMARY KEY(col1));删除表
test_tbl5的列col4和col5。ALTER TABLE test_tbl5 DROP COLUMN col4, DROP COLUMN col5;查看表
test_tbl5的结构。DESC test_tbl5;返回结果如下:
+-------+--------------+------+------+---------+-------+ | FIELD | TYPE | NULL | KEY | DEFAULT | EXTRA | +-------+--------------+------+------+---------+-------+ | COL1 | NUMBER(38) | NO | PRI | NULL | NULL | | COL2 | VARCHAR(50) | YES | NULL | NULL | NULL | | COL3 | NUMBER(38) | YES | NULL | NULL | NULL | | COL6 | NUMBER(38) | YES | NULL | NULL | NULL | | COL7 | NUMBER(38) | YES | NULL | NULL | NULL | +-------+--------------+------+------+---------+-------+ 3 rows in set
清除废弃列
当某些列被删除,即使这些列不再被使用,它们仍然占据物理存储空间。如果要移除这些废弃列并回收相关空间,需要清除废弃列。
清除废弃列的 SQL 语法如下:
ALTER TABLE table_name FORCE;
示例如下:
ALTER TABLE test_tbl5 FORCE;
修改索引
OceanBase 数据库支持增加唯一索引、普通索引和全文索引,同时还支持修改索引的属性。
增加唯一索引
OceanBase 数据库支持在创建表后为表增加唯一索引。如果创建表时同时设置了主键,OceanBase 数据库会默认为主键列创建一个唯一索引。
为表增加唯一索引的示例如下:
创建表
test。obclient> CREATE TABLE test (c1 int PRIMARY KEY, c2 VARCHAR(50));为表增加唯一索引。
obclient> ALTER TABLE test ADD UNIQUE INDEX index_name(c2);
增加普通索引
OceanBase 数据库支持一次增加多个索引,索引关键字用
INDEX或KEY均可以。为表增加普通索引的示例如下:
创建表
test。obclient> CREATE TABLE test (c1 int PRIMARY KEY, c2 VARCHAR(50));同时为表的
c1、c2列添加名为myidx的索引。obclient> ALTER TABLE test ADD INDEX myidx(c1,c2);
增加全文索引
OceanBase 数据库支持为已有的表添加全文索引。
示例如下:
创建表
test。CREATE TABLE test(col1 INT, col2 VARCHAR(20), col3 VARCHAR(50));为表
test添加全文索引ft_idx1_test,指定全文索引的分词器为BENG。ALTER TABLE test ADD FULLTEXT INDEX ft_idx1_test(col2) WITH PARSER BENG;
删除索引
OceanBase 数据库支持删除索引,删除多个索引时用逗号隔开,索引关键字用
INDEX或KEY均可以。示例如下:obclient> ALTER TABLE test DROP KEY index_name, DROP KEY index_name1;
更改表的主键、外键及 Check 约束
OceanBase 数据库支持更改表的主键、外键及 Check 约束,具体操作及详细说明请参见 定义列的约束类型。
更改表的副本数
设置表的副本数为 2。示例如下:
obclient> ALTER TABLE test SET REPLICA_NUM=2;
重命名表
表创建成功后,您可以更改表名。OceanBase 数据库支持重命名表。
示例如下:
obclient> ALTER TABLE test RENAME TO t1;
或者也可以使用以下语句:
obclient> RENAME TABLE test TO t1;
表行存列存转换
OceanBase 数据库默认建表时,构建的是行存表,通过设置 WITH COLUMN GROUP 选项可以显式指定为列存或者行存列存冗余状态。
表创建成功后,您可以使用 ALTER TABLE 语句对表进行行存列存转换,语法格式如下:
将表变更为列存表:
ALTER TABLE table_name ADD COLUMN GROUP([all columns,] each column) [DELAYED];移除表的存储格式:
ALTER TABLE table_name DROP COLUMN GROUP([all columns,] each column);
参数解释:
table_name:指定表名称。ADD COLUMN GROUP(all columns, each column):表示将表变更为行存列存冗余格式的表。ADD COLUMN GROUP(each column):表示将表变更为列存格式的表。DELAYED:可选项,表示延迟(异步)执行行存表转列存表命令,命令执行后表定义中的存储格式已做修改,但是真正执行行存转列存操作的时机是执行合并任务时,此操作不阻塞当前 DML,为 Online DDL。如果没有指定DELAYED,默认为 Offline DDL ,将同步操作行存表转为列存表。注意
- 当前仅支持将行存表修改为列存表(
each column)和将行存表修改为行存列存冗余格式的表(all columns, each column)时指定DELAYED。 - 在执行
DELAYED延迟操作行存表转列存表命令后,在基线数据实际完成合并前,由于数据存储格式没有真正的转换,查询性能可能不符合预期。
- 当前仅支持将行存表修改为列存表(
DROP COLUMN GROUP(all columns, each column):表示移除表的行存列存冗余格式。DROP COLUMN GROUP(all columns):表示移除表的行存格式。DROP COLUMN GROUP(each column):表示移除表的列存格式。
行存表转换为列存表
说明
将通过设置 WITH COLUMN GROUP(all columns) 选项创建的行存表转换为列存表时,再设置 ADD COLUMN GROUP(each column) 后,还要执行 DROP COLUMN GROUP(all columns) 命令来删除这个列组。
示例如下:
默认创建行存表。
创建行存表
tbl1。CREATE TABLE tbl1(col1 INT, col2 VARCHAR(30), col3 DATE);将行存表
tbl1换为列存表。Offline DDL 修改如下:
ALTER TABLE tbl1 ADD COLUMN GROUP(each column);Online DDL(异步将行存表转换为列存表)修改如下:
ALTER TABLE tbl1 ADD COLUMN GROUP(each column) DELAYED;
通过设置
WITH COLUMN GROUP(all columns)选项创建的行存表。创建行存表
tbl1。CREATE TABLE tbl1_ac(col1 INT, col2 VARCHAR(30), col3 DATE) WITH COLUMN GROUP(all columns);将行存表
tbl1换为列存表。Offline DDL 修改如下:
ALTER TABLE tbl1_ac ADD COLUMN GROUP(each column);Online DDL(异步将行存表转换为列存表)修改如下:
ALTER TABLE tbl1_ac ADD COLUMN GROUP(each column) DELAYED;
通过设置
DROP COLUMN GROUP(all columns)来删除行存格式。ALTER TABLE tbl1_ac DROP COLUMN GROUP(all columns);
行存表转换为行存列存冗余表
示例如下:
创建行存表
tbl2。CREATE TABLE tbl2(col1 INT, col2 VARCHAR(30), col3 DATE);将行存表
tbl2转换为行存列存冗余表。Offline DDL 修改如下:
ALTER TABLE tbl2 ADD COLUMN GROUP(all columns, each column);Online DDL(异步将行存表转换为行存列存冗余表)修改如下:
ALTER TABLE tbl2 ADD COLUMN GROUP(all columns, each column) DELAYED;
行存列存冗余表转换为列存表
示例如下:
创建行存列存冗余表
tbl3。CREATE TABLE tbl3(col1 INT, col2 VARCHAR(30), col3 DATE) WITH COLUMN GROUP(all columns, each column);将行存列存冗余表
tbl3转换为列存表。ALTER TABLE tbl3 DROP COLUMN GROUP(all columns);
行存列存冗余表转换为行存表
示例如下:
创建行存列存冗余表
tbl4。CREATE TABLE tbl4(col1 INT, col2 VARCHAR(30), col3 DATE) WITH COLUMN GROUP(all columns, each column);将行存列存冗余表
tbl4转换为行存表。ALTER TABLE tbl4 DROP COLUMN GROUP(each column);或者
ALTER TABLE tbl4 DROP COLUMN GROUP(all columns, each column);
修改现有表的聚集列
注意
修改现有表的聚集列会触发数据的重组,可能需要较长时间,请在业务低峰期执行。
对于已存在的表,可以使用 ALTER TABLE 语句来添加或更改聚集列,SQL 语句如下:
ALTER TABLE table_name [SET] CLUSTER BY (column_name_list);
column_name_list:
column_name [, column_name ...]
示例如下:
将 cb_tbl1 表的聚集列修改为仅按 col4 排序。
obclient> ALTER TABLE cb_tbl1 CLUSTER BY (col4);
删除现有表的聚集列
说明
删除聚集列完成后,表的数据将不再保证物理有序,恢复为堆表的组织方式。
如果不再需要聚集列,或者希望重新调整表结构,可以使用 ALTER TABLE 语句将其删除,SQL 语句如下:
ALTER TABLE table_name DROP CLUSTERING KEY;
示例如下:
删除 cb_tbl1 表的聚集列。
obclient> ALTER TABLE cb_tbl1 DROP CLUSTERING KEY;
相关文档
更多 ALTER TABLE 语句的介绍,请参见 ALTER TABLE。