CREATE TABLE

更新时间:
复制为 MD 格式

表是 Hologres 存储和组织数据的基本单位。通过合理地设置存储模式、表索引及属性,可以为您提供高效的实时数据处理和大规模分析能力。

快速上手

准备工作

建表

推荐使用 V2.1 版本起支持的 CREATE TABLE WITH 语法。此示例演示一张遵循分层命名规范、字段丰富且包含完善注释的交易明细表

BEGIN;

-- 创建交易明细事实表(基础普通表)
-- 显式指定 public schema,并在表名上体现分层规范 (dwd_xxx)
CREATE TABLE IF NOT EXISTS public.dwd_trade_orders (
    order_id BIGINT NOT NULL,           -- 订单唯一标识
    shop_id INT NOT NULL,              -- 店铺ID
    user_id TEXT NOT NULL,             -- 用户ID
    order_amount NUMERIC(12, 2) DEFAULT 0.00,       -- 订单金额
    payment NUMERIC(12, 2) DEFAULT 0.00,         -- 实付金额
    payment_type INT DEFAULT 0,                     -- 支付类型(0:未支付, 1:支付宝, 2:微信, 3:信用卡)
    is_delivered BOOLEAN DEFAULT false,             -- 是否发货
    dt TEXT NOT NULL,                               -- 业务日期
    order_time TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP, -- 下单时间
    PRIMARY KEY (order_id)                          -- 设置主键,保证数据唯一性
)
WITH (
    orientation = 'column',                         -- 设置为列存模式:适用于海量数据的实时分析(OLAP)场景
    distribution_key = 'order_id',                  -- 设置分布键:数据按 order_id 分片存储
    clustering_key = 'order_time:asc',              -- 设置聚簇索引:数据在文件内按时间升序排列
    event_time_column = 'order_time',               -- 设置分段键:利用文件级裁剪快速过滤时间区间
    bitmap_columns = 'shop_id,payment_type,is_delivered', -- 设置位图索引:针对低基数列加速等值过滤
    dictionary_encoding_columns = 'user_id:auto'    -- 设置字典编码:加速字符串列的聚合与过滤
);

-- 添加元数据注释
COMMENT ON TABLE public.dwd_trade_orders IS '交易订单明细基础事实表';
COMMENT ON COLUMN public.dwd_trade_orders.order_id IS '订单唯一标识';
COMMENT ON COLUMN public.dwd_trade_orders.shop_id IS '店铺唯一ID';
COMMENT ON COLUMN public.dwd_trade_orders.user_id IS '购买者用户ID';
COMMENT ON COLUMN public.dwd_trade_orders.dt IS '业务日期, 格式 YYYYMMDD';
COMMENT ON COLUMN public.dwd_trade_orders.order_time IS '订单创建精确时间戳';

COMMIT;

查询表结构

您可以执行如下命令查看TABLE的具体DDL:

SELECT hg_dump_script('public.dwd_trade_orders');

插入数据

Hologres 兼容标准 DML 语法。以下插入 10 条模拟生产环境的明细数据。

INSERT INTO public.dwd_trade_orders (order_id, shop_id, user_id, order_amount, payment, payment_type, is_delivered, dt, order_time) VALUES 
(50001, 101, 'U678', 299.00, 280.00, 1, true,  '20231101', '2023-11-01 10:00:01+08'),
(50002, 102, 'U992', 59.00,  59.00,  2, false, '20231101', '2023-11-01 10:05:12+08'),
(50003, 101, 'U441', 150.00, 145.00, 1, true,  '20231101', '2023-11-01 10:10:45+08'),
(50004, 105, 'U219', 888.00, 888.00, 3, true,  '20231101', '2023-11-01 10:20:11+08'),
(50005, 102, 'U883', 35.00,  30.00,  1, false, '20231101', '2023-11-01 10:32:00+08'),
(50006, 110, 'U007', 120.50, 120.50, 2, true,  '20231101', '2023-11-01 10:45:33+08'),
(50007, 101, 'U321', 210.00, 210.00, 1, true,  '20231101', '2023-11-01 11:02:19+08'),
(50008, 108, 'U556', 45.00,  45.00,  2, false, '20231101', '2023-11-01 11:15:04+08'),
(50009, 101, 'U112', 300.00, 290.00, 3, true,  '20231101', '2023-11-01 11:25:55+08'),
(50010, 105, 'U449', 99.90,  99.90,  1, true,  '20231101', '2023-11-01 11:40:22+08');

