All Products
Search
Document Center

Hologres:Buat tabel dinamis

Last Updated:Jul 15, 2026

Buat Tabel Dinamis yang secara otomatis memperbarui hasil kueri dari tabel dasar menggunakan pembaruan bertahap atau pembaruan penuh.

Catatan penting

  • Batasan penggunaan Tabel Dinamis: Dukungan dan batasan Tabel Dinamis.

  • Hologres V3.1 dan versi lebih baru hanya mendukung sintaks baru untuk membuat Tabel Dinamis. Anda masih dapat melakukan operasi ALTER pada tabel yang dibuat dengan sintaks V3.0, tetapi tidak dapat membuat yang baru. Untuk tabel non-partisi, Anda dapat menggunakan perintah konversi sintaks untuk mengonversi sintaks lama ke sintaks baru. Untuk tabel partisi, buat ulang secara manual.

  • Peningkatan ke Hologres V3.1 dan versi lebih baru mengharuskan pembuatan ulang Tabel Dinamis Bertahap yang sudah ada. Anda dapat menggunakan perintah konversi sintaks untuk melakukannya.

  • Di Hologres V3.1+, mesin secara adaptif mengoptimalkan proses refresh. ID kueri negatif untuk operasi refresh adalah hal yang diharapkan.

Sintaks

V3.1+ (sintaks baru)

Catatan

V3.1+ hanya mendukung sintaks baru.

Sintaks Create Dynamic Table

Sintaks untuk membuat Tabel Dinamis di V3.1+:

CREATE DYNAMIC TABLE [ IF NOT EXISTS ] [<schema_name>.]<table_name>
[ (<col_name> [, ...] ) ]
[LOGICAL PARTITION BY LIST(<partition_key>)]
WITH (
  -- Properti Tabel Dinamis
  freshness = '<num> {minutes | hours}', -- Wajib
  [auto_refresh_enable = {true | false},] -- Opsional
  [auto_refresh_mode = {'full' | 'incremental' | 'auto'},] -- Opsional
  
  [base_table_cdc_format = {'stream' | 'binlog'},] -- Opsional

  [auto_refresh_partition_active_time = '<num> {minutes | hours | days}',] -- Opsional
  [partition_key_time_format = {'YYYYMMDDHH24' | 'YYYY-MM-DD-HH24' | 'YYYY-MM-DD_HH24' | 'YYYYMMDD' | 'YYYY-MM-DD' | 'YYYYMM' | 'YYYY-MM' | 'YYYY'},] --Opsional
  
  [computing_resource = {'local' | 'serverless' | '<warehouse_name>'},] -- Opsional. Nilai warehouse_name hanya didukung di Hologres V4.0.7 dan versi lebih baru.
  [refresh_guc_hg_experimental_serverless_computing_required_cores=xxx,] --Opsional. Menentukan jumlah core komputasi yang diperlukan untuk Serverless.
  
  [refresh_guc_<guc_name> = '<guc_value>',] -- Opsional

  -- Properti umum
  [orientation = {'column' | 'row' | 'row,column'},]
  [table_group = '<tableGroupName>',]
  [distribution_key = '<columnName>[,...]]',]
  [clustering_key = '<columnName>[:asc] [,...]',]
  [event_time_column = '<columnName> [,...]',]
  [bitmap_columns = '<columnName> [,...]',]
  [dictionary_encoding_columns = '<columnName> [,...]',]
  [time_to_live_in_seconds = '<non_negative_literal>',]
  [storage_mode = {'hot' | 'cold'},]
)
AS
<query>; -- Definisi kueri.

Parameter

Mode & sumber daya refresh

Parameter

Deskripsi

Wajib

Default

freshness

Tingkat kesegaran data target dalam menit atau jam. Minimum: 1 menit. Mesin menjadwalkan refresh berdasarkan waktu refresh sebelumnya dan nilai freshness ini. Berbeda dengan interval tetap, freshness menyesuaikan secara otomatis agar data tetap mutakhir.

Ya

Tidak ada

auto_refresh_mode

Mode refresh. Nilai yang valid:

  • auto: Mode otomatis. Mesin secara otomatis menggunakan pembaruan bertahap jika kueri mendukungnya; jika tidak, beralih ke pembaruan penuh.

  • incremental: Pembaruan bertahap. Hanya data inkremental yang diperbarui setiap kali. Untuk informasi selengkapnya, lihat Pembaruan bertahap.

  • full: Pembaruan penuh. Seluruh tabel diperbarui setiap kali. Untuk informasi selengkapnya, lihat Pembaruan penuh.

Tidak

auto

auto_refresh_enable

Mengaktifkan atau menonaktifkan refresh otomatis. Nilai yang valid:

  • true: Mengaktifkan refresh otomatis.

  • false: Menonaktifkan refresh otomatis. Semua pekerjaan refresh berikutnya untuk tabel dihentikan.

Tidak

true

base_table_cdc_format

Cara mengonsumsi perubahan data tabel dasar selama pembaruan bertahap.

  • stream (default): Membaca perubahan data tingkat file. Tidak ada overhead penyimpanan tambahan dan performa lebih tinggi daripada binlog. Untuk informasi selengkapnya, lihat Tabel dinamis.

  • binlog: Mengonsumsi perubahan data tabel dasar melalui binlog. Mengharuskan Anda mengaktifkan binlog secara manual pada tabel dasar (Berlangganan Hologres Binlog).

    begin;
    call set_table_property('<table_name>', 'binlog.level', 'replica');
    call set_table_property('<table_name>', 'binlog.ttl', '2592000');
    commit;
Catatan
  • Mulai V3.1, semua tabel default ke stream. Nonaktifkan binlog jika diaktifkan untuk menghindari biaya penyimpanan yang tidak perlu.

  • Metode stream tidak didukung untuk tabel dasar berorientasi baris; hanya metode binlog yang didukung.

  • Parameter ini tidak dapat dimodifikasi setelah tabel dibuat. Untuk mengubahnya, buat ulang tabel.

Tidak

stream

computing_resource

Sumber daya komputasi untuk refresh. Nilai yang valid:

  • serverless (default): Menggunakan sumber daya Komputasi Tanpa Server, mengisolasi beban kerja refresh dari trafik kueri.

  • <warehouse_name>: Menggunakan gudang komputasi tertentu untuk refresh.

    Catatan

    Hanya didukung di Hologres V4.0.7 dan versi lebih baru.

  • local: Menggunakan sumber daya komputasi lokal dari instans saat ini untuk refresh.

Parameter.

Tidak

serverless

refresh_guc_<guc_name>

Atur parameter GUC untuk refresh. Untuk daftar GUC yang didukung, lihat Parameter GUC.

Tidak

Tidak ada

Tabel partisi

Tabel partisi logis

Parameter

Deskripsi

Wajib

Default

LOGICAL PARTITION BY LIST(<partition_key>)

Membuat Tabel Dinamis partisi logis. Memerlukan auto_refresh_partition_active_time dan partition_key_time_format.

Tidak

Tidak ada

auto_refresh_partition_active_time

Lingkup refresh untuk partisi, dalam menit, jam, atau hari. Hologres menelusuri mundur dari waktu saat ini dan merefresh partisi dalam jendela ini.

Partisi aktif adalah partisi yang selang waktunya sejak mulai (diturunkan dari nama partisi) kurang dari nilai auto_refresh_partition_active_time.

Catatan
  • Parameter auto_refresh_partition_active_time harus menentukan durasi yang lebih besar dari satu interval partisi. Misalnya, jika data dipartisi harian, auto_refresh_partition_active_time harus diatur ke periode lebih dari 24 jam.

  • Parameter ini dapat dimodifikasi. Perubahan hanya memengaruhi partisi mendatang.

  • Mulai Hologres V4.2, merefresh partisi aktif Tabel Dinamis menggunakan kunci tingkat partisi alih-alih kunci tingkat tabel. Artinya, partisi berbeda dapat direfresh secara konkuren tanpa saling menunggu.

Ya

Default ke Interval partisi + 1 jam.

Ini memberikan buffer 1 jam untuk mengantisipasi potensi keterlambatan data dari tabel dasar. Misalnya, dengan partisi harian, default menjadi 25 jam (1 hari + 1 jam).

