CREATE TABLE建表语法
本文介绍CREATE TABLE建表语法,包含5种常见场景的建表模板、完整参数说明和常见问题。
快速建表指南
根据您的业务场景,选择以下建表模板快速开始。每个场景提供最小可用的建表语句和关键注意事项。详细参数说明请参见下方参数章节。
场景1:按日期分区的事实表(最常见)
适用于业务数据按日期持续写入,需要按日期查询和管理数据生命周期的场景,如订单表、日志表、行为数据表。
CREATE TABLE sales (
sale_id BIGINT NOT NULL COMMENT '订单ID',
customer_id VARCHAR NOT NULL COMMENT '顾客ID',
revenue DECIMAL(15, 2) COMMENT '订单金额',
sale_time TIMESTAMP NOT NULL COMMENT '订单时间',
PRIMARY KEY (sale_time, sale_id)
)
DISTRIBUTED BY HASH(sale_id)
PARTITION BY VALUE(DATE_FORMAT(sale_time, '%Y%m%d'))
LIFECYCLE 365;
主键必须包含分布键和分区键。上例中
sale_id(分布键)和sale_time(分区键)都在主键中。详见PRIMARY KEY。分区键建议使用TIMESTAMP或DATE类型。详见PARTITION BY。
INSERT遇到主键重复时,系统会静默忽略重复记录,不会报错。请确保主键能唯一标识每条记录。
场景2:冷热分层分区表(降低存储成本)
适用于历史数据查询频率低,希望将冷数据存储在OSS以降低成本,同时保证近期数据查询性能的场景。
CREATE TABLE order_history (
order_id BIGINT NOT NULL,
customer_id INT NOT NULL,
order_date DATE NOT NULL,
amount DECIMAL(15, 2),
PRIMARY KEY (order_date, order_id)
)
DISTRIBUTED BY HASH(order_id)
PARTITION BY VALUE(DATE_FORMAT(order_date, '%Y%m')) LIFECYCLE 120
STORAGE_POLICY='MIXED' HOT_PARTITION_COUNT=3;
COLD和MIXED策略仅对分区表生效。非分区表即使设置了COLD或MIXED,数据仍存储在SSD(等同于HOT)。详见storage_policy。
冷热分离只能在表级别设置,不支持库级别操作。
HOT_PARTITION_COUNT=3表示最近3个分区的数据存热存储(SSD),其余存冷存储(OSS)。上例按月分区,因此最近3个月的数据为热存储,3个月之前的数据为冷存储。
场景3:带聚集索引的高性能查询表
适用于表数据量大,高频进行范围查询,需要通过聚集索引优化读取性能的场景,如SaaS多租户表按tenant_id查询。
CREATE TABLE user_events (
tenant_id VARCHAR NOT NULL COMMENT '租户ID',
event_id BIGINT NOT NULL,
event_time TIMESTAMP NOT NULL,
event_type VARCHAR,
CLUSTERED KEY idx_tenant(tenant_id, event_time DESC),
PRIMARY KEY (event_time, tenant_id, event_id)
)
DISTRIBUTED BY HASH(tenant_id)
PARTITION BY VALUE(DATE_FORMAT(event_time, '%Y%m%d'))
LIFECYCLE 90;
聚集索引需BUILD后才能生效。创建表或通过ALTER TABLE添加聚集索引后,需等待BUILD任务完成(或手动执行
BUILD TABLE table_name)。详见CLUSTERED KEY。当查询条件不包含分布键时,查询需扫描所有分片。如果业务查询无法覆盖分布键,建议为高频查询列创建聚集索引(CLUSTERED KEY)。
每个表只能有一个聚集索引。聚集索引默认升序,降序查询请将聚集索引设为DESC。
场景4:非分区表(小表/维度表)
适用于数据量较小(千万级以下)、无需按时间管理生命周期的表。
CREATE TABLE product (
product_id BIGINT NOT NULL PRIMARY KEY,
product_name VARCHAR,
category VARCHAR,
price DECIMAL(10, 2)
)
DISTRIBUTED BY HASH(product_id);
未定义主键和分布键时,系统自动添加
__adb_auto_id__列作为主键和分布键。非分区表的所有数据在同一分区,数据量超过千万行时索引扫描效率会下降。大表建议使用分区表。
场景5:复制表(小型查找表)
适用于数据量小(建议不超过2万行)的维度表,需要与大表频繁JOIN。
CREATE TABLE dim_city (
city_id INT NOT NULL PRIMARY KEY,
city_name VARCHAR,
province VARCHAR
)
DISTRIBUTED BY BROADCAST;
复制表在每个节点存一份全量数据,JOIN时无需跨节点传输,但写入会广播到所有节点。
数据量不宜超过2万行。不建议频繁增删改。
注意事项
以下属性建表后不可修改,请在建表前仔细规划:
主键:不能增加、减少或变更主键列。
分布键:不能增加、减少或变更分布键列,需重建表并迁移数据。
分区键:不能增加分区键(即不能将非分区表变更为分区表),也不支持增加、减少或修改分区键中的列,需重建表。
存储引擎:不能切换存储引擎(XUANWU和XUANWU_V2之间不能互相切换),需重建表。
语法
CREATE TABLE [IF NOT EXISTS] table_name
({column_name column_type [column_attributes] [ column_constraints ] [COMMENT 'column_comment']
| table_constraints}
[, ... ])
[table_attribute]
[partition_options]
[index_all]
[storage_policy]
[block_size]
[engine]
[table_properties]
[AS query_expr]
[COMMENT 'table_comment']
column_attributes:
[DEFAULT {constant | CURRENT_TIMESTAMP}]
[AUTO_INCREMENT]
column_constraints:
[{NOT NULL|NULL} ]
[PRIMARY KEY]
table_constraints:
[{INDEX|KEY} [index_name] (column_name|column_name->'$.json_path'|column_name->'$[*]')][,...]
[FULLTEXT [INDEX|KEY] [index_name] (column_name) [index_option]] [,...]
[PRIMARY KEY [index_name] (column_name,...)]
[CLUSTERED KEY [index_name] (column_name[ASC|DESC],...) ]
[[CONSTRAINT [symbol]] FOREIGN KEY (fk_column_name) REFERENCES pk_table_name (pk_column_name)][,...]
[ANN INDEX [index_name] (column_name,...) [index_option]] [,...]
table_attribute:
DISTRIBUTED BY HASH(column_name,...) | DISTRIBUTED BY BROADCAST
partition_options:
PARTITION BY
{VALUE(column_name) | VALUE(DATE_FORMAT(column_name, 'format')) | VALUE(FROM_UNIXTIME(column_name, 'format'))}
LIFECYCLE N
index_all:
INDEX_ALL= 'Y|N'
storage_policy:
STORAGE_POLICY= {'HOT'|'COLD'|'MIXED' {hot_partition_count=N}}
block_size:
BLOCK_SIZE= VALUE
engine:
ENGINE= 'XUANWU|XUANWU_V2'
参数
table_name、column_name、column_type、COMMENT
示例
完整的建表场景和模板请参见快速建表指南。以下示例展示特定功能的用法。
新建非分区表
未定义分布键和分区键,系统自动将主键作为分布键
表定义了主键但未定义分布键,AnalyticDB for MySQL默认将主键作为分布键。
CREATE TABLE orders (
order_id BIGINT NOT NULL COMMENT '订单ID',
customer_id INT NOT NULL COMMENT '顾客ID',
order_status VARCHAR(1) NOT NULL COMMENT '订单状态',
total_price DECIMAL(15, 2) NOT NULL COMMENT '订单金额',
order_date DATE NOT NULL COMMENT '订单日期',
PRIMARY KEY(order_id,order_date)
);
查询建表语句,可以看到主键order_id和order_date被采纳为分布键。
SHOW CREATE TABLE orders;+---------+-----------------------------------------------------------------------------------------------------------------------------------------------+
| Table | Create Table |
+---------+-----------------------------------------------------------------------------------------------------------------------------------------------+
| orders | CREATE TABLE `orders` ( |
| | `order_id` bigint NOT NULL COMMENT '订单ID', |
| | `customer_id` int NOT NULL COMMENT '顾客ID', |
| | `order_status` varchar(1) NOT NULL COMMENT '订单状态', |
| | `total_price` decimal(15, 2) NOT NULL COMMENT '订单金额', |
| | `order_date` date NOT NULL COMMENT '订单日期', |
| | PRIMARY KEY (`order_id`,`order_date`) |
| | ) DISTRIBUTED BY HASH(`order_id`,`order_date`) INDEX_ALL='Y' STORAGE_POLICY='HOT' ENGINE='XUANWU' TABLE_PROPERTIES='{"format":"columnstore"}' |
+---------+-----------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.04 sec)
未定义主键和分布键,系统自动增加主键和分布键
表未定义主键,也未定义分布键,AnalyticDB for MySQL将添加一个列__adb_auto_id__作为主键和分布键。
CREATE TABLE orders_new (
order_id BIGINT NOT NULL COMMENT '订单ID',
customer_id INT NOT NULL COMMENT '顾客ID',
order_status VARCHAR(1) NOT NULL COMMENT '订单状态',
total_price DECIMAL(15, 2) NOT NULL COMMENT '订单金额',
order_date DATE NOT NULL COMMENT '订单日期'
);
查询建表语句,可以看到表中自动增加一个自增列__adb_auto_id__,该自增列作为表的主键和分布键。
SHOW CREATE TABLE orders_new;+-------------+-----------------------------------------------------------------------------------------------------------------------------------------------+
| Table | Create Table |
+-------------+-----------------------------------------------------------------------------------------------------------------------------------------------+
| orders_new | CREATE TABLE `orders_new` ( |
| | `__adb_auto_id__` bigint AUTO_INCREMENT, |
| | `order_id` bigint NOT NULL COMMENT '订单ID', |
| | `customer_id` int NOT NULL COMMENT '顾客ID', |
| | `order_status` varchar(1) NOT NULL COMMENT '订单状态', |
| | `total_price` decimal(15, 2) NOT NULL COMMENT '订单金额', |
| | `order_date` date NOT NULL COMMENT '订单日期', |
| | PRIMARY KEY (`__adb_auto_id__`) |
| | ) DISTRIBUTED BY HASH(`__adb_auto_id__`) INDEX_ALL='Y' STORAGE_POLICY='HOT' ENGINE='XUANWU' TABLE_PROPERTIES='{"format":"columnstore"}' |
+-------------+-----------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.04 sec)
定义主键和分布键,但未定义分区键
新建表supplier,supplier_id为自增列,分布键为supplier_id,按照supplier_id值进行HASH分片。
CREATE TABLE supplier (
supplier_id BIGINT AUTO_INCREMENT PRIMARY KEY,
supplier_name VARCHAR,
address INT,
phone VARCHAR
)
DISTRIBUTED BY HASH(supplier_id);
对部分列创建普通索引
仅对id列和date列创建普通索引,其他列不创建索引。
CREATE TABLE index_tb (
id INT,
sales DECIMAL(15, 2),
date DATE,
INDEX (id),
INDEX (date),
PRIMARY KEY (id)
)
DISTRIBUTED BY HASH(id);
定义全文索引
为content列创建全文索引,索引名称为fidx_c。
CREATE TABLE fulltext_tb (
id INT,
content VARCHAR,
keyword VARCHAR,
FULLTEXT INDEX fidx_c(content),
PRIMARY KEY (id)
)
DISTRIBUTED BY HASH(id);
关于创建和变更全文索引的更多内容,请参见创建全文索引。
关于全文检索,请参见全文检索。
定义向量索引
定义short_feature、float_feature为向量列,类型是array<float>,向量维数为4。
根据short_feature创建向量索引short_feature_index,根据float_feature创建向量索引float_feature_index。
CREATE TABLE fact_tb (
xid BIGINT NOT NULL,
cid BIGINT NOT NULL,
uid VARCHAR NOT NULL,
vid VARCHAR NOT NULL,
wid VARCHAR NOT NULL,
short_feature array<smallint>(4),
float_feature array<float>(4),
ann index short_feature_index(short_feature),
ann index float_feature_index(float_feature),
PRIMARY KEY (xid, cid, vid)
)
DISTRIBUTED BY HASH(xid) PARTITION BY VALUE(cid) LIFECYCLE 4;
更多关于向量索引和向量检索的内容,请参见向量检索。
定义外键索引
新增一个名为store_returns的表,通过使用外键语法FOREIGN KEY将sr_item_sk列和customer表的主键列customer_id关联起来。
CREATE TABLE store_returns (
sr_sale_id BIGINT NOT NULL PRIMARY KEY,
sr_store_sk BIGINT,
sr_item_sk BIGINT NOT NULL,
FOREIGN KEY (sr_item_sk) REFERENCES customer (customer_id)
);
定义JSON Array索引
为vj列创建JSON Array索引,索引名称为idx_vj。
CREATE TABLE json(
id INT,
vj JSON,
INDEX idx_vj(vj->'$[*]')
)
DISTRIBUTED BY HASH(id);
关于创建和变更JSON Array索引的更多内容,请参见创建JSON Array索引和JSON Array索引。
常见问题
压缩与存储
列属性和列约束
分布键、分区键与生命周期
索引
列存
其他
常见报错
相关文档
-
向表中写入数据,请参见INSERT INTO。
-
将查询结果写入或覆盖写入,请参见INSERT SELECT FROM或INSERT OVERWRITE SELECT。
-
将RDS、MaxCompute、OSS或其他数据源的数据导入,请参见数据导入。