查询数据

-- 统计各店铺成交额并按金额降序排列
SELECT 
    shop_id, 
    COUNT(1) as total_orders, 
    SUM(payment) as total_payment 
FROM public.dwd_trade_orders 
GROUP BY shop_id 
ORDER BY total_payment DESC;

查询结果:

shop_id	total_orders	total_payment
105	2	987.90
101	4	925.00
110	1	120.50
102	1	59.00
108	1	45.00

语法说明

建表语法说明

Hologres 提供两种设置表属性及添加注释的语法:

  • 标准语法(推荐 V2.1+ 使用)

    使用 WITH 关键字定义属性,结构紧凑且性能更佳,注释语句通常紧随建表语句,完整示例请参见建表

    BEGIN;
    
    CREATE TABLE [ IF NOT EXISTS] [schema_name.]table_name ([
        { 
        column_name column_type [column_constraints, [...]]
        | table_constraints
        [,...]
        }
    ])
    [WITH (
        property = 'value',
        [, ...]
    )]
    ;
    [COMMENT ON COLUMN <[schema_name.]tablename.column> IS '<value>';]
    [COMMENT ON TABLE <[schema_name.]tablename> IS '<value>';]
    
    COMMIT;
  • 兼容语法(全版本支持)

    通过 CALL 方式set_table_property设置属性和COMMENT注释,必须与 CREATE TABLE 处于同一个事务块(BEGIN...COMMIT)中。

    BEGIN;
    
    CREATE TABLE [ IF NOT EXISTS] [schema_name.]table_name ([
        { 
        column_name column_type [column_constraints, [...]]
        | table_constraints
        [,...]
        }
    ]);
    
    CALL set_table_property('[schema_name.]<table_name>', '<property>', '<value>');
    COMMENT ON COLUMN <[schema_name.]tablename.column> IS '<value>';
    COMMENT ON TABLE <[schema_name.]tablename> IS '<value>';
    
    COMMIT;

表属性

参数

说明

列存表

行存表

行列共存表

建议值

建表后是否可修改

orientation

设置表存储格式。详情参见表存储格式:列存、行存、行列共存

column(默认值)

参考示例:海量数据实时分析场景(事实表)

row

参考示例:高并发主键点查场景(维表)

row,column

参考示例:混合负载场景(行列共存)

column

否,如需修改请重新建表。

distribution_key

分布键,设置表数据的分布策略。详情参见分布键Distribution Key

默认为主键,根据业务场景修改。

默认为主键。

默认为主键。

主键的子集,建议只选择一列。

clustering_key

聚簇索引,用于提升查询性能,详情参见聚簇索引Clustering Key

默认为空。

默认为主键。

默认为空。

建议最多选择一列,且仅支持asc序。

event_time_column

分段键,用于提升查询性能,详情参见Event Time Column(Segment Key)

默认为第一个非空时间戳字段。

不支持。

默认为第一个非空时间戳字段。

建议时间戳字段。

table_group

逻辑存储概念,用于管理Shard数。详情参见Table GroupShard Count操作指南

默认为default table group

默认即可。

否,如需修改请重新建表或者Resharding。

bitmap_columns

位图索引。详情参见位图索引Bitmap

按需使用。

不支持。

按需使用。

建议用于等值比较的列,一般10列以下。

是,详情请参见ALTER TABLE

dictionary_encoding_columns

字典编码。

按需使用。

不支持。

按需使用。

建议低基数列,一般10列以下。

是,详情请参见ALTER TABLE

time_to_live_in_seconds

设置表的数据生命周期,单位为秒。TTL并非精确时间,生产业务中不建议使用TTL来管理数据的生命周期,建议采用分区表,具体详情请参见CREATE PARTITION TABLE

按需使用。

默认即可,无需设置。

是,详情请参见ALTER TABLE

dictionary_encoding_columns