partition_key_time_format

Format nama partisi. Nilai yang valid:

  • Untuk kunci partisi TEXT/VARCHAR:

    YYYYMMDDHH24, YYYY-MM-DD-HH24, YYYY-MM-DD_HH24, YYYYMMDD, YYYY-MM-DD, YYYYMM, YYYY-MM, YYYY.

  • Untuk kunci partisi INT:

    YYYYMMDDHH24, YYYYMMDD, YYYYMM, YYYY.

  • Untuk kunci partisi DATE:

    YYYY-MM-DD

Ya

Tidak ada

Tabel partisi fisik

Parameter

Deskripsi

Wajib

Default

PARTITION BY LIST(<partition_key>)

Membuat Tabel Dinamis partisi fisik.

Tabel Dinamis partisi fisik tidak memiliki partisi dinamis dan memiliki batasan penggunaan. Partisi logis direkomendasikan. Untuk perbedaan, lihat CREATE LOGICAL PARTITION TABLE.

Penting

Hologres V3.1+ tidak mendukung pembuatan Tabel Dinamis sebagai tabel partisi fisik.

Tidak

Tidak ada

Properti tabel

Parameter

Deskripsi

Wajib

Nilai default

Mode pembaruan penuh

Mode pembaruan bertahap

col_name

Nama kolom.

Tentukan nama tetapi bukan atribut atau tipe data—mesin akan menginferensinya.

Catatan

Menentukan atribut kolom dan tipe data dapat menyebabkan inferensi mesin salah.

Tidak

Nama kolom kueri

Nama kolom kueri

orientation

Format penyimpanan. column menunjukkan penyimpanan berorientasi kolom.

Tidak

column

column

table_group

Kelompok Tabel. Default ke kelompok default database saat ini. Untuk informasi selengkapnya, lihat Kelola kelompok tabel dan shard.

Tidak

Nama Kelompok Tabel default

Nama Kelompok Tabel default

distribution_key

Kunci distribusi. Untuk informasi selengkapnya, lihat Kunci distribusi.

Tidak

(tidak ada)

(tidak ada)

clustering_key

Kunci pengelompokan. Untuk informasi selengkapnya, lihat Kunci pengelompokan.

Tidak

Diizinkan, dengan nilai default yang diinferensi.

Diizinkan, dengan nilai default yang diinferensi.

event_time_column

Lihat Kolom waktu event (kunci segmen).

Tidak

(tidak ada)

(tidak ada)

bitmap_columns

Kolom bitmap. Untuk informasi selengkapnya, lihat Indeks bitmap.

Tidak

Bidang tipe TEXT

Bidang tipe TEXT

dictionary_encoding_columns

Lihat Encoding kamus.

Tidak

Bidang tipe TEXT

Bidang tipe TEXT

time_to_live_in_seconds

TTL data.

Tidak

Tidak kedaluwarsa

Tidak kedaluwarsa

storage_mode

Tier penyimpanan. Nilai yang valid:

  • hot: Penyimpanan hot.

  • cold: Penyimpanan dingin.

Catatan

Untuk detailnya, lihat Siapkan tiering penyimpanan.

Tidak

hot

hot

binlog_level

Mengaktifkan binlog untuk Tabel Dinamis. Berlangganan Hologres Binlog.

Catatan
  • Parameter ini memerlukan V3.1.18 dan versi lebih baru.

  • Hindari mengaktifkan binlog untuk Tabel Dinamis yang menggunakan pembaruan penuh.

Tidak

none

none

binlog_ttl

TTL binlog.

Tidak

2592000

2592000

Kueri

Kueri yang mendefinisikan data Tabel Dinamis. Kueri dan tabel dasar yang didukung bervariasi tergantung mode refresh. Untuk informasi selengkapnya, lihat Dukungan dan batasan Tabel Dinamis.

V3.0 (sintaks lama)

Sintaks Create Dynamic Table

CREATE DYNAMIC TABLE [IF NOT EXISTS] <schema.tablename>(
[col_name],
[col_name]
  ) [PARTITION BY LIST (col_name)]
WITH (
    [refresh_mode='[full|incremental]',]
    [auto_refresh_enable='[true|false',]

  --Parameter pembaruan bertahap:
    [incremental_auto_refresh_schd_start_time='[immediate|<timestamptz>]',]
    [incremental_auto_refresh_interval='[<num> {minute|minutes|hour|hours]',]  
    [incremental_guc_hg_computing_resource='[ local | serverless]',]
    [incremental_guc_hg_experimental_serverless_computing_required_cores='<num>',]

   --Parameter pembaruan penuh:
    [full_auto_refresh_schd_start_time='[immediate|<timestamptz>]',]
    [full_auto_refresh_interval='[<num> {minute|minutes|hour|hours]',] 
    [full_guc_hg_computing_resource='[ local | serverless]',]--hg_full_refresh_computing_resource default ke serverless, dapat diatur di tingkat DB, dan opsional bagi pengguna.
    [full_guc_hg_experimental_serverless_computing_required_cores='<num>',]
    
   --Parameter bersama, GUC diizinkan:
   [refresh_guc_<guc>='xxx]',] 
   
  -- Properti Tabel Dinamis umum:
    [orientation = '[column]',]
    [table_group = '[tableGroupName]',]
    [distribution_key = 'columnName[,...]]',]
    [clustering_key = '[columnName{:asc]} [,...]]',]
    [event_time_column = '[columnName [,...]]',]
    [bitmap_columns = '[columnName [,...]]',]
    [dictionary_encoding_columns = '[columnName [,...]]',]
    [time_to_live_in_seconds = '<non_negative_literal>',]
    [storage_mode = '[hot | cold]']
    ) 
AS
<query> --Definisi kueri

Parameter

Mode refresh dan sumber daya

Kategori

Parameter

Deskripsi

Wajib

Default

Parameter refresh bersama

refresh_mode

Mode refresh. Nilai yang valid: full dan incremental.

Jika tidak diatur, tidak ada refresh yang dilakukan.

Tidak

(tidak ada)

auto_refresh_enable

Aktifkan atau nonaktifkan refresh otomatis. Nilai yang valid:

  • true

  • false

Tidak

false

refresh_guc_<guc>

Atur parameter GUC untuk refresh. Untuk daftar GUC yang didukung, lihat Parameter GUC.

Catatan

Sebagai contoh, untuk mengatur GUC timezone, gunakan refresh_guc_timezone = 'GMT-8:00'.

Tidak

(tidak ada)

Pembaruan bertahap

incremental_auto_refresh_schd_start_time

Waktu mulai untuk pembaruan bertahap. Nilai yang valid:

  • immediate: Default. Memulai pembaruan bertahap segera setelah pembuatan tabel.

  • <timestamptz>: Waktu mulai kustom, misalnya '2024-08-24 1:00', untuk memulai tugas refresh pada waktu tersebut.

Tidak

immediate

incremental_auto_refresh_interval

Interval pembaruan bertahap, dalam menit atau jam.

  • Rentang nilai: [1 menit, 48 jam].

  • Jika tidak diatur, Tabel Dinamis hanya direfresh sekali, pada waktu mulai.

Tidak

(tidak ada)

incremental_guc_hg_computing_resource

Sumber daya komputasi untuk pembaruan bertahap. Nilai yang valid:

  • local: Gunakan sumber daya instans sendiri.

  • serverless: Gunakan sumber daya Komputasi Tanpa Server. Untuk memeriksa apakah instans memenuhi persyaratan Komputasi Tanpa Server, lihat Bekerja dengan komputasi tanpa server.

Catatan

Untuk mengatur sumber daya komputasi di tingkat DB, jalankan ALTER DATABASE xxx SET incremental_guc_hg_computing_resource=xx.

Tidak

local

incremental_guc_hg_experimental_serverless_computing_required_cores

Core Komputasi Tanpa Server untuk refresh.

Catatan

Kuota sumber daya Komputasi Tanpa Server bervariasi berdasarkan spesifikasi instans. Untuk informasi selengkapnya, lihat Kelola sumber daya komputasi tanpa server.

Tidak

(tidak ada)

Pembaruan penuh

full_auto_refresh_schd_start_time

