Todos os produtos
Search
Central de documentação

Hologres:CREATE TABLE

Última atualização: Jun 28, 2026

Use CREATE TABLE para definir o layout de armazenamento de uma tabela no Hologres. Configurar corretamente o modo de armazenamento, a chave de distribuição e os índices durante a criação é fundamental, pois a maioria dessas propriedades não pode ser alterada posteriormente.

Pré-requisitos

Antes de começar, verifique se você tem:

Início rápido

Este exemplo cria uma tabela de detalhes de transações com a sintaxe CREATE TABLE WITH (disponível no Hologres V2.1 e posterior). O exemplo adota uma convenção de nomenclatura hierárquica, define vários campos e inclui comentários de metadados.

BEGIN;

-- Create a transaction details fact table.
-- Use the public schema and follow the hierarchical naming convention (dwd_xxx).
CREATE TABLE IF NOT EXISTS public.dwd_trade_orders (
    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,              -- 0: Unpaid, 1: Alipay, 2: WeChat Pay, 3: Credit Card
    is_delivered  BOOLEAN DEFAULT false,
    dt            TEXT NOT NULL,              -- Data timestamp, in YYYYMMDD format
    order_time    TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
    PRIMARY KEY (order_id)
)
WITH (
    orientation                  = 'column',              -- Column-oriented: best for OLAP aggregation on large datasets
    distribution_key             = 'order_id',            -- Shard data by order_id for even distribution
    clustering_key               = 'order_time:asc',      -- Sort data by time within files to accelerate range queries
    event_time_column            = 'order_time',          -- Enable file-level clipping for time range filters
    bitmap_columns               = 'shop_id,payment_type,is_delivered', -- Accelerate equality filters on low-cardinality columns
    dictionary_encoding_columns  = 'user_id:auto'         -- Accelerate GROUP BY and FILTER on string columns
);

-- Add metadata comments.
COMMENT ON TABLE  public.dwd_trade_orders           IS 'Base fact table for transaction order details.';
COMMENT ON COLUMN public.dwd_trade_orders.order_id  IS 'The unique identifier of the order.';
COMMENT ON COLUMN public.dwd_trade_orders.shop_id   IS 'The unique ID of the shop.';
COMMENT ON COLUMN public.dwd_trade_orders.user_id   IS 'The ID of the buyer.';
COMMENT ON COLUMN public.dwd_trade_orders.dt        IS 'The data timestamp, in YYYYMMDD format.';
COMMENT ON COLUMN public.dwd_trade_orders.order_time IS 'The precise timestamp when the order was created.';

COMMIT;

Visualize o esquema da tabela

Execute a consulta a seguir para obter a instrução DDL (Data Definition Language) da tabela:

SELECT hg_dump_script('public.dwd_trade_orders');

Insira dados

O Hologres é compatível com a sintaxe padrão DML (Data Manipulation Language). A instrução abaixo insere 10 linhas de dados de exemplo:

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');

Consulte dados

-- Calculate the total transaction amount per shop, sorted in descending order.
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;

Saída esperada:

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

Sintaxe

Sintaxe do CREATE TABLE

O Hologres oferece suporte a duas sintaxes para definir propriedades e comentários de tabela:

Sintaxe padrão (recomendada para Hologres V2.1 e posterior)

Use a palavra-chave WITH para definir propriedades diretamente na instrução. Esta sintaxe é mais compacta e oferece melhor desempenho.

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;

Sintaxe compatível (suportada em todas as versões)

Use CALL set_table_property para configurar propriedades e COMMENT para adicionar comentários. Todas as instruções devem estar no mesmo bloco de transação BEGIN...COMMIT do CREATE TABLE.

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;

Propriedades da tabela

As propriedades dividem-se em três grupos conforme sua função. As propriedades marcadas como não modificáveis não podem ser alteradas após a criação da tabela — nesse caso, recrie a tabela.

Organização de dados (não modificável após a criação)

Propriedade

Descrição

Orientada a colunas

Orientada a linhas

Híbrida (linha-coluna)

Padrão

orientation

Define o formato de armazenamento. Consulte Modos de armazenamento.

column

row

row,column

column

distribution_key

Define a política de fragmentação de dados. Consulte Chave de distribuição.

Chave primária por padrão; escolha uma coluna da chave primária para obter o melhor desempenho.

Chave primária por padrão.

Chave primária por padrão.

Chave primária

clustering_key

Ordena fisicamente os dados nos arquivos para acelerar consultas de intervalo. Consulte Chave de clusterização.

Vazio por padrão. Use no máximo uma coluna; apenas a ordem crescente é suportada.

