All Products
Search
Document Center

Hologres:BUAT TABEL DINAMIS

Last Updated:Jan 06, 2026

Topik ini menjelaskan cara membuat Tabel Dinamis.

Catatan penting

  • Untuk informasi mengenai batasan Tabel Dinamis, lihat Dukungan dan batasan Tabel Dinamis.

  • Mulai Hologres V3.1, Tabel Dinamis baru dibuat menggunakan sintaks baru secara default. Anda tidak dapat lagi menggunakan sintaks V3.0 untuk membuat tabel. Anda hanya dapat melakukan operasi ALTER pada Tabel Dinamis yang sudah ada yang dibuat di V3.0. Untuk tabel non-partisi, Anda dapat menggunakan perintah konversi sintaks untuk mengonversi sintaks V3.0 ke sintaks V3.1 yang baru. Untuk tabel partisi, Anda harus membuat ulang secara manual.

  • Mulai Hologres V3.1, Anda harus membuat ulang Tabel Dinamis dengan refresh inkremental. Anda dapat menggunakan perintah konversi sintaks untuk membangun ulangnya.

  • Mulai Hologres V3.1, mesin secara otomatis mengoptimalkan proses eksekusi refresh untuk Tabel Dinamis, sehingga proses refresh menjadi lebih stabil. Oleh karena itu, wajar jika Anda melihat ID kueri negatif yang terkait dengan operasi refresh.

Sintaks

V3.1 dan versi selanjutnya (sintaks baru)

Catatan

Mulai Hologres V3.1, Anda hanya dapat menggunakan sintaks baru untuk membuat tabel.

Sintaks pembuatan tabel