设置字典编码Dictionary Encoding,命令语法如下所示。Dictionary Encoding指定列的值构建字典映射。字典编码可以将字符串的比较转成数字的比较,加速Group By、Filter等查询。默认列存表所有TEXT数据类型的字段都会被设置为Dictionary Encoding列 ,在Hologres V0.9及之后版本,会根据数据特征自动选择是否创建字典编码。

CALL set_table_property('table_name', 'dictionary_encoding_columns', '[columnName{:[on|off|auto]}[,...]]');

time_to_live_in_seconds

设置表的数据生命周期(TTL),单位为秒,命令语法如下所示。

  • TTL过期时间是按照数据写入的时间开始计算,不是按照数据更新时间计算。不设置TTL的时候,默认为100年,Hologres从 V1.3.24版本开始,TTL允许的最小值是一天,即86400秒。TTL的详细使用说明请参见SQL命令列表

  • TTL不是精确的时间,即到期后数据会在某一段时间(不是固定时间)删除(只删除数据,表还会存在),因此可能会出现PK重复或者查询结果不一致等问题。

CALL set_table_property('table_name', 'time_to_live_in_seconds', '<non_negative_literal>');

场景示例

示例:基于业务日期的分区表

场景描述:随着业务增长,日增订单量可能达到千万甚至亿级。此时,若继续使用快速上手中的单表结构(dwd_trade_orders),在大规模数据删除(如清理历史数据)或针对特定日期查询时,系统负载会较高。本示例将普通表升级为分区表。它继承了基础表的所有字段定义和索引设置,但通过 PARTITION BY 将数据按天物理隔离。这不仅支持通过 DROP TABLE 秒级清理过期分区,还能在查询时实现精准的“分区裁剪”,是生产环境管理超大规模实时数据的推荐方案。

BEGIN;

-- 升级版:创建分区表父表
-- 结构完全继承自快速上手示例,但 Primary Key 必须包含分区键 dt
CREATE TABLE IF NOT EXISTS public.dwd_trade_orders_partitioned (
    order_id BIGINT NOT NULL,
    shop_id INT NOT NULL,
    user_id TEXT NOT NULL,
    order_amount NUMERIC(12, 2) DEFAULT 0.00,
    payment NUMERIC(12, 2) DEFAULT 0.00,
    payment_type INT DEFAULT 0,
    is_delivered BOOLEAN DEFAULT false,
    dt TEXT NOT NULL,                               -- 分区键
    order_time TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
    PRIMARY KEY (order_id, dt)                      -- 复合主键:包含业务主键和分区键
) 
PARTITION BY LIST (dt)                              -- 开启列表分区
WITH (
    orientation = 'column',
    distribution_key = 'order_id',
    event_time_column = 'order_time',
    clustering_key = 'order_time:asc'
);

COMMIT;

-- 1. 创建子表:为特定日期创建物理存储空间
CREATE TABLE IF NOT EXISTS public.dwd_trade_orders_20231101 
PARTITION OF public.dwd_trade_orders_partitioned FOR VALUES IN ('20231101');

-- 2. 写入数据:应用端逻辑与基础表一致,数据会自动路由至 20231101 子表
INSERT INTO public.dwd_trade_orders_partitioned (order_id, shop_id, user_id, order_amount, payment, payment_type, is_delivered, dt, order_time) VALUES 
(50001, 101, 'U678', 299.00, 280.00, 1, true,  '20231101', '2023-11-01 10:00:01+08'),
(50002, 102, 'U992', 59.00,  59.00,  2, false, '20231101', '2023-11-01 10:05:12+08'),
(50003, 101, 'U441', 150.00, 145.00, 1, true,  '20231101', '2023-11-01 10:10:45+08'),
(50004, 105, 'U219', 888.00, 888.00, 3, true,  '20231101', '2023-11-01 10:20:11+08'),
(50005, 102, 'U883', 35.00,  30.00,  1, false, '20231101', '2023-11-01 10:32:00+08'),
(50006, 110, 'U007', 120.50, 120.50, 2, true,  '20231101', '2023-11-01 10:45:33+08'),
(50007, 101, 'U321', 210.00, 210.00, 1, true,  '20231101', '2023-11-01 11:02:19+08'),
(50008, 108, 'U556', 45.00,  45.00,  2, false, '20231101', '2023-11-01 11:15:04+08'),
(50009, 101, 'U112', 300.00, 290.00, 3, true,  '20231101', '2023-11-01 11:25:55+08'),
(50010, 105, 'U449', 99.90,  99.90,  1, true,  '20231101', '2023-11-01 11:40:22+08');