Chave primária por padrão.

Vazio por padrão.

event_time_column

Segmenta os dados em arquivos por tempo, permitindo filtragem rápida por intervalo temporal. Consulte Coluna de tempo de evento.

Primeiro campo de timestamp não nulo por padrão.

Não suportado.

Primeiro campo de timestamp não nulo por padrão.

Primeiro timestamp não nulo

table_group

Controla a contagem de shards para distribuição de dados. Consulte Grupos de tabelas e contagem de shards.

Grupo de tabelas padrão.

Grupo de tabelas padrão.

Grupo de tabelas padrão.

Grupo de tabelas padrão

Importante

As propriedades orientation, distribution_key, clustering_key e event_time_column não podem ser modificadas após a criação da tabela. Planeje-as cuidadosamente antes de criar a tabela. A propriedade table_group também não pode ser alterada sem recriar a tabela ou executar um novo particionamento (resharding).

Aceleração por índice (modificável após a criação)

Propriedade

Descrição

Orientada a colunas

Orientada a linhas

Híbrida (linha-coluna)

bitmap_columns

Cria um índice bitmap para filtragem rápida por igualdade em colunas de baixa cardinalidade. Consulte Índice bitmap. Use em colunas de comparações de igualdade; evite configurar mais de 10 colunas.

Suportado

Não suportado

Suportado

dictionary_encoding_columns

Cria um mapeamento de dicionário que converte comparações de strings em comparações numéricas, acelerando operações de GROUP BY e FILTER. Todas as colunas TEXT em tabelas orientadas a colunas são habilitadas por padrão. A partir da versão V0.9, o Hologres determina automaticamente se deve aplicar a codificação de dicionário com base nas características dos dados.

Suportado

Não suportado

Suportado

Tanto bitmap_columns quanto dictionary_encoding_columns podem ser modificados após a criação da tabela por meio do comando ALTER TABLE.

Sintaxe de dictionary_encoding_columns:

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

Ciclo de vida dos dados

Propriedade

Descrição

Orientada a colunas

Orientada a linhas

Híbrida (linha-coluna)

time_to_live_in_seconds

Define o TTL (Time to Live) dos dados da tabela em segundos. O TTL conta a partir do momento da escrita, não da atualização. Nas versões V1.3.24 e posteriores, o valor mínimo permitido é 86.400 (um dia).

Suportado

Não recomendado — use o valor padrão

Não recomendado

storage_mode

Especifica se os dados ficam em armazenamento quente ou frio. Suportado na versão V1.3 e posteriores. Consulte Armazenamento de dados em camadas.

Use conforme necessário

Use conforme necessário

Observações sobre time_to_live_in_seconds:

  • O TTL não é aplicado em um horário exato. Após a expiração, os dados são excluídos dentro de uma janela de tempo, e não em um momento preciso.

  • Apenas os dados são excluídos; a tabela permanece intacta.

  • O uso de TTL pode causar chaves primárias duplicadas ou resultados de consulta inconsistentes após a exclusão.

  • Para gerenciar o ciclo de vida de dados em produção, prefira tabelas particionadas. Consulte CREATE PARTITION TABLE.

  • A partir do Hologres V4.2, para tabelas com chave primária, a configuração de TTL é restringida pelo parâmetro GUC hg_time_to_live_in_days_min_value. Este parâmetro é medido em dias, tem valor padrão de 36500 (100 anos) e só pode ser modificado por um Superusuário. Ao definir o TTL de uma tabela com chave primária via CREATE TABLE, ALTER TABLE, SET_TABLE_PROPERTY ou REBUILD, o sistema verifica se o valor atende ao requisito mínimo (deve ser maior ou igual ao número de dias correspondente a hg_time_to_live_in_days_min_value). Tabelas sem chave primária não sofrem essa restrição.

Se não definido, o TTL padrão é de 100 anos (efetivamente sem expiração).

Sintaxe de time_to_live_in_seconds:

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

Sintaxe de storage_mode:

-- Set storage mode at table creation:
CREATE TABLE <table_name> (...) WITH (storage_mode = 'hot');
CREATE TABLE <table_name> (...) WITH (storage_mode = 'cold');

-- Set storage mode after table creation:
CALL set_table_property('table_name', 'storage_mode', 'hot');
CALL set_table_property('table_name', 'storage_mode', 'cold');

Exemplos

Exemplo: Tabela particionada para dados de séries temporais em grande escala