Mulai Hologres V3.1, Anda dapat menggunakan sintaks berikut untuk membuat Tabel Dinamis:

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. warehouse_name hanya didukung di Hologres V4.0.7 dan versi selanjutnya.
  [refresh_guc_hg_experimental_serverless_computing_required_cores=xxx,]-- Opsional. Spesifikasi sumber daya komputasi.
  
  [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

Deskripsi parameter

Mode refresh dan sumber daya

Parameter

Deskripsi

Wajib

Nilai default

freshness

Kefresh-an data. Satuan dalam menit atau jam. Nilai minimum adalah 1 menit. Mesin secara otomatis menjadwalkan refresh berikutnya berdasarkan waktu refresh terakhir dan nilai freshness yang ditetapkan. Dibandingkan dengan menetapkan interval refresh tetap, freshness memberikan kefresh-an data yang lebih otomatis dan optimal.

Ya

Tidak ada

auto_refresh_mode

Mode refresh. Nilai yang valid:

  • auto: Mode otomatis. Jika kueri mendukung refresh inkremental, maka dijalankan secara inkremental. Jika tidak, beralih ke refresh penuh.

  • incremental: Refresh inkremental. Hanya merefresh data inkremental. Untuk detailnya, lihat Pembaruan bertahap.

  • full: Refresh penuh. Merefresh seluruh data tabel setiap kali. Untuk detailnya, lihat Pembaruan penuh.

Tidak

auto

auto_refresh_enable

Aktifkan atau nonaktifkan auto-refresh. Nilai yang valid:

  • true: Mengaktifkan auto-refresh.

  • false: Menonaktifkan auto-refresh. Setelah dinonaktifkan, semua refresh di masa depan akan berhenti.

Tidak

true

base_table_cdc_format

Metode untuk mengonsumsi perubahan tabel sumber selama refresh inkremental.

  • stream (default): Membaca catatan perubahan data di tingkat file dan menghitung data inkremental. Dibandingkan dengan binlog, metode ini tidak memiliki overhead penyimpanan tambahan dan menawarkan performa lebih baik. Untuk detailnya, lihat Tabel Dinamis.

  • binlog: Mengonsumsi data tabel sumber menggunakan binlog. Setelah menyetel parameter ini, aktifkan binlog secara manual untuk tabel sumber. Untuk detailnya, lihat 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 dari V3.1, semua tabel menggunakan stream secara default untuk mengonsumsi perubahan tabel sumber. Jika sebelumnya Anda mengaktifkan binlog, segera nonaktifkan untuk menghindari biaya penyimpanan yang tidak perlu.

  • Jika tabel sumber berorientasi baris, hanya binlog yang didukung. Stream tidak didukung.

  • Anda tidak dapat mengubah parameter ini setelah pembuatan tabel. Untuk mengubahnya, buat ulang tabel tersebut.

Tidak

stream

computing_resource

Untuk detailnya, lihat deskripsi parameter di Setel sumber daya komputasi untuk refresh Tabel Dinamis.

Tidak

serverless

refresh_guc_<guc_name>

Memungkinkan penyetelan parameter GUC untuk Refresh. Untuk GUC yang didukung, lihat Parameter GUC.

Tidak

Tidak ada

Properti partisi

Parameter partisi logis

Nama parameter

Deskripsi

Wajib

Nilai default

LOGICAL PARTITION BY LIST(<partition_key>)

Membuat Tabel Dinamis berpartisi logis. Anda juga harus menyetel parameter auto_refresh_partition_active_time dan partition_key_time_format untuk menggunakan fitur ini.

Tidak

Tidak ada

auto_refresh_partition_active_time

Rentang refresh untuk partisi. Satuan mencakup menit, jam, dan hari. Sistem secara otomatis merefresh data partisi dalam rentang tersebut, dimulai dari waktu saat ini dan mundur berdasarkan nilai yang ditetapkan.

Partisi aktif: waktu saat ini - waktu mulai partisi (diturunkan dari nama partisi) < auto_refresh_partition_active_time.

Catatan
  • Satuan auto_refresh_partition_active_time harus lebih besar dari satu unit partisi. Misalnya, untuk partisi harian, auto_refresh_partition_active_time harus lebih dari 24 jam.

  • Anda dapat mengubah parameter ini. Perubahan hanya berlaku untuk partisi di masa depan.

Ya

unit waktu partisi + 1 jam,

yang memungkinkan latensi data 1 jam untuk tabel sumber. Misalnya, untuk partisi harian, nilai default-nya adalah 25 jam (1 hari + 1 jam).

partition_key_time_format

Format partisi. Saat Tabel Dinamis merupakan tabel partisi logis, sistem menghasilkan partisi berdasarkan format yang ditentukan. Jenis kunci partisi yang didukung dan format yang sesuai:

  • Kunci partisi TEXT/VARCHAR:

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

  • Kunci partisi INT:

    YYYYMMDDHH24, YYYYMMDD, YYYYMM, YYYY.

  • Kunci partisi DATE:

    YYYY-MM-DD

Ya

Tidak ada

Parameter partisi fisik

Parameter

Deskripsi

Wajib

Nilai default

PARTITION BY LIST(<partition_key>)

Membuat Tabel Dinamis berpartisi standar.

Dibandingkan dengan Tabel Dinamis berpartisi logis, Tabel Dinamis berpartisi standar tidak memiliki kemampuan partisi dinamis dan memiliki batasan penggunaan. Kami merekomendasikan penggunaan partisi logis. Untuk perbedaannya, lihat BUAT TABEL PARTISI LOGIS.

Penting

Mulai dari Hologres V3.1, sintaks baru tidak mendukung pembuatan Tabel Dinamis berpartisi fisik.

Tidak

Tidak ada

Parameter properti tabel

Parameter

Deskripsi

Wajib

Nilai default

penuh

inkremental

col_name

Nama kolom untuk Tabel Dinamis.

Anda dapat secara eksplisit menentukan nama kolom tetapi tidak dapat menentukan atribut kolom atau tipe data. Mesin akan menginferensinya secara otomatis.

Catatan

Menentukan atribut kolom atau tipe data menyebabkan inferensi mesin salah.

Tidak

Nama kolom kueri

Nama kolom kueri

orientation

Menentukan mode penyimpanan untuk Tabel Dinamis. column menunjukkan penyimpanan kolom.

Tidak

column

column

table_group

Menentukan Table Group untuk Tabel Dinamis. Default-nya adalah Table Group Default di database saat ini. Untuk detailnya, lihat Panduan Pengguna Table Group dan Jumlah Shard.

Tidak

Nama Table Group Default

Nama Table Group Default

distribution_key

Menentukan Distribution Key untuk Tabel Dinamis. Untuk detailnya, lihat Distribution Key.

Tidak

Tidak ada

Tidak ada

clustering_key

Menentukan Clustering Key untuk Tabel Dinamis. Untuk detailnya, lihat Clustering Key.

Tidak

Dapat dikonfigurasi dengan nilai default yang diinferensi.

Dapat dikonfigurasi dengan nilai default yang diinferensi.

event_time_column

Menentukan event_time_column untuk Tabel Dinamis. Untuk detailnya, lihat Kolom Waktu Event (Kunci Segmen).

Tidak

Tidak ada

Tidak ada

bitmap_columns

Menentukan bitmap_columns untuk Tabel Dinamis. Untuk detailnya, lihat Indeks Bitmap.

Tidak

Kolom tipe TEXT

Kolom tipe TEXT

dictionary_encoding_columns

Menentukan dictionary_encoding_columns untuk Tabel Dinamis. Untuk detailnya, lihat Encoding Kamus.

Tidak

Kolom tipe TEXT

Kolom tipe TEXT

time_to_live_in_seconds

Menentukan siklus hidup data untuk Tabel Dinamis.

Tidak

Permanen

Permanen

storage_mode

Mode penyimpanan untuk Tabel Dinamis. Nilai yang valid:

  • hot: Penyimpanan hot.

  • cold: Penyimpanan dingin.

Catatan

Untuk detail mode penyimpanan, lihat Penyimpanan tiering data.

Tidak

hot

hot

binlog_level

Menentukan apakah akan mengaktifkan binlog untuk Tabel Dinamis. Untuk penggunaan binlog, lihat Berlangganan Hologres Binlog.

Catatan
  • Parameter ini hanya didukung di V3.1.18 dan versi selanjutnya.

  • Kami tidak merekomendasikan mengaktifkan binlog untuk Tabel Dinamis dengan refresh penuh.

Tidak

none

none

binlog_ttl

Siklus hidup binlog setelah diaktifkan untuk Tabel Dinamis.

Tidak

2592000

2592000

Query

Menentukan kueri yang menghasilkan data untuk Tabel Dinamis. Jenis kueri yang didukung dan jenis tabel sumber bervariasi berdasarkan mode refresh. Untuk informasi lebih lanjut, lihat Dukungan dan batasan Tabel Dinamis.

V3.0

Sintaks pembuatan tabel

Anda dapat menggunakan sintaks berikut untuk membuat Tabel Dinamis di Hologres V3.0:

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 untuk refresh inkremental:
    [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 untuk refresh 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-nya serverless dan dapat disetel di tingkat DB. Pengguna dapat mengabaikan pengaturan ini.
    [full_guc_hg_experimental_serverless_computing_required_cores='<num>',]
    
   -- Parameter bersama. Pengaturan GUC diperbolehkan:
   [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

Deskripsi parameter

Mode refresh dan sumber daya

Kategori parameter

Nama parameter

Deskripsi

Wajib

Nilai default

Parameter pembaruan bersama

refresh_mode

Menentukan mode refresh data. Mendukung mode refresh penuh dan inkremental.

Jika tidak disetel, tidak ada refresh yang terjadi.

Tidak

Tidak ada

auto_refresh_enable

Mengaktifkan atau menonaktifkan auto-refresh. Nilai yang valid:

  • true: Mengaktifkan auto-refresh.

  • false: Menonaktifkan auto-refresh.

Tidak

false

refresh_guc_<guc>

Memungkinkan penyetelan parameter GUC untuk Refresh. Untuk GUC yang didukung, lihat Parameter GUC.

Catatan

Contohnya, untuk menyetel parameter GUC timezone, gunakan refresh_guc_timezone = 'GMT-8:00'.

Tidak

Tidak ada

Refresh inkremental

incremental_auto_refresh_schd_start_time

Waktu mulai untuk refresh inkremental. Nilai yang valid:

  • immediate: Default. Memulai refresh inkremental segera setelah pembuatan tabel.

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

Tidak

immediate

incremental_auto_refresh_interval

Interval waktu untuk refresh inkremental. Satuan: minute, minutes, hour, hours.

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

  • Jika tidak disetel, refresh hanya dijalankan sekali pada waktu mulai.

Tidak

Tidak ada

incremental_guc_hg_computing_resource

Menentukan sumber daya komputasi untuk refresh inkremental. Nilai yang valid:

Catatan

Anda dapat menyetel sumber daya komputasi untuk refresh inkremental di tingkat DB menggunakan ALTER DATABASE xxx SET incremental_guc_hg_computing_resource=xx.

Tidak

local

incremental_guc_hg_experimental_serverless_computing_required_cores

Jika menggunakan sumber daya Serverless untuk refresh, setel sumber daya komputasi yang diperlukan.

Catatan

Spesifikasi instans yang berbeda memiliki batasan sumber daya Serverless. Untuk detailnya, lihat Panduan Pengguna Komputasi Tanpa Server.

Tidak

Tidak ada

Refresh penuh

full_auto_refresh_schd_start_time

Waktu mulai untuk refresh penuh. Nilai yang valid:

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

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

Tidak

immediate

full_auto_refresh_interval

Interval waktu untuk refresh penuh. Satuan: minute, minutes, hour, hours.

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

  • Jika tidak disetel, refresh hanya dijalankan sekali pada waktu mulai.

Tidak

Tidak ada

full_guc_hg_computing_resource

Menentukan sumber daya komputasi untuk refresh penuh. Nilai yang valid:

Catatan

Anda dapat menyetel sumber daya komputasi untuk refresh penuh di tingkat DB menggunakan ALTER DATABASE xxx SET full_guc_hg_computing_resource=xx.

Tidak

local

full_guc_hg_experimental_serverless_computing_required_cores

Jika menggunakan Serverless untuk refresh, setel sumber daya komputasi yang diperlukan.

Catatan

Spesifikasi instans yang berbeda memiliki batasan sumber daya Serverless. Untuk detailnya, lihat Panduan Pengguna Komputasi Tanpa Server.

Tidak

Tidak ada

Parameter properti tabel

Parameter

Deskripsi

Wajib

Nilai default

penuh

inkremental

col_name

Nama kolom untuk Tabel Dinamis.

Anda dapat secara eksplisit menentukan nama kolom tetapi tidak dapat menentukan atribut kolom atau tipe data. Mesin akan menginferensinya secara otomatis.

Catatan

Menentukan atribut kolom atau tipe data menyebabkan inferensi mesin salah.

Tidak

Nama kolom kueri

Nama kolom kueri

orientation

Menentukan mode penyimpanan untuk Tabel Dinamis. column menunjukkan penyimpanan kolom.

Tidak

column

column

table_group

Menentukan Table Group untuk Tabel Dinamis. Default-nya adalah Table Group Default di database saat ini. Untuk detailnya, lihat Panduan Pengguna Table Group dan Jumlah Shard.

Tidak

Nama Grup Tabel Default

Nama Table Group Default

distribution_key

Menentukan Distribution Key untuk Tabel Dinamis. Untuk detailnya, lihat Distribution Key.

Tidak

Tidak ada

Tidak ada

clustering_key

Menentukan Clustering Key untuk Tabel Dinamis. Untuk detailnya, lihat Clustering Key.

Tidak

Dapat dikonfigurasi dengan nilai default yang diinferensi.

Dapat dikonfigurasi dengan nilai default yang diinferensi.

event_time_column

Menentukan event_time_column untuk Tabel Dinamis. Untuk detailnya, lihat Kolom Waktu Event (Kunci Segmen).

Tidak

Tidak ada

Tidak ada

bitmap_columns

Menentukan bitmap_columns untuk Tabel Dinamis. Untuk detailnya, lihat Indeks Bitmap.

Tidak

Kolom tipe TEXT

Kolom tipe TEXT

dictionary_encoding_columns

Menentukan dictionary_encoding_columns untuk Tabel Dinamis. Untuk detailnya, lihat Encoding Kamus.

Tidak

Kolom tipe TEXT

Kolom tipe TEXT

time_to_live_in_seconds

Menentukan siklus hidup data untuk Tabel Dinamis.

Tidak

Permanen

Permanen

storage_mode

Mode penyimpanan untuk Tabel Dinamis. Nilai yang valid:

  • hot: Penyimpanan hot.

  • cold: Penyimpanan cold.

Catatan

Untuk detail mode penyimpanan, lihat Penyimpanan tiering data.

Tidak

hot

hot

PARTITION BY LIST

Menentukan apakah tabel dipartisi. Mendukung pembuatan Tabel Dinamis berpartisi. Penggunaannya sama seperti tabel berpartisi standar. Partisi anak yang berbeda dapat menggunakan mode refresh berbeda untuk memenuhi persyaratan ketepatan waktu bisnis yang bervariasi.

Tidak

Tabel tanpa partisi

Tabel tanpa partisi

Query

Menentukan kueri yang menghasilkan data untuk Tabel Dinamis. Jenis kueri yang didukung dan jenis tabel sumber bervariasi berdasarkan mode refresh. Untuk informasi lebih lanjut, lihat Dukungan dan batasan Tabel Dinamis.

Pembaruan bertahap

Pembaruan bertahap secara otomatis mendeteksi perubahan di tabel sumber dan menulis data kueri secara inkremental ke Tabel Dinamis. Dibandingkan dengan pembaruan penuh, pembaruan bertahap memproses lebih sedikit data dan memberikan ketepatan waktu yang lebih tinggi. Kami merekomendasikan penggunaan pembaruan bertahap untuk kueri near-real-time yang membutuhkan data tingkat menit. Perhatikan poin-poin berikut saat menggunakan Tabel Dinamis dengan refresh inkremental:

  • Batasan pada tabel sumber:

    • Hologres V3.1 menggunakan mode stream secara default untuk mengonsumsi data inkremental. Jika Anda mengaktifkan binlog untuk tabel sumber di V3.0, Anda harus menonaktifkannya untuk mencegah peningkatan biaya penyimpanan.

    • Di V3.0, Anda harus mengaktifkan binlog untuk tabel sumber. Binlog tidak diperlukan untuk tabel dimensi dalam operasi JOIN. Mengaktifkan binlog meningkatkan overhead penyimpanan. Untuk memeriksa penggunaan penyimpanan binlog, lihat Detail penyimpanan tabel.

  • Setelah Anda mengaktifkan refresh inkremental, sistem membuat tabel status di latar belakang untuk mencatat hasil agregasi antara. Untuk informasi teknis lebih lanjut tentang tabel status, lihat Tabel Dinamis. Tabel status menyimpan data agregasi antara dan mengonsumsi sumber daya penyimpanan. Untuk memeriksa penggunaan penyimpanan, lihat Lihat skema dan lineage Tabel Dinamis.

  • Untuk informasi lebih lanjut tentang kueri dan operator yang didukung dalam refresh inkremental, lihat Dukungan dan batasan Tabel Dinamis.

JOIN multi-tabel (dual-stream JOIN)

Dual-stream JOIN adalah jenis JOIN multi-tabel yang menggunakan semantik yang sama dengan kueri online analytical processing (OLAP) dan diimplementasikan menggunakan HASH JOIN. JOIN ini mendukung empat jenis operasi: INNER JOIN, LEFT OUTER JOIN, RIGHT OUTER JOIN, dan FULL OUTER JOIN.

V3.1

Catatan

Mulai Hologres V3.1, parameter Grand Unified Configuration (GUC) untuk dual-stream JOIN diaktifkan secara default. Anda tidak perlu mengonfigurasinya secara manual.

Contoh SQL:

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, muncul satu baris hasil join
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, muncul dua baris hasil join. Pembaruan tabel dimensi diterapkan ke semua data, memperbaiki data yang sebelumnya telah di-join
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

Hologres V3.0.26 dan versi selanjutnya mendukung JOIN multi-tabel (dual-stream JOIN). Anda harus terlebih dahulu meningkatkan instans Anda ke salah satu versi tersebut, lalu menjalankan parameter GUC berikut untuk mengaktifkan dual-stream JOIN.

-- 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 SQL:

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, muncul satu baris hasil join
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, muncul dua baris hasil join. Pembaruan tabel dimensi diterapkan ke semua data, memperbaiki data yang sebelumnya telah di-join
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

Bagian berikut menjelaskan semantik JOIN tabel dimensi: setiap catatan data hanya di-join dengan versi terbaru tabel dimensi pada saat pemrosesan. Jika data di tabel dimensi diubah oleh operasi insert, update, atau delete setelah operasi JOIN dilakukan, data yang sebelumnya telah di-join tidak diperbarui. Contoh SQL berikut menunjukkan ilustrasinya:

Catatan

JOIN tabel dimensi hanya bergantung pada semantik SQL dan bukan pada volume data tabel.

Versi 3.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() menandai users sebagai tabel dimensi
FROM orders LEFT JOIN users FOR SYSTEM_TIME AS OF PROCTIME()
ON orders.user_id = users.user_id;

-- Setelah refresh, muncul satu baris hasil join
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, muncul dua baris hasil join. Pembaruan tabel dimensi hanya diterapkan pada data baru, tidak memperbaiki data yang sebelumnya telah di-join
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() menandai users sebagai tabel dimensi
FROM orders LEFT JOIN users FOR SYSTEM_TIME AS OF PROCTIME()
ON orders.user_id = users.user_id;

-- Setelah refresh, muncul satu baris hasil join
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, muncul dua baris hasil join. Pembaruan tabel dimensi hanya diterapkan pada data baru, tidak memperbaiki data yang sebelumnya telah di-join
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)

  • Refresh inkremental mendukung konsumsi tabel lake Paimon untuk integrasi lakehouse.

  • Anda dapat menggunakan Tabel Dinamis Eksternal untuk operasi baca-tulis inkremental pada data lakehouse dan penulisan balik otomatis ke lake (Paimon). Fitur ini memungkinkan pemrosesan data cepat, percepatan kueri data lake, serta penulisan balik otomatis, sehingga menyederhanakan pemrosesan data lake dan mengurangi biaya. Untuk informasi lebih lanjut, lihat Pengantar Tabel Dinamis Eksternal.

Refresh hibrid penuh-inkremental

Tabel Dinamis inkremental juga mendukung konsumsi hibrid penuh dan inkremental. Proses ini pertama-tama mengonsumsi semua data tabel sumber yang cocok dengan kueri, lalu mengonsumsi data tabel sumber baru.

V3.1

Di V3.1, refresh hibrid penuh dan inkremental diaktifkan secara default. Kode berikut memberikan contohnya:

-- Siapkan tabel sumber dan aktifkan binlog, lalu 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
);

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


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


-- Buat Tabel Dinamis dengan refresh inkremental dan konsumsi hibrid penuh-inkremental diaktifkan
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;

Bandingkan konsistensi data:

  • Kueri tabel sumber

    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

Versi 3.0

Di V3.0, Anda harus mengaktifkan parameter GUC untuk refresh hibrid penuh dan inkremental. Kode berikut memberikan contohnya:

-- Siapkan tabel sumber dan aktifkan binlog, lalu 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
);

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