Waktu mulai untuk pembaruan penuh. Nilai yang valid:

  • immediate: Default. Memulai pembaruan penuh segera setelah pembuatan tabel.

  • <timestamptz>: Waktu mulai kustom, misalnya '2024-08-24 1:00', untuk memulai tugas refresh pada waktu tersebut.

Tidak

immediate

full_auto_refresh_interval

Interval pembaruan penuh, dalam menit atau jam.

  • Rentang nilai: [1 menit, 48 jam].

  • Jika tidak diatur, Tabel Dinamis hanya direfresh sekali, pada waktu mulai.

Tidak

(tidak ada)

full_guc_hg_computing_resource

Sumber daya komputasi untuk pembaruan penuh. Nilai yang valid:

  • local: Sumber daya instans sendiri.

  • serverless: Gunakan sumber daya Komputasi Tanpa Server. Untuk memeriksa apakah instans memenuhi persyaratan Komputasi Tanpa Server, lihat Bekerja dengan komputasi tanpa server.

Catatan

Untuk mengatur sumber daya komputasi di tingkat DB, jalankan ALTER DATABASE xxx SET full_guc_hg_computing_resource=xx.

Tidak

local

full_guc_hg_experimental_serverless_computing_required_cores

Core Komputasi Tanpa Server untuk refresh.

Catatan

Kuota sumber daya Komputasi Tanpa Server bervariasi berdasarkan spesifikasi instans. Untuk informasi selengkapnya, lihat Kelola sumber daya komputasi tanpa server.

Tidak

(tidak ada)

Properti tabel

Parameter

Deskripsi

Wajib

Default

full

incremental

col_name

Nama kolom.

Tentukan nama tetapi bukan atribut atau tipe data—mesin akan menginferensinya.

Catatan

Menentukan atribut kolom dan tipe data dapat menyebabkan inferensi mesin salah.

Tidak

Nama kolom kueri

Nama kolom kueri

orientation

Format penyimpanan untuk Tabel Dinamis. column menunjukkan penyimpanan berorientasi kolom.

Tidak

column

column

table_group

Kelompok Tabel. Default ke kelompok default database saat ini. Untuk informasi selengkapnya, lihat Kelola kelompok tabel dan shard.

Tidak

Nama Kelompok Tabel default

Nama Kelompok Tabel default

distribution_key

Kunci distribusi. Untuk informasi selengkapnya, lihat Kunci distribusi.

Tidak

(tidak ada)

(tidak ada)

clustering_key

Kunci pengelompokan. Untuk informasi selengkapnya, lihat Kunci pengelompokan.

Tidak

Diizinkan, dengan nilai default yang diinferensi.

Diizinkan, dengan nilai default yang diinferensi.

event_time_column

Kunci segmen. Untuk informasi selengkapnya, lihat Kolom waktu event (kunci segmen).

Tidak

(tidak ada)

(tidak ada)

bitmap_columns

Kolom bitmap. Untuk informasi selengkapnya, lihat Indeks bitmap.

Tidak

Bidang tipe TEXT

Bidang tipe TEXT

dictionary_encoding_columns

Lihat Encoding kamus.

Tidak

Bidang tipe TEXT

Bidang tipe TEXT

time_to_live_in_seconds

TTL data.

Tidak

Tidak kedaluwarsa

Tidak kedaluwarsa

storage_mode

Tier penyimpanan. Nilai yang valid:

  • hot: Penyimpanan panas.

  • cold: Penyimpanan cold.

Tidak

hot

hot

PARTITION BY LIST

Membuat Tabel Dinamis partisi. Partisi dapat menggunakan mode refresh berbeda untuk kebutuhan kesegaran yang berbeda.

Tidak

Tabel non-partisi

Tabel non-partisi

Kueri

Kueri yang menghasilkan data Tabel Dinamis. Kueri dan jenis tabel dasar yang didukung bervariasi tergantung mode refresh. Dukungan dan batasan Tabel Dinamis.

Pembaruan bertahap

Pembaruan bertahap mendeteksi perubahan pada tabel dasar dan hanya menulis delta ke Tabel Dinamis, ideal untuk kueri near-real-time (tingkat menit).

  • Batasan tabel dasar:

    • V3.1 menggunakan mode default stream. Jika tabel dasar Anda memiliki binlog diaktifkan di V3.0, nonaktifkan untuk menghindari biaya penyimpanan tambahan.

    • Di V3.0, Anda harus mengaktifkan binlog untuk tabel dasar, kecuali untuk tabel dimensi yang terlibat dalam join. Mengaktifkan binlog untuk tabel dasar menimbulkan overhead penyimpanan. Periksa penggunaan penyimpanan binlog dengan merujuk ke Lihat detail penyimpanan tabel.

  • Dalam mode pembaruan bertahap, Hologres menghasilkan tabel status di latar belakang untuk mencatat hasil agregasi antara (lihat Tabel dinamis untuk detailnya). Tabel status juga mengonsumsi ruang penyimpanan. Untuk melihat penggunaan penyimpanan, lihat Lihat skema dan lineage tabel dinamis.

  • Kueri dan operator yang didukung untuk pembaruan bertahap: Dukungan dan batasan Tabel Dinamis.

  • Saat menjalankan pembaruan bertahap untuk pertama kalinya, sistem melakukan pemuatan data penuh dan menginisialisasi tabel status yang digunakan untuk pelacakan status. Karena semua data historis harus diproses sekaligus dan struktur status harus diinisialisasi, konsumsi memori dan sumber daya komputasi jauh lebih tinggi daripada siklus inkremental berikutnya. Jika volume data tabel dasar besar atau sumber daya tidak mencukupi, error kehabisan memori (OOM) dapat terjadi.

  • Untuk menghindari bottleneck sumber daya, evaluasi volume data tabel dasar sebelum menjalankan refresh pertama dan gunakan sumber daya Komputasi Tanpa Server. Untuk informasi selengkapnya, lihat Gunakan Komputasi Tanpa Server untuk membaca dan menulis data.

Join stream-stream

JOIN stream-stream memiliki semantik yang sama dengan kueri OLAP, menggunakan HASH JOIN dan mendukung INNER JOIN, LEFT/RIGHT/FULL OUTER JOIN.

V3.1

Catatan

Mulai Hologres V3.1, GUC untuk JOIN stream-stream diaktifkan secara default.

Contoh:

CREATE TABLE users (
  user_id INT,
  user_name TEXT,
  PRIMARY KEY (user_id)
);
INSERT INTO users VALUES(1, 'hologres');

CREATE TABLE orders (
  order_id INT,
  user_id INT,
  PRIMARY KEY (order_id)
);
INSERT INTO orders VALUES(1, 1);

CREATE DYNAMIC TABLE dt WITH (
  auto_refresh_mode = 'incremental',
  freshness='10 minutes'
) 
AS 
SELECT order_id, orders.user_id, user_name 
FROM orders LEFT JOIN users ON orders.user_id = users.user_id;

-- Setelah refresh, satu record yang digabung terlihat
REFRESH TABLE dt;
SELECT * FROM dt;
 order_id | user_id | user_name 
----------+---------+-----------
        1 |       1 | hologres
(1 row)


UPDATE users SET user_name = 'dynamic table' WHERE user_id = 1;
INSERT INTO orders VALUES(4, 1);

-- Setelah refresh, dua record yang digabung terlihat. Pembaruan tabel dimensi memengaruhi semua data dan dapat mengoreksi record yang sebelumnya digabung.
REFRESH TABLE dt;
SELECT * FROM dt;

Hasil:

order_id | user_id |   user_name   
----------+---------+---------------
        1 |       1 | dynamic table
        4 |       1 | dynamic table
(2 rows)

V3.0

JOIN stream-stream didukung di V3.0.26. Untuk mengaktifkan fitur ini, tingkatkan instans Anda dan aktifkan GUC:

-- Aktifkan di tingkat session
SET hg_experimental_incremental_dynamic_table_enable_hash_join TO ON;

-- Aktifkan di tingkat DB (berlaku untuk koneksi baru)
ALTER database <db_name> SET hg_experimental_incremental_dynamic_table_enable_hash_join TO ON;

Contoh:

CREATE TABLE users (
  user_id INT,
  user_name TEXT,
  PRIMARY KEY (user_id)
) WITH (binlog_level = 'replica');
INSERT INTO users VALUES(1, 'hologres');

CREATE TABLE orders (
  order_id INT,
  user_id INT,
  PRIMARY KEY (order_id)
)  WITH (binlog_level = 'replica');
INSERT INTO orders VALUES(1, 1);

CREATE DYNAMIC TABLE dt WITH (refresh_mode = 'incremental') 
AS 
SELECT order_id, orders.user_id, user_name 
FROM orders LEFT JOIN users ON orders.user_id = users.user_id;

-- Setelah refresh, satu record yang digabung terlihat
REFRESH TABLE dt;
SELECT * FROM dt;
 order_id | user_id | user_name 
----------+---------+-----------
        1 |       1 | hologres
(1 row)


UPDATE users SET user_name = 'dynamic table' WHERE user_id = 1;
INSERT INTO orders VALUES(4, 1);

-- Setelah refresh, dua record yang digabung terlihat. Pembaruan tabel dimensi memengaruhi semua data dan dapat mengoreksi record yang sebelumnya digabung.
REFRESH TABLE dt;
SELECT * FROM dt;

Hasil:

order_id | user_id |   user_name   
----------+---------+---------------
        1 |       1 | dynamic table
        4 |       1 | dynamic table
(2 rows)

Join tabel dimensi

Setiap record stream digabung dengan snapshot terbaru tabel dimensi pada waktu pemrosesan. Perubahan pada tabel dimensi setelah JOIN tidak memengaruhi data yang sudah diproses.

Catatan

Perilaku JOIN tabel dimensi tidak bergantung pada ukuran tabel; ditentukan oleh pernyataan JOIN.

V3.1

CREATE TABLE users (
  user_id INT,
  user_name TEXT,
  PRIMARY KEY (user_id)
);
INSERT INTO users VALUES(1, 'hologres');

CREATE TABLE orders (
  order_id INT,
  user_id INT,
  PRIMARY KEY (order_id)
)  WITH (binlog_level = 'replica');

INSERT INTO orders VALUES(1, 1);
CREATE DYNAMIC TABLE dt_join_2 WITH (
    auto_refresh_mode = 'incremental',
    freshness='10 minutes') 
AS 
SELECT order_id, orders.user_id, user_name 
-- FOR SYSTEM_TIME AS OF PROCTIME() mengidentifikasi 'users' sebagai tabel dimensi
FROM orders LEFT JOIN users FOR SYSTEM_TIME AS OF PROCTIME()
ON orders.user_id = users.user_id;

-- Setelah refresh, satu record yang digabung terlihat
REFRESH TABLE dt_join_2;
SELECT * FROM dt_join_2;
 order_id | user_id | user_name 
----------+---------+-----------
        1 |       1 | hologres
(1 row)


UPDATE users SET user_name = 'dynamic table' WHERE user_id = 1;
INSERT INTO orders VALUES(4, 1);

-- Setelah refresh, dua record yang digabung terlihat. Pembaruan tabel dimensi hanya memengaruhi data baru dan tidak dapat mengoreksi data yang sebelumnya digabung.
REFRESH TABLE dt_join_2;
SELECT * FROM dt_join_2;

Hasil:

order_id | user_id |   user_name   
----------+---------+---------------
        1 |       1 | hologres
        4 |       1 | dynamic table
(2 rows)

V3.0

CREATE TABLE users (
  user_id INT,
  user_name TEXT,
  PRIMARY KEY (user_id)
);
INSERT INTO users VALUES(1, 'hologres');

CREATE TABLE orders (
  order_id INT,
  user_id INT,
  PRIMARY KEY (order_id)
)  WITH (binlog_level = 'replica');
INSERT INTO orders VALUES(1, 1);

CREATE DYNAMIC TABLE dt_join_2 WITH (refresh_mode = 'incremental') 
AS 
SELECT order_id, orders.user_id, user_name 
-- FOR SYSTEM_TIME AS OF PROCTIME() mengidentifikasi 'users' sebagai tabel dimensi
FROM orders LEFT JOIN users FOR SYSTEM_TIME AS OF PROCTIME()
ON orders.user_id = users.user_id;

-- Setelah refresh, satu record yang digabung terlihat
REFRESH TABLE dt_join_2;
SELECT * FROM dt_join_2;

order_id | user_id | user_name 
----------+---------+-----------
        1 |       1 | hologres
(1 row)
 
UPDATE users SET user_name = 'dynamic table' WHERE user_id = 1;
INSERT INTO orders VALUES(4, 1);

-- Setelah refresh, dua record yang digabung terlihat. Pembaruan tabel dimensi hanya memengaruhi data baru dan tidak dapat mengoreksi data yang sebelumnya digabung.
REFRESH TABLE dt_join_2;
SELECT * FROM dt_join_2;

Hasil:

order_id | user_id |   user_name   
----------+---------+---------------
        1 |       1 | hologres
        4 |       1 | dynamic table
(2 rows)

Konsumsi inkremental tabel lake Paimon

  • Pembaruan bertahap mendukung konsumsi tabel Paimon untuk skenario lakehouse.

  • Tabel Dinamis Eksternal mendukung pembacaan inkremental dan penulisan balik, mengurangi biaya pemrosesan dan latensi kueri. Pengantar Tabel Dinamis Eksternal.

Konsumsi hibrida

Tabel Dinamis Bertahap mendukung model hibrida: pemuatan penuh awal dari semua data tabel dasar yang ada, diikuti oleh pemrosesan inkremental berkelanjutan.

V3.1

V3.1 mengaktifkan model refresh hibrida secara default. Contoh:

--Persiapkan tabel dasar dan masukkan data
CREATE TABLE base_sales(
  day TEXT NOT NULL,
  hour INT,
  user_id BIGINT,
  ts TIMESTAMPTZ,
  amount FLOAT,
  pk text NOT NULL PRIMARY KEY
);

-- Impor data ke tabel dasar
INSERT INTO base_sales values ('2024-08-29',1,222222,'2024-08-29 16:41:19.141528+08',5,'ddd');


-- Impor lebih banyak data
INSERT INTO base_sales VALUES ('2024-08-29',2,3333,'2024-08-29 17:44:19.141528+08',100,'aaaaa');


-- Buat Tabel Dinamis bertahap
CREATE DYNAMIC TABLE sales_incremental
  WITH (
    auto_refresh_mode='incremental',
    freshness='10 minutes'
  ) 
AS 
  SELECT day, hour, SUM(amount), COUNT(1) 
    FROM base_sales 
  GROUP BY day, hour;

Periksa konsistensi data:

  • Kueri tabel dasar

    SELECT day, hour, SUM(amount), COUNT(1) 
        FROM base_sales 
      GROUP BY day, hour;

    Hasil:

    day	    hour	sum	count
    2024-08-29	2	100	1
    2024-08-29	1	5	1
  • Kueri Tabel Dinamis

    SELECT * FROM sales_incremental;

    Hasil:

    day	    hour	sum	count
    2024-08-29	1	5	1
    2024-08-29	2	100	1

V3.0

Di V3.0, untuk menggunakan konsumsi hibrida, aktifkan secara manual GUC incremental_guc_hg_experimental_enable_hybrid_incremental_mode. Contoh:

--Persiapkan tabel dasar, aktifkan Binlog, dan masukkan data
CREATE TABLE base_sales(
  day TEXT NOT NULL,
  hour INT,
  user_id BIGINT,
  ts TIMESTAMPTZ,
  amount FLOAT,
  pk text NOT NULL PRIMARY KEY
);

-- Impor data ke tabel dasar
INSERT INTO base_sales values ('2024-08-29',1,222222,'2024-08-29 16:41:19.141528+08',5,'ddd');

-- Aktifkan Binlog untuk tabel dasar
ALTER TABLE base_sales SET (binlog_level = replica);

-- Impor data inkremental ke tabel dasar
INSERT INTO base_sales VALUES ('2024-08-29',2,3333,'2024-08-29 17:44:19.141528+08',100,'aaaaa');