À medida que o volume de dados cresce, manter uma única tabela plana torna-se custoso — limpar dados históricos exige varrer todas as linhas, e consultas baseadas em tempo realizam varreduras completas na tabela. Uma tabela particionada isola fisicamente os dados por dia, permitindo remover partições instantaneamente para limpeza e aplicar poda automática de partições durante as consultas.

Este exemplo atualiza a tabela dwd_trade_orders da seção Início rápido para uma estrutura particionada. As definições de campos e configurações de índice são herdadas, mas a chave primária deve incluir a chave de partição dt.

BEGIN;

-- Create the partitioned parent table.
-- The primary key includes both the business key (order_id) and the partition 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;

-- Create a child table to provide physical storage for a specific date.
CREATE TABLE IF NOT EXISTS public.dwd_trade_orders_20231101
    PARTITION OF public.dwd_trade_orders_partitioned FOR VALUES IN ('20231101');

-- Insert data. The application logic is identical to the flat table.
-- Data is automatically routed to the correct child table.
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');

-- Query with a partition filter. Hologres scans only the matching child table.
SELECT COUNT(*) FROM public.dwd_trade_orders_partitioned WHERE dt = '20231101';

-- Drop a child table to reclaim space in seconds (much faster than DELETE).
-- DROP TABLE public.dwd_trade_orders_20231101;

Exemplo: Análises em tempo real para grandes conjuntos de dados (tabela de fatos)

Cenário: Resumos de painéis em tempo real com grandes volumes de dados, cujo requisito principal é a agregação rápida — por exemplo, calcular o Volume Bruto de Mercadorias (GMV) e a contagem de pedidos.

O armazenamento orientado a colunas é ideal para este caso: altas taxas de compressão reduzem a E/S, e as varreduras de colunas leem apenas as colunas necessárias para a agregação.

BEGIN;

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',           -- Best for large-scale aggregation; high compression, efficient column scans
    distribution_key  = 'order_id',         -- Even distribution; enables local joins with other order tables
    event_time_column = 'order_time',       -- Enables file-level segment clipping for time range filters
    clustering_key    = 'order_time:asc'    -- Reduces disk I/O for "last hour" or "specific day" queries
);

COMMENT ON TABLE  public.dwd_order_summary            IS 'Fact table for order summary details.';
COMMENT ON COLUMN public.dwd_order_summary.order_id   IS 'The unique order ID.';
COMMENT ON COLUMN public.dwd_order_summary.category_id IS 'The category ID.';
COMMENT ON COLUMN public.dwd_order_summary.gmv        IS 'The gross merchandise volume.';
COMMENT ON COLUMN public.dwd_order_summary.order_time IS 'The time when the order was placed.';

COMMIT;

Exemplo: Consultas pontuais de alta concorrência (tabela de dimensões)

Cenário: Recuperar o perfil de um usuário por user_id em milissegundos, sob alta taxa de consultas por segundo (QPS).

O armazenamento orientado a linhas é otimizado para buscas baseadas em chave primária. Todos os dados da linha ficam armazenados de forma contígua, tornando as consultas pontuais extremamente rápidas, sem necessidade de varrer colunas irrelevantes.

BEGIN;

CREATE TABLE IF NOT EXISTS public.dim_user_persona (
    user_id       TEXT PRIMARY KEY,
    user_level    INT,
    persona_jsonb JSONB
) WITH (
    orientation = 'row'
    -- For row-oriented tables, the primary key is automatically used as the distribution key
    -- and clustering key. No additional settings are required.
);

COMMENT ON TABLE  public.dim_user_persona              IS 'Dimension table for user profiles.';
COMMENT ON COLUMN public.dim_user_persona.user_id      IS 'The unique user ID.';
COMMENT ON COLUMN public.dim_user_persona.user_level   IS 'The user level.';
COMMENT ON COLUMN public.dim_user_persona.persona_jsonb IS 'The user profile features in JSON format.';

COMMIT;

Exemplo: Carga de trabalho híbrida (armazenamento híbrido linha-coluna)

Cenário: Sistema de logística e pós-venda que necessita tanto de análises (resumo de status logísticos) quanto de consultas pontuais (recuperação de detalhes de pedidos por order_id).

O armazenamento híbrido linha-coluna combina o desempenho de consultas pontuais em nível de milissegundos do armazenamento orientado a linhas com a eficiência de agregação do armazenamento orientado a colunas.

BEGIN;

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',      -- Supports both point queries and aggregation
    distribution_key = 'order_id',        -- Controls data distribution across shards
    bitmap_columns   = 'shipping_status'  -- Accelerates "status = X" filter queries on a low-cardinality column
);