-- Aktifkan binlog untuk tabel sumber
ALTER TABLE base_sales SET (binlog_level = replica);

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


-- Buat Tabel Dinamis dengan refresh inkremental dan konsumsi hibrid penuh-inkremental diaktifkan
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;

Bandingkan konsistensi data:

  • Kueri tabel sumber

    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

Refresh penuh

Pembaruan penuh menulis semua data kueri ke Tabel Dinamis. Dibandingkan dengan pembaruan bertahap, pembaruan penuh memiliki keunggulan berikut:

  • Dukungan untuk lebih banyak jenis tabel sumber.

  • Dukungan untuk lebih banyak variasi jenis kueri dan operator.

Pembaruan penuh memproses lebih banyak data dan mengonsumsi lebih banyak sumber daya. Direkomendasikan untuk skenario seperti melihat laporan periodik dan melakukan pengisian ulang data terjadwal.

Catatan

Untuk informasi selengkapnya, lihat Pembaruan penuh.

Contoh penggunaan

V3.1

Contoh 1: Buat Tabel Dinamis dengan refresh inkremental

Sebelum menjalankan langkah-langkah berikut, impor dataset publik tpch_10g ke Hologres. Untuk informasi lebih lanjut, lihat Impor satu-klik dataset publik.

Catatan