-- 3. 分区裁剪:查询时指定 dt 条件,系统仅扫描相关子表,避免全表扫描
SELECT COUNT(*) FROM public.dwd_trade_orders_partitioned WHERE dt = '20231101';

-- 4. 快速清理:删除过期数据时,直接 DROP 子表,秒级回收空间
-- DROP TABLE public.dwd_trade_orders_20231101; 

示例:海量数据实时分析场景(事实表)

场景描述:用于实时大盘汇总。此类表通常数据量极大,核心需求是统计聚合性能(如计算 GMV、订单量)。

BEGIN;

-- 显式指定 public schema
CREATE TABLE IF NOT EXISTS public.dwd_order_summary (
    order_id BIGINT PRIMARY KEY,
    category_id INT NOT NULL,
    gmv NUMERIC(15, 2),
    order_time TIMESTAMPTZ NOT NULL
) WITH (
    orientation = 'column',             -- 存储模式:列存。海量聚合分析的首选,提供高压缩比和高效的列扫描
    distribution_key = 'order_id',      -- 分布键:按 order_id 分片,确保数据均匀分布;关联其他订单表时可实现 Local Join
    event_time_column = 'order_time',   -- 分段键:通常设为时间字段。系统会按此字段划分文件段,加速按时间范围的过滤
    clustering_key = 'order_time:asc'   -- 聚簇索引:物理上按时间升序排列。在查询“最近1小时”或“某天”的数据时,减少磁盘 I/O
);

-- 添加元数据注释,便于后续数据治理
COMMENT ON TABLE public.dwd_order_summary IS '订单汇总明细事实表';
COMMENT ON COLUMN public.dwd_order_summary.order_id IS '唯一订单ID';
COMMENT ON COLUMN public.dwd_order_summary.category_id IS '品类ID';
COMMENT ON COLUMN public.dwd_order_summary.gmv IS '成交额';
COMMENT ON COLUMN public.dwd_order_summary.order_time IS '下单时间';

COMMIT;

示例:高并发主键点查场景(维表)

场景描述:根据 user_id 毫秒级回显用户画像。此类表侧重于高 QPS 下的极低延迟响应。

BEGIN;

-- 显式指定 public schema
CREATE TABLE IF NOT EXISTS public.dim_user_persona (
    user_id TEXT PRIMARY KEY,           -- 主键:点查场景的核心,必须设置
    user_level INT,
    persona_jsonb JSONB 
) WITH (
    orientation = 'row'                 -- 存储模式:行存。专门为基于主键的点查(Point Lookup)优化,响应速度可达毫秒级
    -- 说明:行存表会自动将主键设为分布键和聚簇索引,无需额外设置
);

-- 添加元数据注释
COMMENT ON TABLE public.dim_user_persona IS '用户画像维度表';
COMMENT ON COLUMN public.dim_user_persona.user_id IS '唯一用户ID';
COMMENT ON COLUMN public.dim_user_persona.user_level IS '用户等级';
COMMENT ON COLUMN public.dim_user_persona.persona_jsonb IS '用户特征画像JSON';

COMMIT;

示例:混合负载场景(行列共存)

场景描述:物流售后系统。既要对物流状态进行分析汇总(分析类),也要根据订单 ID 瞬间调取物流详情(点查类)。

BEGIN;

-- 显式指定 public schema
CREATE TABLE IF NOT EXISTS public.ads_shipping_info (
    order_id BIGINT PRIMARY KEY,
    shipping_status INT,
    receiver_address TEXT,
    update_time TIMESTAMPTZ
) WITH (
    orientation = 'row,column',         -- 存储模式:行列共存。同时拥有行存的毫秒级点查和列存的高效聚合分析能力
    distribution_key = 'order_id',      -- 分布键:决定数据在 Shard 间的分布逻辑
    bitmap_columns = 'shipping_status'  -- 位图索引:针对状态字段等低基数列设置,极大加速“状态过滤”类的查询
);

