ClickHouse Patterns¶
Pola desain OLAP untuk ERP. DDL: ../../database/migrations/clickhouse/. Konvensi migrasi: README.md.
Model data¶
| Prinsip | Implementasi |
|---|---|
| Satu database | erp_clickhouse โ bukan DB per tenant |
| Isolasi tenant | Kolom tenant_kode di semua tabel fakta |
| Sumber kebenaran | PostgreSQL โ CH adalah read model |
| Versi baris | versi UInt64 microseconds untuk ReplacingMergeTree |
Engine per tipe tabel¶
| Tabel | Engine | Query pattern |
|---|---|---|
transaksi, transaksi_detail, jurnal, stok, akun* |
ReplacingMergeTree(versi) |
WHERE is_deleted = 0 + FINAL bila perlu dedup |
*_riwayat |
MergeTree |
Append-only audit; tidak pakai FINAL untuk histori |
| Materialized Views | SummingMergeTree / derived |
Agregat dashboard โ rebuild DROP+CREATE |
Stok: tanpa _riwayat โ cache; mutasi audit lewat transaksi_detail.
Kolom audit CDC¶
| Kolom | Tipe | Fungsi |
|---|---|---|
versi |
UInt64 | Tie-break ReplacingMergeTree |
is_deleted |
UInt8 | Soft delete dari op d |
op |
String | c/u/d/r |
Materialized Views¶
MV tidak bisa ALTER โ perubahan skema:
DROP MATERIALIZED VIEWCREATE MATERIALIZED VIEWbaru- Data MV terisi ulang dari insert berikutnya / backfill
Contoh MV: mv_dashboard_penjualan_harian, mv_saldo_akun โ lihat migrasi material_views/V301__*.sql.
Skip indexes¶
Filter query wajib punya skip index bila memfilter volume besar (saldo, jatuh_tempo, jenis_kode).
-- Verifikasi (contoh)
EXPLAIN indexes = 1 SELECT ... FROM transaksi WHERE tenant_kode = 'sparepart' AND jenis_kode = 'PJ';
Referensi: V105__transaksi_add_skip_indexes.sql, QUICKREF.md.
Sinkronisasi DDL dengan PostgreSQL¶
| Operasi | Urutan |
|---|---|
| Tambah kolom | ClickHouse dulu โ PostgreSQL |
| Hapus kolom | PostgreSQL dulu โ ClickHouse |
| Ubah tipe | Stop consumer โ CH โ PG โ start |
| Rename | Anggap hapus + tambah |
Kolom baru: wajib DEFAULT atau Nullable. Tabel *_riwayat selalu diupdate bersama tabel utama.
Rujuk AGENTS.md.
Query dari backend¶
- Service:
backend/src/database/clickhouse.service.ts - Dashboard:
dashboard.service.ts - Selalu filter
tenant_kodedari JWT โ jangan andalkan CH untuk isolasi tanpa filter
Initial load vs CDC delta¶
| Fase | Metode |
|---|---|
| Baseline | Direct load PG โ CH (SOP_INITIAL_LOAD) |
| Steady | CDC Kafka consumer |
| Validasi | Count PG = CH sebelum Start Consumer (guardrail UI masih parsial) |
Tooling dev¶
clickhouse-client -q "SELECT count() FROM erp_clickhouse.transaksi WHERE tenant_kode='sparepart'"
Kredensial dev: AGENTS.md ยง ClickHouse, INSTALL.md.