Sebelum membuat Tabel Dinamis inkremental, Anda harus mengaktifkan binlog untuk tabel sumber. Binlog tidak diperlukan untuk tabel dimensi.

-- Buat Tabel Dinamis inkremental single-table dengan refresh dimulai segera dan dijalankan 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 dengan refresh inkremental JOIN multi-tabel

Sebelum menjalankan langkah-langkah berikut, impor dataset publik tpch_10g ke Hologres. Untuk informasi lebih lanjut, lihat Impor satu-klik dataset publik.

Catatan

Sebelum membuat Tabel Dinamis inkremental, Anda harus mengaktifkan binlog untuk tabel sumber. Binlog tidak diperlukan untuk tabel dimensi.

-- Buat Tabel Dinamis dengan refresh inkremental JOIN multi-tabel
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

Anda dapat menyetel Tabel Dinamis untuk auto-refresh. Mesin secara otomatis memilih mode refresh. Mode refresh inkremental diprioritaskan dan beralih ke refresh penuh jika refresh inkremental tidak didukung.

Sebelum menjalankan langkah-langkah berikut, impor dataset publik tpch_10g ke Hologres. Untuk informasi lebih lanjut, lihat Impor satu-klik dataset publik.

-- Buat Tabel Dinamis dengan auto-refresh. Mesin secara otomatis memilih mode refresh (inkremental dalam kasus ini)
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 berpartisi logis

