---
title: "创建表 - OceanBase 数据库 V4.3.5 | OceanBase 文档中心"
description: 创建表 本文将向您介绍如何使用 SQL 语句来创建表，同时介绍创建表的前提条件、表简介和需要遵循的要求等，并提供一些示例。 表简介 表是一系列二维数组的集合，用来代表和储存数据对象之间的关系。通过合理设计和使用数据库表，可以提高数据的可靠性、一致性和查询性能，从而有效管理和利用数据库中的数据。 更多有关 OceanB…
---
切换语言

- 中文站 - 简体中文
- International - English
- 日本站 - 日本語

文档反馈![](https://mdn.alipayobjects.com/huamei_22khvb/afts/img/A*P8CuR4UJ_FkAAAAAAAAAAAAADiGDAQ/original) OceanBase 数据库分布式版 - V 4.3.5 LTS

# 创建表

更新时间：2026-04-07 20:57:19

[编辑](https://github.com/oceanbase/oceanbase-doc/edit/V4.3.5/zh-CN/300.develop/100.application-development-of-mysql-mode/300.database-object-planning-of-mysql-mode/300.create-table-of-mysql-mode-in-develop.md)  

本文将向您介绍如何使用 SQL 语句来创建表，同时介绍创建表的前提条件、表简介和需要遵循的要求等，并提供一些示例。

## 表简介

表是一系列二维数组的集合，用来代表和储存数据对象之间的关系。通过合理设计和使用数据库表，可以提高数据的可靠性、一致性和查询性能，从而有效管理和利用数据库中的数据。

更多有关 OceanBase 数据库表的详细信息，请参见 [表概述](https://www.oceanbase.com/docs/common-oceanbase-database-cn-1000000002016766)。

## 前提条件

在创建表前，您需要确认以下事项：

- 您已部署 OceanBase 集群并且创建了 MySQL 模式租户。更多有关部署 OceanBase 集群的信息，请参见 [部署概述](https://www.oceanbase.com/docs/common-oceanbase-database-cn-1000000002012734)。
 - 您已连接到 OceanBase 数据库的 MySQL 租户。更多连接数据库的信息，请参见 [连接方式概述](https://www.oceanbase.com/docs/common-oceanbase-database-cn-1000000002013253)。
 - 您已创建数据库。更多有关创建数据库的信息，请参见 [创建数据库](https://www.oceanbase.com/docs/common-oceanbase-database-cn-1000000002013232)。
 - 您已拥有 `CREATE` 权限。查看当前用户权限的相关操作请参见 [查看用户权限](https://www.oceanbase.com/docs/common-oceanbase-database-cn-1000000002016102)。如果不具备该权限，请联系管理员为您授权，用户授权的相关操作请参见 [直接授予权限](https://www.oceanbase.com/docs/common-oceanbase-database-cn-1000000002016096)。

## 使用命令行创建表

请使用 [CREATE TABLE](https://www.oceanbase.com/docs/common-oceanbase-database-cn-1000000002017069) 语句创建表。

#### 说明

您可以使用 `SHOW TABLES;` 语句查看数据库中表的信息。

### 定义表名

创建表时，需要先为表命名，以下是定义表名时需要遵循的要求：

- 在 OceanBase 数据库的 MySQL 模式中，每个表的名称必须保证在数据库内唯一。
 - 表名称不能超过 64 个字符。
 - 建议给表起一个有意义的名字，不要使用 `t1`、`table1` 这样的表名。更多表命名规范信息，请参见 [表命名规范](https://www.oceanbase.com/docs/common-oceanbase-database-cn-1000000002013334)。

示例 1：创建一个有关订单信息的表。

#### 注意

因为未添加列信息，所以下方这条 SQL 暂时还不能被运行。

```sql
CREATE TABLE orders (...);

```

### 定义列

​在数据库中，列（Column）用于记录一张表上某个属性的字段的值，用户给每个属性起的名称即为列名。除了列名以外，列上还有数据类型以及数据类型的最大长度（精度）等信息。

以下是定义表的列时需要遵循的要求：

- 根据数据类型的特点，为待存储在列中的数据选择合适的数据类型。

  OceanBase 数据库 MySQL 模式中支持的数据类型及详细介绍请参见 [数据类型概述](https://www.oceanbase.com/docs/common-oceanbase-database-cn-1000000002017567)。
 - 对于字符串数据，建议使用变长字符串数据类型，并指定最大长度。请确保指定的最大长度大于需要存储的最大字符数，避免超出最大长度时出现字符截断现象。
 - 根据 [主键列](#定义主键列) 的要求，确认是否需要为表定义主键列。
 - 根据 [其他约束](#定义其他列约束) 的要求，确认是否需要向列中添加其他约束。
 - 当列上有 `NOT NULL` 约束时，通常建议为该列设置默认值。当列类型为日期或时间类型时，可以设置默认值为数据库的当前时间。

### 定义主键列

主键值规则（Primary Key Value Rule）是定义在某一键 Key（键指一列或一个列集）上的规则，其作用是确保表内的每一数据行都可以由某一个键值唯一地确定。每个数据库表上最多只能定义一个 `PRIMARY KEY` 约束。构成此约束的列（一列或多列）的值可以作为一行数据的唯一标识符，即每个数据行可以由此主键值命名。

要指定某一列为主键列，请在该列的定义后添加 `PRIMARY KEY` 关键字。如果要在多列上定义主键约束，请在 [CREATE TABLE](https://www.oceanbase.com/docs/common-oceanbase-database-cn-1000000002017069) 语句中所有列的列表之后再添加主键约束的定义。

以下是定义主键列时需要遵循的要求：

- 建议为表定义一个主键，每个数据库表最多拥有一个主键列集合。

  在 OceanBase ​数据库中，不强制用户为表定义主键，但使用主键可以使表内的每行数据被唯一确定，且不存在重复的数据行。如果没有合适的字段作为主键，可以在创建表时不指定主键，待表创建成功后系统会为无主键表指定自增列作为隐藏主键。有关自增列的详细介绍请参见 [定义自增列](https://www.oceanbase.com/docs/common-oceanbase-database-cn-1000000002015440)。

  此外，如果在创建时未定义主键列，OceanBase 数据库支持为已存在的表添加主键列。
 - 主键列集合的值在全表范围内唯一。
 - 主键列的数量不能超过 64 列，且主键数据总长度不能超过 16 KB。
 - 主键列的值不能为 NULL 或空字符串，您必须为主键列输入值。
 - 建议明确标识主键约束的名称。例如，主键约束命名为 “PK_xxx”。

更多主键约束相关的介绍，请参见 [主键约束](https://www.oceanbase.com/docs/common-oceanbase-database-cn-1000000002017305)。

示例 2：在多列上定义主键约束。

```shell
obclient> CREATE TABLE test(c1 INT, c2 INT, CONSTRAINT PK_c1_c2 PRIMARY KEY(c1, c2));
Query OK, 0 rows affected

obclient> desc test;
+-------+---------+------+-----+---------+-------+
| Field | Type    | Null | Key | Default | Extra |
+-------+---------+------+-----+---------+-------+
| c1    | int(11) | NO   | PRI | NULL    |       |
| c2    | int(11) | NO   | PRI | NULL    |       |
+-------+---------+------+-----+---------+-------+
2 rows in set

```

示例 2 中，定义了 `c1`、`c2` 列为主键列，且约束名称为 `PK_c1_c2`。 `c1`、`c2` 列的值不允许为 `NULL` 并且必须是不重复的。

定义主键列后，支持删除主键，更多主键约束相关的操作请参见 [定义列的约束类型](https://www.oceanbase.com/docs/common-oceanbase-database-cn-1000000002015447)。

### 定义其他列约束

除了 `PRIMARY KEY` 约束外，OceanBase 数据库还支持 `NOT NULL` 约束、唯一性（UNIQUE）约束、外键（FOREIGN KEY）约束和 `CHECK` 约束。使用约束可以简化表查询、提高查询性能并确保数据在语义上保持有效。

各约束类型及说明如下：

- 非空约束（`NOT NULL`）：表示不允许约束包含的列的值为 `NULL`。

  对于有非空约束的列，在 `INSERT` 语句中必须指定该列的值，除非该列还定义了非空的默认值。
 - 唯一性约束（`UNIQUE`）：不允许约束包含的列的值有重复值，但是可以有多个 `NULL` 值。
 - 外键约束（`FOREIGN KEY`）：要求约束的列的值取自于另外一个表的主键列。

  创建外键约束时，如果不指定外键名，系统会自动分配一个约束名，自动分配的约束名为 `表名_OBFK_创建时间戳`。例如，`t1_OBFK_1627747200000000`。

  OceanBase 数据库默认开启了外键约束检查，外键约束检查开关由租户变量 `foreign_key_checks` 来控制。`foreign_key_checks` 变量的更多说明，请参见 [foreign_key_checks](https://www.oceanbase.com/docs/common-oceanbase-database-cn-1000000002016028)。
 - `CHECK` 约束：要求数据库中某列的值符合指定的条件。

  可以对单个列定义一个或多个 `CHECK` 约束，使该列只允许特定的值，也可以定义表级的 `CHECK` 约束，将一个 `CHECK` 约束应用于多个列。修改表名时，`CHECK` 约束名不会被修改。删除某个表时，同时也会删除应用于该表的 `CHECK` 约束。

  创建 `CHECK` 约束时，如果未指定约束名称，系统会自动分配一个约束名，自动分配的约束名为 `表名_OBCHECK_创建时间戳`，例如，`t1_OBCHECK_1629350823880271`。

要约束单个列，请在该列的定义中添加一个约束关键字，如果要约束多个列，请在 [CREATE TABLE](https://www.oceanbase.com/docs/common-oceanbase-database-cn-1000000002017069) 语句中所有列的列表之后再添加整个约束的定义。

以下是定义其他列约束时需要遵循的要求：

- 建议给明确不存在 NULL 值的字段加上 `NOT NULL` 约束。
 - 如果要引用另一个表中的值，请使用外键约束。
 - 组合主键不能作为外键使用。
 - 如果需要防止列中出现重复值，请使用唯一约束。
 - 除 `NOT NULL` 约束外，建议明确标识其他约束的名称。例如，唯一约束命名为 “UNI_xxx”，外键约束命名为 “FK_xxx”。

示例 3：创建表 `tbl1`，并设置列 `col1` 为非空约束。

```shell
obclient> CREATE TABLE tbl1(col1 INT NOT NULL,col2 INT);
Query OK, 0 rows affected

obclient> DESC tbl1;
+-------+---------+------+-----+---------+-------+
| Field | Type    | Null | Key | Default | Extra |
+-------+---------+------+-----+---------+-------+
| col1  | int(11) | NO   |     | NULL    |       |
| col2  | int(11) | YES  |     | NULL    |       |
+-------+---------+------+-----+---------+-------+
2 rows in set

```

示例 3 中，后续插入数据时，列 `col1` 插入的值不能为 `NULL`。

示例 4：创建表 `tbl2`，并设置列 `col1` 为唯一性约束。

```shell
obclient> CREATE TABLE tbl2(col1 INT UNIQUE,col2 INT);
Query OK, 0 rows affected

obclient> desc tbl2;
+-------+---------+------+-----+---------+-------+
| Field | Type    | Null | Key | Default | Extra |
+-------+---------+------+-----+---------+-------+
| col1  | int(11) | YES  | UNI | NULL    |       |
| col2  | int(11) | YES  |     | NULL    |       |
+-------+---------+------+-----+---------+-------+
2 rows in set

```

示例 4 中，列 `col1` 的值不能有重复值。

示例 5：创建外键约束。

```shell
obclient> CREATE TABLE test(c1 INT, c2 INT, CONSTRAINT PK_c1 PRIMARY KEY(c1));
Query OK, 0 rows affected

obclient> CREATE TABLE tbl3(col1 INT PRIMARY KEY,col2 INT,CONSTRAINT FK_col2 FOREIGN KEY(col2) REFERENCES test(c1));
Query OK, 0 rows affected

obclient> SELECT * FROM information_schema.TABLE_CONSTRAINTS;
+--------------------+-------------------+-------------------------------+--------------+------------+-----------------+----------+
| CONSTRAINT_CATALOG | CONSTRAINT_SCHEMA | CONSTRAINT_NAME               | TABLE_SCHEMA | TABLE_NAME | CONSTRAINT_TYPE | ENFORCED |
+--------------------+-------------------+-------------------------------+--------------+------------+-----------------+----------+
| def                | xxx               | PRIMARY                       | xxx          | test       | PRIMARY KEY     | YES      |
| def                | xxx               | PRIMARY                       | xxx          | tbl3       | PRIMARY KEY     | YES      |
| def                | xxx               | FK_col2                       | xxx          | tbl3       | FOREIGN KEY     | YES      |
+--------------------+-------------------+-------------------------------+--------------+------------+-----------------+----------+
3 rows in set

```

示例 5 中，表 `tbl3` 的列 `col2` 关联另一个表 `test` 的主键列 `c1`。创建成功后，可以通过 `information_schema.TABLE_CONSTRAINTS` 视图查看。

示例 6：创建表 `tbl4`，并设置列 `col1` 的值需大于 `10`。

```shell
obclient> CREATE TABLE tbl4(col1 INT CHECK(col1>10),col2 INT);
Query OK, 0 rows affected

obclient> INSERT INTO tbl4 VALUES(2,2);
ERROR 3819 (HY000): check constraint violated

obclient> INSERT INTO tbl4 VALUES(11,2);
Query OK, 1 row affected

```

示例 6 中，由于 `col1` 列添加了 `CHECK` 约束，后续插入列 `col1` 的值不大于 `10` 时就会报错。

定义其他列约束的详细操作请参见 [定义列的约束类型](https://www.oceanbase.com/docs/common-oceanbase-database-cn-1000000002015447)。

### 定义表的自增列

在 OceanBase 数据库中，如果创建表时需要某个数值列的值不重复并且保持递增，可以将表中列的类型定义为 `AUTO_INCREMENT`，即自增列。

自增列有三个重要属性，包括自增起始值、自增步长和自增列缓存大小，通过 `auto_increment_cache_size`、`auto_increment_increment` 和 `auto_increment_offset` 三个租户变量来控制。

| 变量名 | 说明 |
| --- | --- |
| auto_increment_cache_size | Global 级变量，用于设置自增的缓存个数，取值范围为 [1, 100000000]，默认值为 `1000000`。 |
| auto_increment_increment | Session 级变量，用于设置自增步长，取值范围为 [1, 65535]，默认值为 `1`。 |
| auto_increment_offset | Session 级变量，用于确定 `AUTO_INCREMENT` 列值的起点，取值范围为 [1, 65535]，默认值为 `1`。 |

您可以根据业务需要，修改这三个系统变量的值，修改系统变量的操作请参见 [配置项和系统变量概述](https://www.oceanbase.com/docs/common-oceanbase-database-cn-1000000002013018)。

以下是定义自增列需要遵循的要求：

- `AUTO_INCREMENT` 是数据列的一种属性，仅适用于整数类型的数据列。
 - `AUTO_INCREMENT` 所在的数据列必须具备 `NOT NULL` 属性。
 - 创建分区表时，若使用自增列作为分区键，则在 OceanBase 数据库中，自增列的值全局唯一，但在分区内不保证递增。

自增列创建后，如果使用 `INSERT` 语句插入数据时指定了自增列的值，且系统变量 `SQL_MODE` 未设置为 `NO_AUTO_VALUE_ON_ZERO`，如果指定的值为 `0`，则系统会使用自增列的下一个值填充列的值；如果指定的值比当前最大值小，则不影响自增列的下一个值的计算；如果指定的值比当前值最大值大，则自增列会将本次插入值与自增列缓存值的和作为下次自增的起始值。

#### 说明

如果系统变量 `SQL_MODE` 的值为 `NO_AUTO_VALUE_ON_ZERO`，则表示不要在插入值为零的列中生成 `AUTO_INCREMENT`。

示例 7：创建一个含自增列的表。

```shell
obclient> CREATE TABLE personal_info(id bigint NOT NULL AUTO_INCREMENT PRIMARY KEY, name varchar(50), gmt_create timestamp NOT NULL default current_timestamp);
Query OK, 0 rows affected

```

示例 7 中，由于设置了 `id` 列为自增列，所以在使用 `INSERT` 语句插入数据时不需要指定自增列的值，系统就会自动为该列填充值，如下所示。

```shell
obclient> INSERT INTO personal_info(name) VALUES('A'),('B'),('C');
Query OK, 3 rows affected
Records: 3  Duplicates: 0  Warnings: 0

obclient> SELECT * FROM personal_info;
+----+------+---------------------+
| id | name | gmt_create          |
+----+------+---------------------+
|  1 | A    | 2020-04-03 17:09:55 |
|  2 | B    | 2020-04-03 17:09:55 |
|  3 | C    | 2020-04-03 17:09:55 |
+----+------+---------------------+
3 rows in set

```

更多自增列的介绍和详细操作请参见 [定义自增列](https://www.oceanbase.com/docs/common-oceanbase-database-cn-1000000002015440)。

### 选择分区方案

在创建表时，需要明确表的分区方案，如果表中的数据量很大时，建议对表进行分区。创建分区表时，需要根据待存储在表中的数据来选择合适的分区方式。

OceanBase 数据库的 MySQL 模式中，单个表最多支持创建的分区个数为由租户级配置项 [max_partition_num](https://www.oceanbase.com/docs/common-oceanbase-database-cn-1000000002015551) 控制，默认为 8192 个。

在 OceanBase 数据库的 MySQL 模式中，按照分区策略，分区表可以分为：

- Range 分区 / Range Columns 分区
 - List 分区 / List Columns 分区
 - Hash 分区 / key 分区
 - 组合分区

按照分区维度，分区表又可以分为一级分区和二级分区，二级分区是一级分区的二次拆分，因此一级分区表有一个分区键，二级分区表有两个分区键，并且两次拆分的策略可以不一样。在 OceanBase 数据库中，二级分区表包括模板化二级分区表和非模板化二级分区表。

关于分区相关的详细介绍请参见 [分区概述](https://www.oceanbase.com/docs/common-oceanbase-database-cn-1000000002016759)。

**Range 分区/Range Columns 分区**

Range 分区和 Range Columns 分区都是按照每个分区建立的分区键值范围来划分分区。通常适用于对分区键需要按照范围的查询。例如，按照时间字段或者价格区间等进行范围分区。

Range 分区 和 Range Columns 分区的区别如下：

- Range 分区的分区键必须是整数类型，如果对日期字段分区，则需要使用函数进行转换。例如，针对 date 字段进行分区时，要使用 `YEAR()` 函数进行转换。而 Range Columns 分区的分区键不要求是整数，可以是任意类型。
 - Range 分区的分区键可以写表达式，但不能是列（列向量），例如，不能写 `partition by range(c1, c2)`。Range Columns 分区的分区键不能写表达式，但是可以是多列（列向量）。

Range 分区和 Range Columns 分区使用 `VALUES LESS THAN(value)` 关键字来定义每个分区，其中 `value` 的值只能是连续不重叠的从小到大的值。

示例 8：创建 Range Columns 分区表。

```shell
obclient> CREATE TABLE tb1_rc(col1 INT,col2 INT)
       PARTITION BY RANGE COLUMNS(col1)
        (PARTITION p0 VALUES LESS THAN(100),
         PARTITION p1 VALUES LESS THAN(200),
         PARTITION p2 VALUES LESS THAN(300)
        );
Query OK, 0 rows affected

```

示例 8 中，由于 Range Columns 分区的分区键可以是任意类型，可以使用 `col1` 列名作为分区键，分区表 `tb1_rc` 将会按照 `100、200、300` 的数值范围进行分区。`p0、p1、p2` 为指定的分区名，可以自定义，只需要满足同一个表中每个分区名不重复即可。

**List 分区/List Columns 分区**

List 分区是根据具体的数值分区，每个分区的数值不重叠。List 分区的优点是可以方便的对无序或无关的数据集进行分区。

如果要使用多列的 List 分区，或者其他数据类型的 List 分区，可以使用 List Columns 分区。List Columns 分区是 List 分区的一个扩展，支持多个分区键，并且支持 INT 数据、DATE 类型和 DATETIME 类型。

List 分区和 List Columns 分区的区别如下：

- List 分区的分区键必须是整数类型，List Columns 分区的分区键可以是任意类型。
 - List 分区仅支持单分区键，其分区键可以是一列，也可以是表达式，List Columns 分区的分区键不能是表达式，但可以是多列（列向量）。

List 分区和 List Columns 分区使用 `VALUES IN(value_list)` 关键字来定义每个分区。

示例 9：创建一个 List 分区表。

```shell
obclient> CREATE TABLE tbl2_l (col1 INT,col2 DATE)
       PARTITION BY LIST(col1)
        (PARTITION p0 VALUES IN (100),
         PARTITION p1 VALUES IN (200)
        );
Query OK, 0 rows affected

```

示例 9 中，由于 List 分区的分区键必须是整数类型，使用 `col1` 列作为分区键，分区表 `tbl2_l` 将会按照 `100、200` 的范围对数值进行分区。

**Hash 分区/key 分区**

Hash 分区需要指定分区键和分区个数。系统通过 Hash 的分区表达式计算得到一个整数，根据这个结果再跟分区个数取模可以得到具体某行数据属于哪个分区。

Key 分区与 Hash 分区类似，都是通过对分区个数取模的方式来确定数据属于哪个分区。不同的是系统会对 Key 分区键做一个内部默认的 Hash 函数后再取模。所以用户通常没有办法自己通过简单的计算来得知某一行属于哪个分区。

Key 分区 与 Hash 分区的区别如下：

- Hash 分区的分区键必须是整数，Key 分区没有该要求，且支持字符列。
 - Hash 分区的分区键支持表达式，Key 分区的分区键不能是表达式。

示例 10：创建一个 HASH 分区表 `tbl3_h`。

```shell
obclient> CREATE TABLE tbl3_h(col1 INT,col2 VARCHAR(50))
    PARTITION BY HASH(col1) PARTITIONS 2;
Query OK, 0 rows affected

```

示例 10 中，由于 Hash 分区的分区键必须是整数，可以使用 `col1` 作为分区键，将表 `tbl3_h` 分为 2 个 区。由于创建表时，未指定分区的名称，分区命名由系统根据命名规则完成，即每个分区分别命名为 p0、p1、...、pn。

**组合分区（二级分区）**

组合分区通常是先使用一种分区策略，然后在子分区再使用另外一种分区策略，适合于业务表的数据量非常大时。使用组合分区能发挥多种分区策略的优点。

Range 分区、Range Columns 分区、List 分区、List Columns 分区、Hash 分区 和 key 分区均可以作为组合分区表的二级分区策略。在 OceanBase 数据库中，二级分区表包括模板化二级分区表和非模板化二级分区表。

下面通过几个简单示例，简单介绍二级分区表的创建方法。

示例 11：创建模板化 Range Columns + Range 分区表。

```shell
obclient> CREATE TABLE tb1_m_rcr(col1 INT,col2 INT)
         PARTITION BY RANGE COLUMNS(col1)
         SUBPARTITION BY RANGE(col2)
         SUBPARTITION TEMPLATE
          (SUBPARTITION mp0 VALUES LESS THAN(3),
           SUBPARTITION mp1 VALUES LESS THAN(6),
           SUBPARTITION mp2 VALUES LESS THAN(9)
          )
          (PARTITION p0 VALUES LESS THAN(100),
           PARTITION p1 VALUES LESS THAN(200),
           PARTITION p2 VALUES LESS THAN(300)
          );
Query OK, 0 rows affected

obclient> SELECT table_name,partition_name,subpartition_name FROM information_schema.partitions;
+------------+----------------+-------------------+
| table_name | partition_name | subpartition_name |
+------------+----------------+-------------------+
| tb1_m_rcr  | p0             | p0smp0            |
| tb1_m_rcr  | p0             | p0smp1            |
| tb1_m_rcr  | p0             | p0smp2            |
| tb1_m_rcr  | p1             | p1smp0            |
| tb1_m_rcr  | p1             | p1smp1            |
| tb1_m_rcr  | p1             | p1smp2            |
| tb1_m_rcr  | p2             | p2smp0            |
| tb1_m_rcr  | p2             | p2smp1            |
| tb1_m_rcr  | p2             | p2smp2            |
+------------+----------------+-------------------+
9 rows in set

```

示例 11 中，由于 Range 分区的分区键要求为整数类型，二次分区可以直接使用 `col2` 列名作为分区键，使用 `SUBPARTITION TEMPLATE` 关键字来创建模板化二级分区表。模板化二级分区表的每个一级分区下的二级分区都按照模板中的二级分区定义，即每个一级分区下的二级分区定义均相同。本示例中，先使用 Range Columns 分区方式进行分区，再使用 Range 分区方式进行二次分区。

此外，创建模板化二级分区时，完成二级分区的定义后，不需要单独指定每个分区的分区名，由系统根据命名规则统一完成，每个二级分区的命名规则为 `($part_name)s($subpart_name)`，可以看到，本示例中，一级分区 `p0` 对应的二级分区的分区名分别为 `p0smp0`、`p0smp1`、`p0smp2`。

#### 注意

对于 Hash/Key 分区，如果是通过指定分区数的方式（例如，`SUBPARTITIONS 5`）进行二次分区，则在创建模板化二级分区表时，不需要指定 `SUBPARTITION TEMPLATE` 关键字。

示例 12：创建非模板化 List + List Columns 分区表。

```shell
obclient> CREATE TABLE tbl2_f_llc(col1 INT,col2 DATE)
       PARTITION BY LIST(col1)
       SUBPARTITION BY LIST COLUMNS(col2)
        (PARTITION p0 VALUES IN(100)
           (SUBPARTITION sp0 VALUES IN('2021/04/01'),
            SUBPARTITION sp1 VALUES IN('2021/07/01'),
            SUBPARTITION sp2 VALUES IN('2021/10/01'),
            SUBPARTITION sp3 VALUES IN('2022/01/01')
           ),
         PARTITION p1 VALUES IN(200)
           (SUBPARTITION sp4 VALUES IN('2021/04/01'),
            SUBPARTITION sp5 VALUES IN('2021/07/01'),
            SUBPARTITION sp6 VALUES IN('2021/10/01'),
            SUBPARTITION sp7 VALUES IN('2022/01/01')
            )
         );
Query OK, 0 rows affected

```

示例 12 中，创建的是非模板化二级分区表，需要为每个一级分区定义其二级分区，每个一级分区下的二级分区的定义可以相同也可以不同。

示例 13：创建非模板化 Hash + Key 分区表。

```shell
obclient> CREATE TABLE tbl3_f_hk (col1 INT,col2 VARCHAR(50))
     PARTITION BY HASH(col1)
     SUBPARTITION BY KEY(col2)
      (PARTITION p1
       (SUBPARTITION sp0
       ,SUBPARTITION sp1
       ,SUBPARTITION sp2
       ,SUBPARTITION sp3
       ),
       PARTITION p2
       (SUBPARTITION sp4
       ,SUBPARTITION sp5
       ,SUBPARTITION sp6
       ,SUBPARTITION sp7
       )
      );
Query OK, 0 rows affected

```

示例 13 中，由于 Key 分区支持字符列作为分区键，可以使用 `col2` 列作为分区键进行二次分区，其中 `sp0、……、sp7` 为指定的二级分区名。

## 创建复制表

复制表是 OceanBase 数据库的一种特殊表。这种表可以在任意一个 “健康” 的副本上读取到数据的最新修改。对于写入频率较低、读取频率较高的场景，复制表是一种很好的选择。

更多复制表信息，请参见管理员指南下 [创建表](https://www.oceanbase.com/docs/common-oceanbase-database-cn-1000000002015448) 中的 **创建复制表** 章节。

#### 注意

仅用户租户可以创建复制表，`sys` 租户无法创建复制表。

创建复制表的 SQL 语法如下：

```sql
CREATE TABLE table_name column_definition DUPLICATE_SCOPE='none | cluster';

```

参数解释：

- `table_name`：表名。
 - `column_definition`：表的列信息。比如，列定义、主键定义等。
 - `DUPLICATE_SCOPE`：用来指定复制表的属性，取值如下：

     - `none`：表示该表是一个普通表。
     - `cluster`：表示该表是一个复制表，Leader 需要将事务复制到当前租户的所有 F 副本及 R 副本。

示例 14：使用下面 SQL 语句，创建复制表 `test_tbl14`。

```sql
CREATE TABLE test_tbl14 (col1 INT,col2 INT) DUPLICATE_SCOPE= 'cluster';

```

## 后续操作

创建表完成后，您可能需要执行以下一些后续操作来完善表的使用和管理：

- 创建表后，可以使用 `INSERT` 语句将数据插入到表中。更多有关插入数据的详细信息，请参见 [插入数据](https://www.oceanbase.com/docs/common-oceanbase-database-cn-1000000002013243)。
 - 如果需要提高查询性能，可以为表中的列创建索引。更多有关创建索引的详细信息，请参见 [创建索引](https://www.oceanbase.com/docs/common-oceanbase-database-cn-1000000002013233)。

## 相关文档

- 更多有关查看表属性的详细信息，请参见 [查看表的定义](https://www.oceanbase.com/docs/common-oceanbase-database-cn-1000000002015446)。
 - 更多有关删除表的详细信息，请参见 [删除表](https://www.oceanbase.com/docs/common-oceanbase-database-cn-1000000002015443)。
 - 更多有关修改表结构的详细信息，请参见 [更改表](https://www.oceanbase.com/docs/common-oceanbase-database-cn-1000000002015441)。
 - 更多有关创建分区表的详细信息，请参见 [创建分区表](https://www.oceanbase.com/docs/common-oceanbase-database-cn-1000000002015453)。

 上一篇 下一篇 ![有帮助](https://gw.alipayobjects.com/mdn/ob_asset/afts/img/A*y6ocSqN8cqsAAAAAAAAAAAAAARQnAQ)![无帮助](https://gw.alipayobjects.com/mdn/ob_asset/afts/img/A*BG9IQJyLHF8AAAAAAAAAAAAAARQnAQ)![反馈](https://gw.alipayobjects.com/mdn/ob_asset/afts/img/A*eTWdQKCRKHwAAAAAAAAAAAAAARQnAQ)[AI](https://www.oceanbase.com/obi) 咨询热线