-- Buat Tabel Dinamis bertahap dengan auto-refresh dan aktifkan GUC untuk konsumsi hibrida
CREATE DYNAMIC TABLE sales_incremental
  WITH (
    refresh_mode='incremental',
    incremental_auto_refresh_schd_start_time = 'immediate',
    incremental_auto_refresh_interval = '3 minutes',
    incremental_guc_hg_experimental_enable_hybrid_incremental_mode= 'true'
  ) 
AS 
  SELECT day, hour, SUM(amount), COUNT(1) 
    FROM base_sales 
  GROUP BY day, hour;

Periksa konsistensi data:

  • Kueri tabel dasar

    SELECT day, hour, SUM(amount), COUNT(1) 
        FROM base_sales 
      GROUP BY day, hour;

    Hasil:

    day	    hour	sum	count
    2024-08-29	2	100	1
    2024-08-29	1	5	1
  • Kueri Tabel Dinamis

    SELECT * FROM sales_incremental;

    Hasil:

    day	    hour	sum	count
    2024-08-29	1	5	1
    2024-08-29	2	100	1

Pembaruan penuh

Pembaruan penuh menulis ulang seluruh dataset dari kueri. Dibandingkan dengan pembaruan bertahap:

  • Mendukung lebih banyak jenis tabel dasar.

  • Mendukung lebih banyak jenis kueri dan operator.

Pembaruan penuh menggunakan lebih banyak sumber daya dan paling cocok untuk pelaporan periodik serta pengisian ulang data.

Catatan

Untuk informasi selengkapnya, lihat Pembaruan penuh.

Contoh

V3.1

Contoh 1: Buat Tabel Dinamis Bertahap biasa

Sebelum melanjutkan, impor dataset publik tpch_10g ke Hologres dengan mengikuti panduan di Impor dataset publik dengan beberapa klik.

Catatan

Sebelum membuat Tabel Dinamis Bertahap, aktifkan Binlog untuk tabel dasar (tidak diperlukan untuk tabel dimensi).

-- Buat Tabel Dinamis Bertahap yang direfresh setiap 3 menit.
CREATE DYNAMIC TABLE public.tpch_q1_incremental 
WITH (
auto_refresh_mode='incremental',
freshness='3 minutes'
) AS SELECT
        l_returnflag,
        l_linestatus,
        COUNT(*) AS count_order
FROM
        hologres_dataset_tpch_10g.lineitem
WHERE
        l_shipdate <= DATE '1998-12-01' - INTERVAL '120' DAY
GROUP BY
        l_returnflag,
        l_linestatus;

Contoh 2: Buat Tabel Dinamis Bertahap dari join stream-stream

Sebelum melanjutkan, impor dataset publik tpch_10g ke Hologres dengan mengikuti panduan di Impor dataset publik dengan beberapa klik.

Catatan

Sebelum membuat Tabel Dinamis Bertahap, aktifkan binlog untuk tabel dasar (tidak diperlukan untuk tabel dimensi).

-- Buat Tabel Dinamis Bertahap dari join stream-stream.
CREATE DYNAMIC TABLE dt_join
  WITH (
    auto_refresh_mode='incremental',
    freshness='30 minutes'
  ) 
AS 
SELECT
        l_shipmode,
        SUM(CASE
                WHEN o_orderpriority = '1-URGENT'
                        OR o_orderpriority = '2-HIGH'
                        THEN 1
                ELSE 0
        END) AS high_line_count,
        SUM(CASE
                WHEN o_orderpriority <> '1-URGENT'
                        AND o_orderpriority <> '2-HIGH'
                        THEN 1
                ELSE 0
        END) AS low_line_count
FROM
        hologres_dataset_tpch_10g.orders,
        hologres_dataset_tpch_10g.lineitem
WHERE
        o_orderkey = l_orderkey
        AND l_shipmode IN ('FOB', 'AIR')
        AND l_commitdate < l_receiptdate
        AND l_shipdate < l_commitdate
        AND l_receiptdate >= DATE '1997-01-01'
        AND l_receiptdate < DATE '1997-01-01' + INTERVAL '1' YEAR
GROUP BY
        l_shipmode;

Contoh 3: Buat Tabel Dinamis dengan Auto-refresh

Atur mode refresh ke auto. Mesin memprioritaskan pembaruan bertahap dan beralih ke pembaruan penuh jika tidak didukung.

Sebelum melanjutkan, impor dataset publik tpch_10g ke Hologres dengan mengikuti panduan di Impor dataset publik dengan beberapa klik.

-- Buat Tabel Dinamis dengan Auto-refresh yang secara cerdas menentukan mode refresh. Dalam contoh ini, hasilnya adalah pembaruan bertahap.
CREATE DYNAMIC TABLE thch_q6_auto
  WITH (
    auto_refresh_mode='auto',
    freshness='1 hours'
       ) 
AS
SELECT
        SUM(l_extendedprice * l_discount) AS revenue
FROM
        hologres_dataset_tpch_100g.lineitem
WHERE
        l_shipdate >= DATE '1996-01-01'
        AND l_shipdate < DATE '1996-01-01' + INTERVAL '1' YEAR
        AND l_discount BETWEEN 0.02 - 0.01 AND 0.02 + 0.01
        AND l_quantity < 24;

Contoh 4: Buat Tabel Dinamis partisi logis

Untuk dasbor transaksi real-time, seringkali diperlukan tampilan near-real-time data saat ini dan koreksi data historis, yang memerlukan solusi analisis real-time dan offline terintegrasi (Kognisi bisnis dan data). Pendekatan umum menggunakan partisi logis `Tabel Dinamis` untuk skenario ini adalah sebagai berikut:

  • Tabel dasar dipartisi berdasarkan hari. Partisi terbaru ditulis oleh Flink secara real-time/near-real-time, sedangkan partisi historis ditulis dari MaxCompute.

  • Tabel Dinamis dibuat sebagai tabel partisi logis. Dua partisi terbaru aktif dan direfresh secara bertahap untuk analitik data near-real-time.

  • Partisi historis tidak aktif dan menggunakan pembaruan penuh. Jika partisi historis tabel dasar telah dikoreksi atau diisi ulang, mereka dapat direfresh menggunakan pembaruan penuh.