Dalam skenario seperti dasbor transaksi real-time, Anda mungkin memerlukan tampilan near real-time dari data terkini dan kemampuan untuk memperbaiki data historis. Ini adalah skenario analisis hibrid real-time dan offline. Untuk informasi lebih lanjut, lihat Pemahaman bisnis dan data. Anda dapat menggunakan Tabel Dinamis berpartisi logis untuk tujuan ini:

  • Tabel sumber dipartisi berdasarkan hari. Partisi terbaru menerima tulisan real-time atau near real-time dari Flink. Partisi historis menerima data dari MaxCompute.

  • Tabel Dinamis menggunakan partisi logis. Dua partisi terbaru aktif dan menggunakan refresh inkremental untuk analitik near real-time.

  • Partisi historis tidak aktif dan menggunakan refresh penuh. Jika data sumber historis diperbaiki atau diisi ulang, Anda dapat menggunakan refresh penuh untuk partisi historis tersebut.

Contoh ini menggunakan dataset publik GitHub.

  1. Siapkan tabel dasar.

    Data terbaru ditulis secara real-time oleh Flink. Untuk informasi lebih lanjut, lihat Praktik terpadu offline dan real-time menggunakan dataset event publik 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 'Actor ID';
    COMMENT ON COLUMN public.gh_realtime_data.actor_login IS 'Nama login Actor';
    COMMENT ON COLUMN public.gh_realtime_data.repo_id IS 'Repo ID';
    COMMENT ON COLUMN public.gh_realtime_data.repo_name IS 'Nama Repo';
    COMMENT ON COLUMN public.gh_realtime_data.org_id IS 'Organization ID';
    COMMENT ON COLUMN public.gh_realtime_data.org_login IS 'Nama Organization';
    COMMENT ON COLUMN public.gh_realtime_data.type IS 'Jenis Event';
    COMMENT ON COLUMN public.gh_realtime_data.created_at IS 'Waktu kejadian Event';
    COMMENT ON COLUMN public.gh_realtime_data.action IS 'Perilaku Event';
    COMMENT ON COLUMN public.gh_realtime_data.iss_or_pr_id IS 'ID Issue/pull request';
    COMMENT ON COLUMN public.gh_realtime_data.number IS 'Nomor Issue/pull request';
    COMMENT ON COLUMN public.gh_realtime_data.comment_id IS 'ID Komentar';
    COMMENT ON COLUMN public.gh_realtime_data.commit_id IS 'ID Commit';
    COMMENT ON COLUMN public.gh_realtime_data.member_id IS 'ID Anggota';
    COMMENT ON COLUMN public.gh_realtime_data.rev_or_push_or_rel_id IS 'ID Review/push/release';
    COMMENT ON COLUMN public.gh_realtime_data.ref IS 'Nama resource yang dibuat/dihapus';
    COMMENT ON COLUMN public.gh_realtime_data.ref_type IS 'Jenis resource yang dibuat/dihapus';
    COMMENT ON COLUMN public.gh_realtime_data.state IS 'Status issue/pull request/review';
    COMMENT ON COLUMN public.gh_realtime_data.author_association IS 'Hubungan antara actor dan repo';
    COMMENT ON COLUMN public.gh_realtime_data.language IS 'Bahasa pemrograman';
    COMMENT ON COLUMN public.gh_realtime_data.merged IS 'Apakah digabung';
    COMMENT ON COLUMN public.gh_realtime_data.merged_at IS 'Waktu penggabungan';
    COMMENT ON COLUMN public.gh_realtime_data.additions IS 'Baris ditambahkan';
    COMMENT ON COLUMN public.gh_realtime_data.deletions IS 'Baris dihapus';
    COMMENT ON COLUMN public.gh_realtime_data.changed_files IS 'File yang diubah dalam pull request';
    COMMENT ON COLUMN public.gh_realtime_data.push_size IS 'Jumlah push';
    COMMENT ON COLUMN public.gh_realtime_data.push_distinct_size IS 'Jumlah push berbeda';
    COMMENT ON COLUMN public.gh_realtime_data.hr IS 'Jam kejadian event (misalnya, 00 untuk 00:23)';
    COMMENT ON COLUMN public.gh_realtime_data.month IS 'Bulan kejadian event (misalnya, 2015-10 untuk Oktober 2015)';
    COMMENT ON COLUMN public.gh_realtime_data.year IS 'Tahun kejadian event (misalnya, 2015)';
    COMMENT ON COLUMN public.gh_realtime_data.ds IS 'Tanggal kejadian event (yyyy-mm-dd)';
    
    COMMIT;
  2. Buat Tabel Dinamis berpartisi 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 sumber berubah—misalnya, data untuk 2025-04-01 diperbarui—Anda dapat menyinkronkan Tabel Dinamis dengan menyetel partisi historis ke mode refresh penuh dan menjalankan refresh menggunakan Serverless.

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

