Buat Dynamic Table yang secara otomatis merefresh hasil kueri dari tabel dasar menggunakan incremental refresh atau full refresh.
Catatan penting
-
Batasan penggunaan Dynamic Table: Dukungan dan batasan Dynamic Table.
-
Hologres V3.1 dan versi lebih baru hanya mendukung sintaks baru untuk membuat Dynamic Table. Anda masih dapat melakukan operasi ALTER pada tabel yang dibuat dengan sintaks V3.0, tetapi tidak dapat membuat yang baru. Untuk tabel non-partisi, gunakan 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 Incremental Dynamic Table 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)
V3.1+ hanya mendukung sintaks baru.
Sintaks Create Dynamic Table
Sintaks untuk membuat Dynamic Table di V3.1+:
CREATE DYNAMIC TABLE [ IF NOT EXISTS ] [<schema_name>.]<table_name>
[ (<col_name> [, ...] ) ]
[LOGICAL PARTITION BY LIST(<partition_key>)]
WITH (
-- Properti Dynamic Table
freshness = {'<num> {minutes | hours}' | 'upstream'}, -- 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 dibutuhkan 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 Penyegaran dan Sumber Daya
|
Parameter |
Deskripsi |
Wajib |
Default |
|
|
Tingkat kesegaran data target dalam menit atau jam. Minimum: 1 menit. Mesin menjadwalkan refresh berdasarkan waktu refresh sebelumnya dan nilai
|
Ya |
Tidak ada |
|
|
Mode refresh. Nilai yang valid:
|
Tidak |
auto |
|
|
Mengaktifkan atau menonaktifkan refresh otomatis. Nilai yang valid:
|
Tidak |
true |
|
|
Cara mengonsumsi perubahan data tabel dasar selama incremental refresh.
Catatan
|
Tidak |
stream |
|
|
Sumber daya komputasi untuk refresh. Nilai yang valid:
|
Tidak |
serverless |
|
|
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 |
|
|
Membuat Dynamic Table partisi logis. Memerlukan |
Tidak |
Tidak ada |
|
|
Lingkup refresh untuk partisi, dalam menit, jam, atau hari. Hologres melacak 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 Catatan
|
Ya |
Default ke 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). |
|
|
Format nama partisi. Nilai yang valid:
|
Ya |
Tidak ada |
Tabel partisi fisik
|
Parameter |
Deskripsi |
Wajib |
Default |
|
|
Membuat Dynamic Table partisi fisik. Dynamic Table 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 Dynamic Table sebagai tabel partisi fisik. |
Tidak |
Tidak ada |
Properti tabel
|
Parameter |
Deskripsi |
Wajib |
Nilai default |
|
|
Full Refresh Mode |
Incremental Refresh Mode |
|||
|
|
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 |
|
|
Format penyimpanan. |
Tidak |
|
|
|
|
Kelompok Tabel. Default ke kelompok default database saat ini. Untuk informasi lebih lanjut, lihat Mengelola kelompok tabel dan shard. |
Tidak |
Nama Kelompok Tabel default |
Nama Kelompok Tabel default |
|
|
Kunci distribusi. Untuk informasi lebih lanjut, lihat Kunci distribusi. |
Tidak |
(tidak ada) |
(tidak ada) |
|
|
Kunci pengelompokan. Untuk informasi lebih lanjut, lihat Kunci pengelompokan. |
Tidak |
Diizinkan, dengan nilai default yang diinferensi. |
Diizinkan, dengan nilai default yang diinferensi. |
|
|
Tidak |
(tidak ada) |
(tidak ada) |
|
|
|
Kolom bitmap. Untuk informasi lebih lanjut, lihat Indeks bitmap. |
Tidak |
Bidang tipe TEXT |
Bidang tipe TEXT |
|
|
Lihat Encoding kamus. |
Tidak |
Bidang tipe TEXT |
Bidang tipe TEXT |
|
|
TTL data. |
Tidak |
Tidak kedaluwarsa |
Tidak kedaluwarsa |
|
|
Tingkat penyimpanan. Nilai yang valid:
Catatan
Untuk detail, lihat Menyiapkan tiering penyimpanan. |
Tidak |
|
|
|
|
Mengaktifkan binlog untuk Dynamic Table. Subscribe to Hologres Binlog. Catatan
|
Tidak |
|
|
|
|
TTL binlog. |
Tidak |
|
|
Refresh kaskade
Hologres V5.0 dan versi lebih baru mendukung refresh kaskade. Ketika tabel dasar dari dynamic table mencakup dynamic table lain, Anda dapat mengatur freshness-nya ke 'upstream' sehingga tabel tersebut direfresh secara otomatis setelah dynamic table hulunya selesai merefresh, membentuk rantai refresh kaskade. Pendekatan ini cocok untuk skenario gudang data multi-lapis: atur nilai freshness eksplisit hanya pada akar rantai dan atur setiap lapisan hilir ke 'upstream'. Data kemudian mengalir lapis demi lapis tanpa interval refresh untuk setiap lapisan dan tanpa penjadwal eksternal untuk mengatur dependensi.
Contoh
-- Akar: direfresh dengan freshness tetap.
CREATE DYNAMIC TABLE dwd_orders
WITH (
auto_refresh_mode = 'incremental',
freshness = '5 minutes'
)
AS SELECT order_id, user_id, ds, amount FROM ods_orders;
-- Lapisan kedua: dipicu setelah dwd_orders direfresh.
CREATE DYNAMIC TABLE dws_user_amount
WITH (
auto_refresh_mode = 'incremental',
freshness = 'upstream'
)
AS SELECT user_id, ds, SUM(amount) AS amt FROM dwd_orders GROUP BY user_id, ds;
-- Lapisan ketiga: dipicu setelah dws_user_amount direfresh.
CREATE DYNAMIC TABLE ads_daily_amount
WITH (
auto_refresh_mode = 'incremental',
freshness = 'upstream'
)
AS SELECT ds, SUM(amt) AS amt FROM dws_user_amount GROUP BY ds;
Untuk memantau rantai kaskade, kueri hologres.hg_dynamic_table_refresh_history. Refresh yang dipicu oleh tabel hulu dicatat dengan tipe pemicu cascade.
SELECT dynamic_table_name, refresh_type, status, refresh_start
FROM hologres.hg_dynamic_table_refresh_history
WHERE schema_name = '<SCHEMA_NAME>'
ORDER BY refresh_start;
Perilaku pemicu
-
Pemicu menyebar satu level per satu waktu: ketika dynamic table hulu selesai merefresh, ia memicu tabel hilir langsungnya, dan masing-masing memicu level berikutnya setelah selesai. Tabel hulu tidak pernah memicu cucu langsung. Dalam rantai A ke B ke C, C dipicu oleh B, bukan oleh A.
-
Tabel hulu mengembalikan respons segera setelah refresh-nya sendiri selesai dan tidak menunggu refresh hilir. Hal yang sama berlaku untuk
REFRESH DYNAMIC TABLEmanual: pernyataan mengembalikan respons ketika tabel saat ini direfresh, dan refresh hilir berjalan secara asinkron setelahnya. Untuk mengontrol apakah refresh manual memicu tabel hilir, gunakan parametercascading. Untuk informasi lebih lanjut, lihat Refresh dynamic table. -
Ketika dynamic table memiliki beberapa dynamic table hulu, refresh sukses dari salah satu tabel hulu memicu satu refresh tabel ini tanpa menunggu tabel hulu lainnya. Akibatnya, tabel ini mungkin menggabungkan data terbaru dari beberapa tabel hulu dengan data lama dari yang lain. Ini adalah perilaku yang diharapkan untuk refresh kaskade. Jika bisnis Anda memerlukan semua data hulu selaras, jangan mengandalkan pemicu kaskade. Refresh tabel secara manual setelah semua data hulu siap.
Kueri
Kueri yang mendefinisikan data Dynamic Table. Kueri yang didukung dan tabel dasar bervariasi berdasarkan mode refresh. Untuk informasi lebih lanjut, lihat Dukungan dan batasan Dynamic Table.
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 incremental refresh:
[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 full refresh:
[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 Dynamic Table 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 |
|
Mode refresh. Nilai yang valid: Jika tidak diatur, tidak ada refresh yang dilakukan. |
Tidak |
(tidak ada) |
|
|
Mengaktifkan atau menonaktifkan refresh otomatis. Nilai yang valid:
|
Tidak |
false |
|
|
|
Atur parameter GUC untuk refresh. Untuk daftar GUC yang didukung, lihat Parameter GUC. Catatan
Contohnya, untuk mengatur GUC timezone, gunakan |
Tidak |
(tidak ada) |
|
|
Incremental refresh |
|
Waktu mulai untuk incremental refresh. Nilai yang valid:
|
Tidak |
immediate |
|
|
Interval incremental refresh, dalam menit atau jam.
|
Tidak |
(tidak ada) |
|
|
|
Sumber daya komputasi untuk incremental refresh. Nilai yang valid:
Catatan
Untuk mengatur sumber daya komputasi di tingkat DB, jalankan |
Tidak |
local |
|
|
|
Core Serverless Computing untuk refresh. Catatan
Kuota sumber daya Serverless Computing bervariasi berdasarkan spesifikasi instans. Untuk informasi lebih lanjut, lihat Mengelola sumber daya komputasi tanpa server. |
Tidak |
(tidak ada) |
|
|
Full refresh |
|
Waktu mulai untuk full refresh. Nilai yang valid:
|
Tidak |
immediate |
|
|
Interval full refresh, dalam menit atau jam.
|
Tidak |
(tidak ada) |
|
|
|
Sumber daya komputasi untuk full refresh. Nilai yang valid:
Catatan
Untuk mengatur sumber daya komputasi di tingkat DB, jalankan |
Tidak |
local |
|
|
|
Core Serverless Computing untuk refresh. Catatan
Kuota sumber daya Serverless Computing bervariasi berdasarkan spesifikasi instans. Untuk informasi lebih lanjut, lihat Mengelola sumber daya komputasi tanpa server. |
Tidak |
(tidak ada) |
Properti tabel
|
Parameter |
Deskripsi |
Wajib |
Default |
|
|
full |
incremental |
|||
|
|
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 |
|
|
Format penyimpanan untuk Dynamic Table. |
Tidak |
|
|
|
|
Kelompok Tabel. Default ke kelompok default database saat ini. Untuk informasi lebih lanjut, lihat Mengelola kelompok tabel dan shard. |
Tidak |
Nama Kelompok Tabel default |
Nama Kelompok Tabel default |
|
|
Kunci distribusi. Untuk informasi lebih lanjut, lihat Kunci distribusi. |
Tidak |
(tidak ada) |
(tidak ada) |
|
|
Kunci pengelompokan. Untuk informasi lebih lanjut, lihat Kunci pengelompokan. |
Tidak |
Diizinkan, dengan nilai default yang diinferensi. |
Diizinkan, dengan nilai default yang diinferensi. |
|
|
Kunci segmen. Untuk informasi lebih lanjut, lihat Kolom waktu event (kunci segmen). |
Tidak |
(tidak ada) |
(tidak ada) |
|
|
Kolom bitmap. Untuk informasi lebih lanjut, lihat Indeks bitmap. |
Tidak |
Bidang tipe TEXT |
Bidang tipe TEXT |
|
|
Lihat Encoding kamus. |
Tidak |
Bidang tipe TEXT |
Bidang tipe TEXT |
|
|
TTL data. |
Tidak |
Tidak kedaluwarsa |
Tidak kedaluwarsa |
|
|
Tingkat penyimpanan. Nilai yang valid:
Catatan
|
Tidak |
|
|
|
|
Membuat Dynamic Table partisi. Partisi dapat menggunakan mode refresh berbeda untuk kebutuhan freshness yang bervariasi. |
Tidak |
Tabel non-partisi |
Tabel non-partisi |
Kueri
Kueri yang menghasilkan data Dynamic Table. Kueri yang didukung dan tipe tabel dasar bervariasi berdasarkan mode refresh. Dukungan dan batasan Dynamic Table.
Incremental refresh
Incremental refresh mendeteksi perubahan pada tabel dasar dan hanya menulis delta ke Dynamic Table, 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 incremental refresh, Hologres menghasilkan tabel status di latar belakang untuk mencatat hasil agregasi antara (lihat Dynamic tables untuk detail). Tabel status juga mengonsumsi ruang penyimpanan. Untuk melihat penggunaan penyimpanan, lihat Lihat skema dan lineage dynamic table.
-
Kueri dan operator yang didukung untuk incremental refresh: Dukungan dan batasan Dynamic Table.
-
Ketika Anda menjalankan incremental refresh untuk pertama kali, 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 Serverless Computing untuk menjalankannya. Untuk informasi lebih lanjut, lihat Gunakan Serverless Computing untuk pembacaan dan penulisan 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
Mulai dari 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 catatan 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 catatan yang digabung terlihat. Pembaruan tabel dimensi memengaruhi semua data dan dapat memperbaiki catatan 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 catatan 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 catatan yang digabung terlihat. Pembaruan tabel dimensi memengaruhi semua data dan dapat memperbaiki catatan 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 catatan stream digabung dengan snapshot terbaru tabel dimensi pada waktu pemrosesan. Perubahan pada tabel dimensi setelah JOIN tidak memengaruhi data yang sudah diproses.
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 catatan 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 catatan yang digabung terlihat. Pembaruan tabel dimensi hanya memengaruhi data baru dan tidak dapat memperbaiki 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 catatan 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 catatan yang digabung terlihat. Pembaruan tabel dimensi hanya memengaruhi data baru dan tidak dapat memperbaiki 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)
Batasan
Kolom yang diperoleh dari join tabel dimensi bersifat non-deterministik: nilainya bergantung pada baris tabel fakta saat ini dan isi tabel dimensi pada waktu pemrosesan. Dalam hal ini, berperilaku seperti fungsi non-deterministik NOW() dan RAND(). Kami menyarankan Anda hanya menggunakan kolom tersebut dalam daftar proyeksi SELECT. Menggunakannya di tempat lain dapat menyebabkan error refresh atau hasil yang tidak terduga.
|
Lokasi penggunaan |
Diizinkan |
|
SELECT projection list |
Ya |
|
Argumen fungsi agregat, seperti |
Ya, tetapi tidak disarankan. Ketika retraction memicu recomputation, nilai dari tabel dimensi mungkin sudah berubah, yang dapat menghasilkan hasil tak terduga. |
|
GROUP BY kunci |
Tidak |
|
Predikat WHERE |
Tidak |
|
Kondisi ON dari JOIN hilir |
Tidak |
|
Klausa PARTITION BY dari fungsi jendela |
Tidak |
Jika logika bisnis Anda memerlukan pengelompokan atau penyaringan berdasarkan kolom tabel dimensi, gunakan join stream-stream sebagai gantinya. Perubahan pada tabel dimensi kemudian akan memicu retraction dan recomputation data historis, yang menjaga hasil tetap benar.
Namun, join stream-stream harus mempertahankan status JOIN, sehingga mengonsumsi lebih banyak sumber daya ketika tabel dimensi besar. Perubahan massal pada tabel dimensi juga dapat memicu recomputation hilir yang luas.
Konsumsi inkremental tabel lake Paimon
-
Incremental refresh mendukung konsumsi tabel Paimon untuk skenario lakehouse.
-
Dynamic Table eksternal mendukung pembacaan inkremental dan write-back, mengurangi biaya pemrosesan dan latensi kueri. Pengantar Dynamic Table eksternal.
Konsumsi hibrid
Dynamic Table Inkremental mendukung model hibrid: pemuatan penuh awal dari semua data tabel dasar yang ada, diikuti oleh pemrosesan inkremental berkelanjutan.
V3.1
V3.1 mengaktifkan model refresh hibrid secara default. Contoh:
--Siapkan 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 Dynamic Table Inkremental
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 Dynamic Table
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 hibrid, aktifkan secara manual GUC incremental_guc_hg_experimental_enable_hybrid_incremental_mode. Contoh:
--Siapkan 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 Dynamic Table Inkremental dengan auto-refresh dan aktifkan GUC untuk konsumsi hibrid
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 Dynamic Table
SELECT * FROM sales_incremental;Hasil:
day hour sum count 2024-08-29 1 5 1 2024-08-29 2 100 1
Full refresh
Full refresh menulis ulang seluruh dataset dari kueri. Dibandingkan dengan incremental refresh:
-
Mendukung lebih banyak tipe tabel dasar.
-
Mendukung lebih banyak tipe kueri dan operator.
Full refresh menggunakan lebih banyak sumber daya. Paling cocok untuk pelaporan periodik dan pengisian ulang data.
Untuk informasi lebih lanjut, lihat Full refresh.
Contoh
V3.1
Contoh 1: Membuat Incremental Dynamic Table reguler
Sebelum melanjutkan, impor dataset publik tpch_10g ke Hologres dengan mengikuti panduan di Impor dataset publik dengan beberapa klik.
Sebelum membuat Incremental Dynamic Table, aktifkan Binlog untuk tabel dasar (tidak diperlukan untuk tabel dimensi).
-- Buat Incremental Dynamic Table yang merefresh 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 Incremental Dynamic Table dari join stream-stream
Sebelum melanjutkan, impor dataset publik tpch_10g ke Hologres dengan mengikuti panduan di Impor dataset publik dengan beberapa klik.
Sebelum membuat Incremental Dynamic Table, aktifkan binlog untuk tabel dasar (tidak diperlukan untuk tabel dimensi).
-- Buat Incremental Dynamic Table 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 Dynamic Table dengan auto-refresh
Atur mode refresh ke auto. Mesin memprioritaskan incremental refresh dan beralih ke full refresh jika tidak didukung.
Sebelum melanjutkan, impor dataset publik tpch_10g ke Hologres dengan mengikuti panduan di Impor dataset publik dengan beberapa klik.
-- Buat Dynamic Table Auto-refresh yang secara cerdas menentukan mode refresh. Dalam contoh ini, hasilnya adalah incremental refresh.
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 Dynamic Table 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 `Dynamic Table` 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.
-
Dynamic Table dibuat sebagai tabel partisi logis. Dua partisi terbaru aktif dan direfresh secara inkremental untuk analitik data near-real-time.
-
Partisi historis tidak aktif dan menggunakan full refresh. Jika partisi historis tabel dasar telah dikoreksi atau diisi ulang, partisi tersebut dapat direfresh menggunakan full refresh.
Contoh ini menggunakan dataset publik dari GitHub.
-
Siapkan 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; -
Buat Dynamic Table partisi logis.
CREATE DYNAMIC TABLE ads_dt_github_event LOGICAL PARTITION BY LIST(ds) WITH ( -- Properti dynamic table 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 -
Kueri Dynamic Table.
SELECT * FROM ads_dt_github_event ; -
Isi ulang partisi historis.
Jika data historis di tabel dasar berubah (misalnya, data untuk '2025-04-01'), dan Dynamic Table perlu diperbarui, atur partisi historis ke mode full refresh dan picu refresh, sebaiknya dengan sumber daya Serverless Computing.
REFRESH OVERWRITE DYNAMIC TABLE ads_dt_github_event PARTITION (ds = '2025-04-01') WITH ( refresh_mode = 'full' );
Contoh 5: Hitung UV dengan Incremental Dynamic Table
Mulai dari Hologres V3.1, Incremental Dynamic Table mendukung fungsi RB_BUILD_AGG untuk perhitungan seperti jumlah UV. Dibandingkan dengan pre-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:
-
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'); -- 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; -
Hitung UV menggunakan Incremental Dynamic Table.
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; -
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 dynamic table full-refresh 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 dynamic table single-table full refresh, mulai segera dan merefresh 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 dynamic table inkremental dengan waktu mulai
Sebelum melanjutkan, impor dataset publik tpch_10g ke Hologres dengan mengikuti panduan di Impor dataset publik dengan beberapa klik.
Contoh:
Sebelum membuat `Dynamic Table` inkremental, 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 dynamic table single-table incremental refresh, 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 dynamic table full-refresh multi-join
--Buat dynamic table dengan kueri join multi-tabel, menggunakan mode full refresh 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 dynamic table inkremental join dimensi
Contoh:
Sebelum membuat `Dynamic Table` inkremental, Anda harus mengaktifkan Binlog untuk tabel dasar (tidak diperlukan untuk tabel dimensi).
Semantik JOIN tabel dimensi adalah bahwa setiap catatan 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 dynamic table 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 `Dynamic Table` incremental dan full refresh. Pendekatannya sebagai berikut:
-
Buat tabel dasar partisi di mana partisi terbaru ditulis secara real-time/near-real-time, dan partisi historis kadang-kadang dikoreksi.
-
Buat `Dynamic Table` sebagai tabel induk partisi. Gunakan incremental refresh untuk partisi terbaru untuk memenuhi kebutuhan analisis near-real-time.
-
Alihkan partisi historis ke mode full refresh. Jika partisi historis tabel sumber telah dikoreksi, partisi `Dynamic Table` juga dapat diisi ulang menggunakan full refresh, sebaiknya dengan Serverless untuk mempercepatnya.
Contoh:
-
Siapkan 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 penulisan 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'); -
Buat tabel induk `Dynamic Table` 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; -
Buat sub-tabel dan atur mode refresh-nya.
Anda dapat membuat sub-partisi `Dynamic Table` secara manual atau dinamis menggunakan DataWorks. Atur partisi terbaru ke incremental refresh dan partisi historis ke full refresh.
-- Aktifkan Binlog untuk tabel dasar ALTER TABLE base_sales SET (binlog_level = replica); -- Asumsikan sub-partisi Dynamic Table 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 Dynamic Table baru, atur mode refresh-nya ke incremental, 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 full refresh 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 Dynamic Table. Setelah meningkatkan dari V3.0, buat ulang Dynamic Table dengan sintaks baru. Alat konversi menyederhanakan proses ini.
Skenario
-
Incremental Dynamic Table harus dibuat ulang dengan sintaks baru.
-
Ketidakcocokan sintaks ditemukan selama pemeriksaan peningkatan. Rujuk laporan pemeriksaan peningkatan Anda untuk detailnya.
Kecuali untuk skenario di atas, Dynamic Table dari V3.0 tidak perlu dibuat 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 terbatas pada tabel non-partisi (baik Incremental maupun Full-refresh). Untuk Dynamic Table partisi dari V3.0, buat ulang secara manual.
Lihat Dynamic Table 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 Serverless Computing. -
Perubahan penggunaan sumber daya untuk instans gudang virtual:
-
V3.1/V3.2 (sintaks baru): Refresh Dynamic Table menggunakan sumber daya dari gudang virtual utama dari Kelompok Tabel tabel dasar dan dynamic table.
-
V3.0 (sintaks lama) dan V4.1 (sintaks baru): Refresh Dynamic Table menggunakan sumber daya dari gudang virtual utama dari Kelompok Tabel Dynamic Table.
-
-
Sintaks baru menambahkan satu koneksi per Dynamic Table untuk penjadwalan. Jika instans Anda memiliki penggunaan koneksi tinggi, bersihkan koneksi idle terlebih dahulu.
-
Perintah:
-- Hanya untuk tabel non-partisi (full dan incremental).
-- Konversi satu Dynamic Table
call hg_dynamic_table_config_upgrade('<table_name>');
-- Konversi semua Dynamic Table. Gunakan dengan hati-hati.
call hg_upgrade_all_normal_dynamic_tables();
Perintah ini mengonversi Dynamic Table (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 |
|
|
|
Nilai parameter dipertahankan setelah konversi. Misalnya, |
|
|
|
Nilai parameter dipertahankan setelah konversi. |
|
|
|
Nilai Misalnya, |
|
|
||
|
|
|
Nilai parameter dipertahankan setelah konversi. Misalnya, |
|
|
|
Nilai parameter dipertahankan setelah konversi. |
|
|
|
Nilai parameter dipertahankan setelah konversi. Misalnya, |
|
Properti tabel (misalnya, |
Properti tabel (misalnya, |
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 Dynamic Table tidak boleh null. Untuk aturan pengaturan kunci ini, lihat Kolom waktu event (kunci segmen).
-
Solusi:
-
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 dapat 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); -
Error kunci segmen: Jalankan perintah berikut untuk mengizinkan kunci segmen yang dapat null. Mulai dari Hologres V4.1, kunci segmen secara default diizinkan null, jadi kami menyarankan untuk meningkatkan instans Anda untuk memperbaiki error.
--Untuk V3.1 dan versi lebih baru, mengizinkan kunci pengelompokan yang dapat null ALTER DYNAMIC TABLE [ IF EXISTS ] [<schema>.]<table_name> SET (refresh_guc_hg_experimental_enable_nullable_clustering_key=true);
-