Contoh ini menggunakan dataset publik dari GitHub.

  1. Persiapkan tabel dasar.

    Gunakan Flink untuk menulis data terbaru ke tabel dasar. Untuk langkah-langkah detail, lihat Analitik batch dan real-time terpadu pada event GitHub.

    DROP TABLE IF EXISTS gh_realtime_data;
    
    BEGIN;
    CREATE TABLE gh_realtime_data (
        id BIGINT,
        actor_id BIGINT,
        actor_login TEXT,
        repo_id BIGINT,
        repo_name TEXT,
        org_id BIGINT,
        org_login TEXT,
        type TEXT,
        created_at timestamp with time zone NOT NULL,
        action TEXT,
        iss_or_pr_id BIGINT,
        number BIGINT,
        comment_id BIGINT,
        commit_id TEXT,
        member_id BIGINT,
        rev_or_push_or_rel_id BIGINT,
        ref TEXT,
        ref_type TEXT,
        state TEXT,
        author_association TEXT,
        language TEXT,
        merged BOOLEAN,
        merged_at TIMESTAMP WITH TIME ZONE,
        additions BIGINT,
        deletions BIGINT,
        changed_files BIGINT,
        push_size BIGINT,
        push_distinct_size BIGINT,
        hr TEXT,
        month TEXT,
        year TEXT,
        ds TEXT,
        PRIMARY KEY (id,ds)
    )
    PARTITION BY LIST (ds);
    CALL set_table_property('public.gh_realtime_data', 'distribution_key', 'id');
    CALL set_table_property('public.gh_realtime_data', 'event_time_column', 'created_at');
    CALL set_table_property('public.gh_realtime_data', 'clustering_key', 'created_at');
    
    COMMENT ON COLUMN public.gh_realtime_data.id IS 'Event ID';
    COMMENT ON COLUMN public.gh_realtime_data.actor_id IS 'Event actor ID';
    COMMENT ON COLUMN public.gh_realtime_data.actor_login IS 'Event actor login name';
    COMMENT ON COLUMN public.gh_realtime_data.repo_id IS 'Repo ID';
    COMMENT ON COLUMN public.gh_realtime_data.repo_name IS 'Repo name';
    COMMENT ON COLUMN public.gh_realtime_data.org_id IS 'Repo organization ID';
    COMMENT ON COLUMN public.gh_realtime_data.org_login IS 'Repo organization name';
    COMMENT ON COLUMN public.gh_realtime_data.type IS 'Event type';
    COMMENT ON COLUMN public.gh_realtime_data.created_at IS 'Event time';
    COMMENT ON COLUMN public.gh_realtime_data.action IS 'Event action';
    COMMENT ON COLUMN public.gh_realtime_data.iss_or_pr_id IS 'Issue/pull_request ID';
    COMMENT ON COLUMN public.gh_realtime_data.number IS 'Issue/pull_request number';
    COMMENT ON COLUMN public.gh_realtime_data.comment_id IS 'Comment ID';
    COMMENT ON COLUMN public.gh_realtime_data.commit_id IS 'Commit ID';
    COMMENT ON COLUMN public.gh_realtime_data.member_id IS 'Member ID';
    COMMENT ON COLUMN public.gh_realtime_data.rev_or_push_or_rel_id IS 'Review/push/release ID';
    COMMENT ON COLUMN public.gh_realtime_data.ref IS 'Name of created/deleted resource';
    COMMENT ON COLUMN public.gh_realtime_data.ref_type IS 'Type of created/deleted resource';
    COMMENT ON COLUMN public.gh_realtime_data.state IS 'State of issue/pull_request/pull_request_review';
    COMMENT ON COLUMN public.gh_realtime_data.author_association IS 'Relationship between actor and repo';
    COMMENT ON COLUMN public.gh_realtime_data.language IS 'Programming language';
    COMMENT ON COLUMN public.gh_realtime_data.merged IS 'Whether merged';
    COMMENT ON COLUMN public.gh_realtime_data.merged_at IS 'Merge time';
    COMMENT ON COLUMN public.gh_realtime_data.additions IS 'Number of added lines';
    COMMENT ON COLUMN public.gh_realtime_data.deletions IS 'Number of deleted lines';
    COMMENT ON COLUMN public.gh_realtime_data.changed_files IS 'Number of changed files in pull request';
    COMMENT ON COLUMN public.gh_realtime_data.push_size IS 'Number of pushes';
    COMMENT ON COLUMN public.gh_realtime_data.push_distinct_size IS 'Number of distinct pushes';
    COMMENT ON COLUMN public.gh_realtime_data.hr IS 'Hour of event, e.g., 00 for 00:23';
    COMMENT ON COLUMN public.gh_realtime_data.month IS 'Month of event, e.g., 2015-10 for Oct 2015';
    COMMENT ON COLUMN public.gh_realtime_data.year IS 'Year of event, e.g., 2015';
    COMMENT ON COLUMN public.gh_realtime_data.ds IS 'Date of event, ds=yyyy-mm-dd';
    
    COMMIT;
  2. Buat Tabel Dinamis partisi logis.

    CREATE  DYNAMIC TABLE ads_dt_github_event
    LOGICAL PARTITION BY LIST(ds)
    WITH (
      -- Properti tabel dinamis
      freshness = '5 minutes', 
      auto_refresh_mode = 'auto', 
      auto_refresh_partition_active_time = '2 days' ,
      partition_key_time_format = 'YYYY-MM-DD'
    )
    AS
    SELECT
        repo_name,
        COUNT(*) AS events,
        ds
    FROM
        gh_realtime_data
    GROUP BY repo_name,ds
  3. Kueri Tabel Dinamis.

    SELECT * FROM ads_dt_github_event ;
  4. Isi ulang partisi historis.

    Jika data historis di tabel dasar berubah (misalnya, data untuk '2025-04-01'), dan Tabel Dinamis perlu diperbarui, atur partisi historis ke mode pembaruan penuh dan picu refresh, sebaiknya dengan sumber daya Komputasi Tanpa Server.

    REFRESH OVERWRITE DYNAMIC TABLE ads_dt_github_event
    PARTITION (ds = '2025-04-01') 
    WITH (
      refresh_mode = 'full'
    );

Contoh 5: Hitung UV dengan Tabel Dinamis Bertahap

Mulai Hologres V3.1, Tabel Dinamis Bertahap mendukung fungsi RB_BUILD_AGG untuk perhitungan seperti jumlah UV. Dibandingkan dengan pra-agregasi, pendekatan ini menawarkan:

  • Performa lebih cepat: Hanya menghitung data inkremental.

  • Biaya lebih rendah: Volume data dan penggunaan sumber daya berkurang, memungkinkan perhitungan periode lebih panjang.

Contoh:

  1. Persiapkan tabel detail pengguna.

    BEGIN;
    CREATE TABLE IF NOT EXISTS ods_app_detail (
         uid INT,
         country TEXT,
         prov TEXT,
         city TEXT,
         channel TEXT,
         operator TEXT,
         brand TEXT,
         ip TEXT,
         click_time TEXT,
         year TEXT,
         month TEXT,
         day TEXT,
         ymd TEXT NOT NULL
    );
    CALL set_table_property('ods_app_detail', 'orientation', 'column');
    CALL set_table_property('ods_app_detail', 'bitmap_columns', 'country,prov,city,channel,operator,brand,ip,click_time, year, month, day, ymd');
    -- Atur distribution_key berdasarkan kebutuhan kueri untuk efek sharding optimal.
    CALL set_table_property('ods_app_detail', 'distribution_key', 'uid');
    -- Untuk bidang dengan tanggal-waktu lengkap yang digunakan dalam filter WHERE, disarankan mengaturnya sebagai clustering_key dan event_time_column.
    CALL set_table_property('ods_app_detail', 'clustering_key', 'ymd');
    CALL set_table_property('ods_app_detail', 'event_time_column', 'ymd');
    COMMIT;
  2. Hitung UV menggunakan Tabel Dinamis Bertahap.

    CREATE DYNAMIC TABLE ads_uv_dt
      WITH (
        freshness = '5 minutes', 
        auto_refresh_mode = 'incremental') 
      AS 
    SELECT  
     RB_BUILD_AGG(uid),
     country,
     prov,
     city,
     ymd,
    COUNT(1)
    FROM    ods_app_detail
    WHERE ymd >= '20231201' AND ymd <='20240502'
    GROUP BY country,prov,city,ymd;
  3. Kueri UV untuk hari tertentu.

    SELECT  
    RB_CARDINALITY(RB_OR_AGG(rb_uid)) AS uv,
      country,
      prov,
      city,
      SUM(pv) AS pv
    FROM    ads_uv_dt
    WHERE   ymd = '20240329'
    GROUP BY country,prov,city;

V3.0

Contoh 1: Buat tabel dinamis pembaruan penuh yang mulai otomatis

Sebelum melanjutkan, impor dataset publik tpch_10g ke Hologres dengan mengikuti panduan di Impor dataset publik dengan beberapa klik.

--Buat Skema "test"
CREATE SCHEMA test;

--Buat tabel dinamis pembaruan penuh single-table, mulai segera dan direfresh setiap jam.
CREATE DYNAMIC TABLE test.thch_q1_full
  WITH (
    refresh_mode='full',
    auto_refresh_enable='true',
    full_auto_refresh_interval='1 hours',
    full_guc_hg_computing_resource='serverless',
    full_guc_hg_experimental_serverless_computing_required_cores='32'
       ) 
AS
  SELECT
        l_returnflag,
        l_linestatus,
        SUM(l_quantity) AS sum_qty,
        SUM(l_extendedprice) AS sum_base_price,
        SUM(l_extendedprice * (1 - l_discount)) AS sum_disc_price,
        SUM(l_extendedprice * (1 - l_discount) * (1 + l_tax)) AS sum_charge,
        AVG(l_quantity) AS avg_qty,
        AVG(l_extendedprice) AS avg_price,
        AVG(l_discount) AS avg_disc,
        COUNT(*) AS count_order
FROM
        hologres_dataset_tpch_10g.lineitem
WHERE
        l_shipdate <= DATE '1998-12-01' - INTERVAL '120' DAY
GROUP BY
        l_returnflag,
        l_linestatus;