Contoh 5: Hitung UV periode panjang apa pun menggunakan refresh inkremental

Mulai Hologres V3.1, Tabel Dinamis dengan refresh inkremental mendukung fungsi RB_BUILD_AGG untuk menghitung unique visitors (UV) periode panjang. Dibandingkan dengan pre-agregasi, refresh inkremental memberikan manfaat berikut:

  • Performa lebih baik: hanya data inkremental yang dihitung pada setiap refresh.

  • Biaya lebih rendah: lebih sedikit data diproses, sehingga mengurangi penggunaan sumber daya komputasi dan memungkinkan perhitungan periode lebih panjang.

Contoh:

  1. Siapkan 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');
    -- Set distribution_key berdasarkan kebutuhan kueri real-time
    CALL set_table_property('ods_app_detail', 'distribution_key', 'uid');
    -- Set clustering_key dan event_time_column untuk filter WHERE dengan field tanggal-waktu lengkap
    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 refresh inkremental.

    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 periode apa pun.

    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 dengan refresh penuh dan mulai merefresh segera

Sebelum menjalankan langkah-langkah berikut, impor dataset publik tpch_10g ke Hologres. Untuk informasi lebih lanjut, lihat Impor satu-klik dataset publik.

-- Buat skema "test"
CREATE SCHEMA test;

-- Buat Tabel Dinamis single-table dengan refresh penuh, mulai merefresh segera, dan refresh 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 dengan refresh inkremental dan waktu mulai kustom

Sebelum menjalankan langkah-langkah berikut, impor dataset publik tpch_10g ke Hologres. Untuk informasi lebih lanjut, lihat Impor satu-klik dataset publik.