COMMENT ON TABLE  public.ads_shipping_info                  IS 'Application table for logistics status queries.';
COMMENT ON COLUMN public.ads_shipping_info.order_id         IS 'The order ID.';
COMMENT ON COLUMN public.ads_shipping_info.shipping_status  IS 'Logistics status (1: To be shipped, 2: In transit, 3: Delivered).';
COMMENT ON COLUMN public.ads_shipping_info.receiver_address IS 'The shipping address.';

COMMIT;

Limitações

O Hologres suporta no máximo 6.400 colunas por tabela.

Limites de chave primária

  • Composite primary keys: Vários campos podem formar a chave primária. Todos os campos devem ser NOT NULL e declarados em uma única instrução.

    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;
  • Tipos não suportados: FLOAT, DOUBLE, NUMERIC, ARRAY, JSON, DATE e outros tipos complexos não podem ser usados como colunas de chave primária.

  • Não modificável: A chave primária não pode ser alterada após a criação da tabela. Recrie a tabela caso precise de uma chave primária diferente.

  • Requisitos de armazenamento: Tabelas orientadas a linhas e híbridas (linha-coluna) devem ter uma chave primária. Para tabelas orientadas a colunas, a chave primária é opcional.

Suporte a restrições

Restrição

Nível de coluna

Nível de tabela

primary key

Suportado

Suportado

not null

Suportado

null

Suportado

unique

Não suportado

Não suportado

check

Não suportado

Não suportado

default

Suportado

Não suportado

Regras de nomenclatura e escape

  • Nomes de colunas não podem começar com hg_.

  • Nomes de esquemas não podem começar com holo_, hg_ ou pg_.

  • Nomes de tabelas não podem exceder 127 bytes.

  • Coloque nomes entre aspas duplas ("") quando forem palavras-chave SQL, palavras reservadas, campos do sistema (como ctid), identificadores sensíveis a maiúsculas e minúsculas, nomes com caracteres especiais ou nomes iniciados por dígito.

Sintaxe para nomes de colunas com escape no Hologres V2.0 e posterior:

-- Single escaped column
BEGIN;
CREATE TABLE tbl (c1 INT NOT NULL);
CALL set_table_property('tbl', 'clustering_key', '"c1":asc');
COMMIT;

-- Multiple columns, including an uppercase one (V2.1 and later)
BEGIN;
CREATE TABLE tbl ("C1" INT NOT NULL, c2 TEXT NOT NULL) WITH (clustering_key = '"C1",c2');
COMMIT;

-- Multiple columns, including an uppercase one (V2.0 and later)
BEGIN;
CREATE TABLE tbl ("C1" INT NOT NULL, c2 TEXT NOT NULL);
CALL set_table_property('tbl', 'clustering_key', '"C1",c2');
COMMIT;

Sintaxe para nomes de colunas com escape em versões anteriores ao Hologres V2.0:

BEGIN;
CREATE TABLE tbl (c1 INT NOT NULL);
CALL set_table_property('tbl', 'clustering_key', '"c1:asc"');
COMMIT;

-- Multiple columns, including an uppercase one
BEGIN;
CREATE TABLE tbl ("C1" INT NOT NULL, c2 TEXT NOT NULL);
CALL set_table_property('tbl', 'clustering_key', '"C1,c2"');
COMMIT;

Para alternar para a sintaxe antiga do analisador no Hologres V2.0 quando necessário:

-- Enable the old syntax at the session level.
SET hg_disable_parse_holo_property = on;

-- Enable the old syntax at the database level.
ALTER DATABASE <db_name> SET hg_disable_parse_holo_property = on;

Comportamento do IF NOT EXISTS

Condição

**IF NOT EXISTS especificado**

**IF NOT EXISTS não especificado**

Existe uma tabela com o mesmo nome

Retorna um NOTICE, ignora a criação, operação bem-sucedida

Retorna um ERROR

Não existe tabela com o mesmo nome

Operação bem-sucedida

Operação bem-sucedida

Limites de modificação

Após a criação da tabela, os seguintes itens não podem ser alterados:

  • Tipos de dados (antes do Hologres V3.0)

  • Ordem das colunas

  • Restrição de nulidade (NOT NULL ↔ anulável)

  • Propriedades de layout de armazenamento: orientation, distribution_key, clustering_key, event_time_column

Os seguintes itens podem ser alterados após a criação da tabela:

  • bitmap_columns e dictionary_encoding_columns — via ALTER TABLE

  • Tipos de dados: alguns tipos na versão V3.0 e posterior; todos os tipos via REBUILD na versão V3.1 e posterior — consulte Modificar tipos de dados e REBUILD

Próximos passos