Contoh 2: Buat tabel dinamis bertahap dengan waktu mulai

Sebelum melanjutkan, impor dataset publik tpch_10g ke Hologres dengan mengikuti panduan di Impor dataset publik dengan beberapa klik.

Contoh:

Catatan

Sebelum membuat `Tabel Dinamis` bertahap, Anda harus mengaktifkan Binlog untuk tabel dasar (tidak diperlukan untuk tabel dimensi).

--Aktifkan binlog untuk tabel dasar:
BEGIN;
CALL set_table_property('hologres_dataset_tpch_10g.lineitem', 'binlog.level', 'replica');
COMMIT;

--Buat tabel dinamis refresh bertahap single-table, menentukan waktu mulai dan interval refresh 3 menit.
CREATE DYNAMIC TABLE public.tpch_q1_incremental 
WITH (
refresh_mode='incremental',
auto_refresh_enable='true',
incremental_auto_refresh_schd_start_time='2024-09-15 23:50:0',
incremental_auto_refresh_interval='3 minutes',
incremental_guc_hg_computing_resource='serverless',
incremental_guc_hg_experimental_serverless_computing_required_cores='30'
) AS SELECT
        l_returnflag,
        l_linestatus,
        COUNT(*) AS count_order
FROM
        hologres_dataset_tpch_10g.lineitem
WHERE
        l_shipdate <= DATE '1998-12-01' - INTERVAL '120' DAY
GROUP BY
        l_returnflag,
        l_linestatus
;

Contoh 3: Buat tabel dinamis multi-join pembaruan penuh

--Buat tabel dinamis dengan kueri join multi-tabel, menggunakan mode pembaruan penuh setiap 3 jam.
CREATE DYNAMIC TABLE dt_q_full
  WITH (
    refresh_mode='full',
    auto_refresh_enable='true',
    full_auto_refresh_schd_start_time='immediate',
    full_auto_refresh_interval='3 hours',
    full_guc_hg_computing_resource='serverless',
    full_guc_hg_experimental_serverless_computing_required_cores='64'
  ) 
AS 
SELECT
        o_orderpriority,
        COUNT(*) AS order_count
FROM
        hologres_dataset_tpch_10g.orders
WHERE
        o_orderdate >= DATE '1996-07-01'
        AND o_orderdate < DATE '1996-07-01' + INTERVAL '3' MONTH
        AND EXISTS (
                SELECT
                        *
                FROM
                        hologres_dataset_tpch_10g.lineitem
                WHERE
                        l_orderkey = o_orderkey
                        AND l_commitdate < l_receiptdate
        )
GROUP BY
        o_orderpriority;

Contoh 4: Buat tabel dinamis join-dimensi bertahap

Contoh:

Catatan

Sebelum membuat `Tabel Dinamis` bertahap, Anda harus mengaktifkan Binlog untuk tabel dasar (tidak diperlukan untuk tabel dimensi).

Semantik JOIN tabel dimensi adalah bahwa setiap record hanya digabung dengan versi terbaru data tabel dimensi pada waktu tersebut, yaitu JOIN terjadi pada waktu pemrosesan. Jika data tabel dimensi berubah (tambah, perbarui, atau hapus) setelah JOIN, data yang sudah digabung tidak diperbarui. Contoh SQL:

--Tabel detail
BEGIN;
CREATE TABLE public.sale_detail(
        app_id TEXT,
        uid TEXT,
        product TEXT,
        gmv BIGINT,
        order_time TIMESTAMPTZ
);
--Aktifkan binlog untuk tabel dasar; tabel dimensi tidak memerlukannya.
CALL set_table_property('public.sale_detail', 'binlog.level', 'replica');
COMMIT;

--Tabel properti
CREATE TABLE public.user_info(
        uid TEXT,
        province TEXT,
        city TEXT
);

CREATE DYNAMIC TABLE public.dt_sales_incremental
  WITH (
    refresh_mode='incremental',
    auto_refresh_enable='true',
    incremental_auto_refresh_schd_start_time='2024-09-15 00:00:00',
    incremental_auto_refresh_interval='5 minutes',
    incremental_guc_hg_computing_resource='serverless',
    incremental_guc_hg_experimental_serverless_computing_required_cores='128') 
AS 
SELECT 
    sale_detail.app_id,
    sale_detail.uid,
    product,
    SUM(sale_detail.gmv) AS sum_gmv,
    sale_detail.order_time,
    user_info.province,
    user_info.city 
FROM public.sale_detail 
INNER JOIN public.user_info  FOR SYSTEM_TIME AS OF PROCTIME()
ON sale_detail.uid =user_info.uid
GROUP BY sale_detail.app_id,sale_detail.uid,sale_detail.product,sale_detail.order_time,user_info.province,user_info.city;

Contoh 5: Buat tabel dinamis partisi

Untuk dasbor transaksi real-time, seringkali diperlukan tampilan near-real-time data saat ini dan koreksi data historis. Hal ini dapat dicapai dengan kombinasi `Tabel Dinamis` pembaruan bertahap dan penuh. Pendekatannya sebagai berikut:

  1. Buat tabel dasar partisi di mana partisi terbaru ditulis secara real-time/near-real-time, dan partisi historis kadang-kadang dikoreksi.

  2. Buat `Tabel Dinamis` sebagai tabel induk partisi. Gunakan pembaruan bertahap untuk partisi terbaru untuk memenuhi kebutuhan analisis near-real-time.

  3. Alihkan partisi historis ke mode pembaruan penuh. Jika partisi historis tabel sumber telah dikoreksi, partisi `Tabel Dinamis` juga dapat diisi ulang menggunakan pembaruan penuh, sebaiknya dengan Serverless untuk mempercepatnya.

Contoh:

  1. Persiapkan tabel dasar dan data.

    Tabel dasar adalah tabel partisi, dengan partisi terbaru menerima data real-time.

    -- Buat tabel sumber partisi
    CREATE TABLE base_sales(
      uid INT,
      opreate_time TIMESTAMPTZ,
      amount FLOAT,
      tt TEXT NOT NULL,
      ds TEXT,
      PRIMARY KEY(ds)
    ) PARTITION BY LIST (ds) ;
    
    --Partisi historis
    CREATE TABLE base_sales_20240615 PARTITION OF base_sales FOR VALUES IN ('20240615');
    INSERT INTO base_sales_20240615 VALUES (2,'2024-06-15 16:18:25.387466+08','111','2','20240615');
    
    --Partisi terbaru, biasanya untuk tulisan real-time
    CREATE TABLE base_sales_20240616 PARTITION OF base_sales FOR VALUES IN ('20240616');
    INSERT INTO base_sales_20240616 VALUES (1,'2024-06-16 16:08:25.387466+08','2','1','20240616');

  2. Buat tabel induk `Tabel Dinamis` partisi, hanya mendefinisikan kueri tanpa mode refresh.

    --Buat ekstensi
    CREATE EXTENSION roaringbitmap;
    
    CREATE DYNAMIC TABLE partition_dt_base_sales
    PARTITION BY LIST (ds)
    as
    SELECT  
     public.RB_BUILD_AGG(uid),
     opreate_time,
     amount,
     tt,
     ds,
    COUNT(1)
    FROM    base_sales
    GROUP BY opreate_time ,amount,tt,ds;

  3. Buat sub-tabel dan atur mode refresh-nya.

    Anda dapat membuat sub-partisi `Tabel Dinamis` secara manual atau dinamis menggunakan DataWorks. Atur partisi terbaru ke pembaruan bertahap dan partisi historis ke pembaruan penuh.

    -- Aktifkan Binlog untuk tabel dasar
    ALTER TABLE base_sales SET (binlog_level = replica);
    
    -- Asumsikan sub-partisi Tabel Dinamis historis adalah sebagai berikut:
    CREATE DYNAMIC TABLE partition_dt_base_sales_20240615 PARTITION OF partition_dt_base_sales FOR VALUES IN ('20240615')
      WITH (
        refresh_mode='incremental',
        auto_refresh_enable='true',
        incremental_auto_refresh_schd_start_time='immediate',
        incremental_auto_refresh_interval='30 minutes'
           );
    
    -- Buat sub-partisi Tabel Dinamis baru, atur mode refresh-nya ke bertahap, mulai segera, refresh setiap 30 menit, dan gunakan sumber daya instans.
    CREATE DYNAMIC TABLE partition_dt_base_sales_20240616 PARTITION OF partition_dt_base_sales FOR VALUES IN ('20240616')
      WITH (
        refresh_mode='incremental',
        auto_refresh_enable='true',
        incremental_auto_refresh_schd_start_time='immediate',
        incremental_auto_refresh_interval='30 minutes'
           );
    
    --Alihkan partisi historis ke mode pembaruan penuh
    ALTER DYNAMIC TABLE partition_dt_base_sales_20240615 SET (refresh_mode = 'full');
    --Jika data partisi historis perlu dikoreksi, jalankan refresh, sebaiknya dengan serverless.
    SET hg_computing_resource = 'serverless';
    REFRESH DYNAMIC TABLE partition_dt_base_sales_20240615;