Contoh berikut menunjukkan cara membuat Tabel Dinamis dengan refresh inkremental:

Catatan

Sebelum membuat Tabel Dinamis inkremental, Anda harus mengaktifkan binlog untuk tabel sumber. Binlog tidak diperlukan untuk tabel dimensi.

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

-- Buat Tabel Dinamis single-table dengan refresh inkremental, mulai merefresh pada waktu kustom, dan refresh setiap 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 JOIN multi-tabel dengan refresh penuh

-- Buat Tabel Dinamis JOIN multi-tabel dengan mode refresh penuh, merefresh 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: Membuat tabel dimensi JOIN Dynamic Table yang diperbarui secara inkremental

Contoh: Menggabungkan tabel dimensi dengan Tabel Dinamis dengan refresh inkremental:

Catatan

Sebelum membuat Tabel Dinamis inkremental, Anda harus mengaktifkan binlog untuk tabel sumber. Binlog tidak diperlukan untuk tabel dimensi.

Semantik JOIN tabel dimensi: setiap catatan data hanya di-join dengan versi terbaru tabel dimensi pada saat pemrosesan. Jika data di tabel dimensi berubah setelah operasi JOIN, data yang sebelumnya telah di-join tidak diperbarui. Berikut adalah contoh pernyataan 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 sumber (tabel dimensi tidak memerlukannya)
CALL set_table_property('public.sale_detail', 'binlog.level', 'replica');
COMMIT;

-- Tabel atribut
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 skenario seperti dasbor transaksi real-time, Anda mungkin memerlukan tampilan near real-time dari data terkini dan dukungan untuk koreksi data historis. Dalam hal ini, Anda dapat menggunakan refresh inkremental dan refresh penuh untuk Tabel Dinamis:

  1. Buat tabel sumber berpartisi. Data ditulis ke partisi terbaru secara real-time atau near real-time. Koreksi data kadang-kadang dilakukan pada partisi historis.

  2. Buat Tabel Dinamis sebagai tabel partisi induk. Gunakan refresh inkremental untuk partisi terbaru guna memenuhi kebutuhan analitik near real-time.

  3. Alihkan partisi historis ke mode refresh penuh. Jika data di partisi sumber historis diperbaiki atau diisi ulang, Anda dapat merefresh partisi Tabel Dinamis historis yang sesuai menggunakan refresh penuh. Anda dapat menggunakan Serverless untuk mempercepat proses pengisian ulang.

Contoh:

  1. Siapkan tabel sumber dan data.

    Tabel sumber dipartisi. Data ditulis ke partisi terbaru secara real-time.

    -- Buat tabel sumber berpartisi
    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 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 partisi induk untuk Tabel Dinamis. Pada langkah ini, Anda hanya perlu mendefinisikan kueri dan tidak perlu menyetel 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 tabel anak dan setel mode refresh-nya.

    Anda dapat membuat tabel anak untuk partisi Tabel Dinamis secara manual atau menggunakan DataWorks untuk membuatnya secara dinamis. Gunakan refresh inkremental untuk partisi terbaru dan refresh penuh untuk partisi historis.

    -- Aktifkan binlog untuk tabel sumber
    ALTER TABLE base_sales SET (binlog_level = replica);
    
    -- Asumsikan tabel anak partisi Tabel Dinamis historis sudah ada:
    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 tabel anak partisi Tabel Dinamis baru dengan refresh inkremental untuk partisi terbaru, mulai segera dengan interval 30 menit menggunakan 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 refresh penuh
    ALTER DYNAMIC TABLE partition_dt_base_sales_20240615 SET (refresh_mode = 'full');
    -- Jika partisi historis memerlukan koreksi data, jalankan refresh. Gunakan Serverless untuk performa lebih baik
    SET hg_computing_resource = 'serverless';
    REFRESH DYNAMIC TABLE partition_dt_base_sales_20240615;

Perintah konversi sintaks

Sintaks Tabel Dinamis ditingkatkan di Hologres V3.1. Jika Anda meningkatkan dari V3.0, Anda harus membuat ulang tabel menggunakan sintaks V3.1. Untuk menyederhanakan proses ini, Hologres menyediakan alat konversi sintaks.

Skenario yang memerlukan pembuatan ulang tabel

  • Tabel dinamis yang menggunakan refresh inkremental harus dibuat ulang.

  • Jika ditemukan ketidakcocokan sintaks selama pemeriksaan peningkatan, Anda harus membuat ulang tabel sesuai yang ditentukan dalam laporan peningkatan.

Catatan

Tabel dinamis yang menggunakan sintaks V3.0 tidak perlu dibuat ulang kecuali jika termasuk dalam skenario yang dijelaskan di atas. Namun, Anda hanya dapat menjalankan operasi ALTER pada tabel-tabel tersebut. Anda tidak dapat menggunakan sintaks V3.0 untuk membuat tabel baru.

Skenario yang berlaku untuk perintah konversi sintaks

Perintah konversi sintaks hanya berlaku untuk tabel non-partisi yang menggunakan mode refresh inkremental atau penuh. Anda harus membuat ulang secara manual tabel dinamis berpartisi yang menggunakan sintaks V3.0. Kami merekomendasikan penggunaan partisi logis saat membuat ulang tabel-tabel tersebut.

Lihat tabel yang memerlukan konversi

Anda dapat menjalankan perintah berikut untuk melihat tabel yang memerlukan konversi 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';

Menggunakan perintah konversi sintaks