-- 添加元数据注释
COMMENT ON TABLE public.ads_shipping_info IS '物流状态查询应用表';
COMMENT ON COLUMN public.ads_shipping_info.order_id IS '订单ID';
COMMENT ON COLUMN public.ads_shipping_info.shipping_status IS '物流状态(1:待发货, 2:运输中, 3:已签收)';
COMMENT ON COLUMN public.ads_shipping_info.receiver_address IS '收货地址';

COMMIT;

使用限制

主键设置限制

  • 复合主键:支持将多个字段设置为Primary Key。必须为not nullable,且只能在一条语句中设置。

    BEGIN;
    CREATE TABLE public.test (
     "id" text NOT NULL,
     "ds" text NOT NULL,
    PRIMARY KEY (id,ds)
    );
    CALL SET_TABLE_PROPERTY('public.test', 'orientation', 'column');
    COMMIT;
  • 类型限制:不支持 Float、Double、Numeric、Array、Json、Date 等复杂类型。

  • 修改限制:不支持修改主键,需重构。

  • 存储依赖:行存表和行列共存表必须有主键,列存表可选。

约束支持情况

参数

column_constraints

table_constraints

primary key

支持

支持

not null

支持

-

null

支持

-

unique

不支持

不支持

check

不支持

不支持

default

支持

不支持

关键字、大小写与转义限制

  • 命名规范:列名不能以hg_开头;Schema不能以holo_hg_pg_开头。

  • 转义场景:关键字、保留字、系统字段(如ctid)、大小写敏感名称、特殊字符、数字开头名称必须加双引号("")。

  • V2.0版本语法优化:

    • 开关旧语法:

      -- session级别开启旧语法开关
      set hg_disable_parse_holo_property = on;
      -- DB级别开启旧语法开关
      alter database <db_name> set hg_disable_parse_holo_property = on;
    • 转义列设置属性的示例:

      create table "TBL" (a int);
      select relname from pg_class where relname = 'TBL';
      insert into "TBL" values (-1977);
      select * from "TBL";
      ------------------------------------------------------------------
      -- Hologres V2.0版本起,为需要转义的列设置表属性的语法
      begin;
      create table tbl (c1 int not null);
      call set_table_property('tbl', 'clustering_key', '"c1":asc'); 
      commit;
      -- Hologres V2.0版本前,为需要转义的列设置表属性的语法
      begin;
      create table tbl (c1 int not null);
      call set_table_property('tbl', 'clustering_key', '"c1:asc"'); 
      commit;
      ------------------------------------------------------------------
      -- Hologres V2.1版本起,为多列(包含大写)设置表属性的语法
      begin;
      create table tbl ("C1" int not null, c2 text not null) with (clustering_key = '"C1",c2');
      commit;
      -- Hologres V2.0版本起,为多列(包含大写)设置表属性的语法
      begin;
      create table tbl ("C1" int not null, c2 text not null);
      call set_table_property('tbl', 'clustering_key', '"C1",c2'); 
      commit;
      -- Hologres V2.0版本前,为多列(包含大写)设置表属性的语法
      begin;
      create table tbl ("C1" int not null, c2 text not null);
      call set_table_property('tbl', 'clustering_key', '"C1,c2"'); 
      commit;
      ------------------------------------------------------------------
      create table "Tab_$A%*" (a int);
      select relname from pg_class where relname = 'Tab_$A%*';
      insert into "Tab_$A%*" values (-1977);
      select * from "Tab_$A%*";
      ------------------------------------------------------------------
      create table tbl ("2c" int not null);
      insert into tbl values (3), (4);
      select "2c" from tbl;

建表逻辑限制

配置项

指定 IF NOT EXISTS

不指定 IF NOT EXISTS

存在同名表

提示 NOTICE 并跳过,返回成功

返回异常 ERROR

不存在同名表

返回成功

返回成功

修改限制

  • 长度限制:表名不能超过127字节。

  • 不支持修改的项目:

    • 不支持修改数据类型。

    • 不支持调整列顺序。

    • 不支持修改空值约束(not nullnullable互转)。

    • 存储布局属性:一经创建,orientationdistribution_keyclustering_keyevent_time_column 不支持更改。

  • 支持修改的项目:bitmap_columns 和 dictionary_encoding_columns 可以在建表后更改。