Konversi sintaks lama ke sintaks baru

Hologres V3.1 mengubah sintaks pembuatan Tabel Dinamis. Setelah meningkatkan dari V3.0, buat ulang Tabel Dinamis dengan sintaks baru. Alat konversi menyederhanakan proses ini.

Skenario

  • Tabel Dinamis Bertahap harus dibuat ulang dengan sintaks baru.

  • Ketidakcocokan sintaks ditemukan selama pemeriksaan peningkatan. Rujuk laporan pemeriksaan peningkatan Anda untuk detailnya.

Catatan

Kecuali untuk skenario di atas, Tabel Dinamis dari V3.0 tidak memerlukan pembuatan ulang di Hologres V3.1. Namun, hanya ALTER DYNAMIC TABLE yang dapat dilakukan pada mereka. CREATE DYNAMIC TABLE (sintaks lama) tidak didukung di V3.1+.

Batasan

Perintah konversi sintaks hanya berlaku untuk tabel non-partisi (baik Bertahap maupun Pembaruan Penuh). Untuk Tabel Dinamis partisi dari V3.0, buat ulang secara manual.

Lihat Tabel Dinamis yang memerlukan konversi sintaks

Temukan tabel di instans Anda yang perlu dikonversi setelah peningkatan:

Tabel non-partisi

SELECT DISTINCT 
    p.dynamic_table_namespace as table_namespace, 
    p.dynamic_table_name as table_name
FROM hologres.hg_dynamic_table_properties p
JOIN pg_class c ON c.relname = p.dynamic_table_name
JOIN pg_namespace n ON n.oid = c.relnamespace AND n.nspname = p.dynamic_table_namespace
WHERE p.property_key = 'refresh_mode' 
    AND p.property_value = 'incremental'
    AND c.relispartition = false 
    AND c.relkind != 'p';

Tabel partisi

SELECT DISTINCT 
    pn.nspname as parent_schema,
    pc.relname as parent_name
FROM hologres.hg_dynamic_table_properties p
JOIN pg_class c ON c.relname = p.dynamic_table_name
JOIN pg_namespace n ON n.oid = c.relnamespace AND n.nspname = p.dynamic_table_namespace
JOIN pg_inherits i ON c.oid = i.inhrelid
JOIN pg_class pc ON pc.oid = i.inhparent
JOIN pg_namespace pn ON pn.oid = pc.relnamespace
WHERE p.property_key = 'refresh_mode' 
    AND p.property_value = 'incremental'
    AND c.relispartition = true 
    AND c.relkind != 'p';

Lakukan konversi sintaks

Catatan:

  • Persyaratan versi: V3.1.11 dan versi lebih baru.

  • Persyaratan peran: Superuser.

  • Perubahan perilaku pasca-konversi:

    • Refresh otomatis dimulai segera jika mode refresh adalah auto. Pastikan operasi dilakukan selama jam sepi untuk menghindari konflik sumber daya. Untuk isolasi yang lebih baik, gunakan sumber daya Komputasi Tanpa Server.

    • Perubahan penggunaan sumber daya untuk instans gudang virtual:

      • V3.1/V3.2 (sintaks baru): Refresh Tabel Dinamis menggunakan sumber daya dari gudang virtual primer dari Kelompok Tabel tabel dasar dan dinamis.

      • V3.0 (sintaks lama) dan V4.1 (sintaks baru): Refresh Tabel Dinamis menggunakan sumber daya dari gudang virtual primer dari Kelompok Tabel Tabel Dinamis.

    • Sintaks baru menambahkan satu koneksi per Tabel Dinamis untuk penjadwalan. Jika instans Anda memiliki penggunaan koneksi tinggi, bersihkan koneksi idle terlebih dahulu.

Perintah:

-- Hanya untuk tabel non-partisi (penuh dan bertahap).
-- Konversi satu Tabel Dinamis
call hg_dynamic_table_config_upgrade('<table_name>');

-- Konversi semua Tabel Dinamis. Gunakan dengan hati-hati.
call hg_upgrade_all_normal_dynamic_tables();
Catatan

Perintah ini mengonversi Tabel Dinamis (sintaks lama) di database saat ini ke sintaks baru.

Pemetaan parameter sintaks

Perintah memetakan parameter dan nilai V3.0 dan V3.1 sebagai berikut:

Sintaks lama (V3.0)

Sintaks baru (V3.1+)

Deskripsi

refresh_mode

auto_refresh_mode

Nilai parameter dipertahankan setelah konversi. Misalnya, refresh_mode='incremental' menjadi auto_refresh_mode='incremental'.

auto_refresh_enable

auto_refresh_enable

Nilai parameter dipertahankan setelah konversi.

{refresh_mode}_auto_refresh_schd_start_time

freshness

Nilai auto_refresh_interval menjadi nilai freshness.

Misalnya, full_auto_refresh_interval='30 minutes' menjadi freshness='30 minutes'.

{refresh_mode}_auto_refresh_interval

{refresh_mode}_guc_hg_computing_resource

computing_resource

Nilai parameter dipertahankan setelah konversi. Misalnya, full_guc_hg_computing_resource='serverless' menjadi computing_resource='serverless'.

{refresh_mode}guc_hg_experimental_serverless_computing_required_cores

refresh_guc_hg_experimental_serverless_computing_required_cores

Nilai parameter dipertahankan setelah konversi.

{refresh_mode}guc<guc>

refresh_guc<guc_name>

Nilai parameter dipertahankan setelah konversi. Misalnya, incremental_guc_hg_experimental_max_consumed_rows_per_refresh='1000000' menjadi refresh_guc_hg_experimental_max_consumed_rows_per_refresh='1000000'.

Properti tabel (misalnya, orientation)

Properti tabel (misalnya, orientation)

Properti tabel dasar tetap tidak berubah.

Referensi

FAQ

  • T: Bagaimana cara memperbaiki error dengan kunci segmen atau pengelompokan null? Contoh:

    ERROR: commit ddl phase1 failed: the index partition key "xxx" should not be nullable
  • Penyebab: Kunci segmen atau pengelompokan Tabel Dinamis tidak boleh null. Untuk aturan pengaturan kunci ini, lihat Kolom waktu event (kunci segmen).

  • Solusi:

    1. Error kunci pengelompokan: Untuk Hologres sebelum V3.1.26, V3.2.9, V4.0.0, tingkatkan instans Anda dan modifikasi GUC berikut untuk mengizinkan kunci pengelompokan yang bisa null:

      -- Untuk V3.1 dan versi lebih baru
      ALTER DYNAMIC TABLE [ IF EXISTS ] [<schema>.]<table_name> SET
      (refresh_guc_hg_experimental_enable_nullable_segment_key=true);
    2. Error kunci segmen: Jalankan perintah berikut untuk mengizinkan kunci segmen yang bisa null. Mulai Hologres V4.1, kunci segmen secara default diizinkan null, sehingga kami merekomendasikan peningkatan instans Anda untuk memperbaiki error.

      --Untuk V3.1 dan versi lebih baru, mengizinkan kunci pengelompokan yang bisa null
      ALTER DYNAMIC TABLE [ IF EXISTS ] [<schema>.]<table_name> SET
      (refresh_guc_hg_experimental_enable_nullable_clustering_key=true);