Sebelum menggunakan perintah konversi sintaks, perhatikan informasi berikut:

  • Perintah ini hanya didukung di Hologres V3.1.11 dan versi selanjutnya.

  • Anda harus memiliki hak istimewa Superuser untuk menjalankan perintah ini.

  • Setelah menjalankan perintah, perubahan berikut terjadi:

    • Jika auto-refresh diaktifkan, tugas refresh dimulai segera. Kami merekomendasikan menjalankan perintah selama jam sepi untuk menghindari konflik sumber daya. Anda dapat menggunakan instans Serverless untuk mengisolasi tugas refresh.

    • Penggunaan sumber daya berubah:

      • Jika Anda menggunakan sintaks baru (V3.1 dan V3.2) pada instans compute group, sumber daya warehouse dialokasikan dari warehouse leader TG tabel sumber dan TG tabel dinamis.

      • Jika Anda menggunakan sintaks lama (V3.0) atau sintaks baru pada instans V4.1, sumber daya warehouse dialokasikan dari warehouse leader TG tabel dinamis.

    • Jumlah koneksi berubah. Sintaks baru menggunakan mekanisme penjadwalan yang lebih stabil dan efisien, sehingga menyebabkan setiap tabel dinamis menggunakan satu koneksi tambahan. Jika instans Anda memiliki penggunaan koneksi tinggi dan banyak tabel dinamis (misalnya, ratusan), kami merekomendasikan membersihkan koneksi idle sebelum menjalankan perintah.

Perintah konversi:

-- Hanya berlaku untuk tabel non-partisi (refresh penuh dan inkremental). Buat ulang tabel berpartisi secara manual dan pertimbangkan penggunaan partisi logis.
-- Konversi satu tabel
call hg_dynamic_table_config_upgrade('<table_name>');

-- Konversi batch semua tabel. Gunakan dengan hati-hati.
call hg_upgrade_all_normal_dynamic_tables();
Catatan

Perintah ini mengonversi semua tabel dinamis yang menggunakan sintaks V3.0 di database saat ini untuk menggunakan sintaks V3.1.

Pemetaan parameter sintaks

Tabel berikut menunjukkan bagaimana parameter V3.0 dan V3.1 dipetakan saat Anda menggunakan perintah konversi sintaks.

Nama Parameter V3.0

Parameter V3.1

Deskripsi

refresh_mode

auto_refresh_mode

Nilai tetap tidak berubah. Contoh: refresh_mode='incremental' menjadi auto_refresh_mode='incremental'.

auto_refresh_enable

auto_refresh_enable

Nilai tetap tidak berubah.

{refresh_mode}_auto_refresh_schd_start_time

freshness

Nilai auto_refresh_interval dikonversi menjadi freshness.

Contoh: full_auto_refresh_interval='30 minutes' menjadi freshness='30 minutes'.

{refresh_mode}_auto_refresh_interval

{refresh_mode}_guc_hg_computing_resource

computing_resource

Nilai tetap tidak berubah. Contoh: 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 tetap tidak berubah.

{refresh_mode}_guc_<guc>

refresh_guc_<guc_name>

Nilai tetap tidak berubah. Contoh:

incremental_guc_hg_experimental_max_consumed_rows_per_refresh='1000000' menjadi refresh_guc_hg_experimental_max_consumed_rows_per_refresh='1000000' .

orientation dan properti tabel lainnya

orientation dan properti tabel lainnya

Semua properti tabel dasar tetap tidak berubah.

Langkah selanjutnya: Kelola Tabel Dinamis

Setelah membuat Tabel Dinamis, Anda dapat melakukan operasi berikut:

FAQ

  • Masalah: Terjadi error jika Kunci Segmen atau Kunci Pengelompokan kosong. Berikut contoh error-nya:

    ERROR: commit ddl phase1 failed: the index partition key "xxx" should not be nullable
  • Penyebab: Error ini terjadi karena kolom yang ditentukan sebagai Kunci Segmen atau Kunci Pengelompokan untuk tabel dinamis tidak boleh berisi nilai null. Untuk informasi lebih lanjut tentang aturan Kunci Segmen dan Kunci Pengelompokan, lihat Kolom Waktu Event (Kunci Segmen).

  • Solusi:

    1. Jika error terkait Kunci Pengelompokan, error ini tidak terjadi untuk tabel yang dibuat di Hologres V3.1.26, V3.2.9, V4.0.0, atau versi selanjutnya. Untuk versi sebelumnya, tingkatkan instans Anda dan jalankan GUC berikut untuk mengizinkan Kunci Pengelompokan yang dapat bernilai null.

      -- Sintaks V3.1+ untuk mengizinkan kunci segmen yang dapat bernilai null
      ALTER DYNAMIC TABLE [ IF EXISTS ] [<schema>.]<table_name> SET
      (refresh_guc_hg_experimental_enable_nullable_segment_key=true);
    2. Jika error terkait Kunci Segmen, jalankan GUC berikut untuk mengizinkan Kunci Segmen yang dapat bernilai null. Kunci Segmen dapat bernilai null di Hologres V4.1 dan versi selanjutnya. Kami merekomendasikan peningkatan instans Anda.

      -- Sintaks V3.1+ untuk mengizinkan kunci pengelompokan yang dapat bernilai null
      ALTER DYNAMIC TABLE [ IF EXISTS ] [<schema>.]<table_name> SET
      (refresh_guc_hg_experimental_enable_nullable_clustering_key=true);