0Pricing
SQL Academy · Pelajaran

Tabel Peristiwa Hanya-Tambah

Catat apa yang terjadi, jangan pernah menimpa data.

Tabel Peristiwa Hanya-Tambah adalah pelajaran SQL Academy gratis di CoddyKit. Ini adalah pelajaran 2 dari 4. Kamu bisa membaca pelajaran lengkapnya di bawah secara gratis — lalu praktikkan langsung di browser dengan editor kode bawaan dan tutor AI 24/7. Ini adalah bagian dari jalur belajar SQL Academy, dan progresmu tersinkronisasi di web dan aplikasi CoddyKit. Kursus SQL Academy mencakup 4 pelajaran total.

Apa Itu Tabel Hanya-Tambah?

Tabel peristiwa hanya-tambah adalah tabel yang barisnya hanya pernah ditambahkan—tidak pernah diperbarui atau dihapus. Setiap baris mewakili sesuatu yang terjadi pada titik waktu tertentu.

Pola ini merupakan fondasi sumber peristiwa. Alih-alih menyimpan keadaan saat ini, Anda menyimpan setiap perubahan sebagai peristiwa yang tidak dapat diubah, sehingga menghasilkan riwayat yang lengkap dan dapat diaudit.

Membuat Tabel Peristiwa

Tabel peristiwa yang dirancang dengan baik mencatat siapa melakukan apa, pada sumber daya mana, dan kapan. Kolom occurred_at mencatat stempel waktu yang tepat, sedangkan DEFAULT NOW() memastikan kolom tersebut selalu terisi secara otomatis.

Perhatikan bahwa tidak ada UPDATE atau DELETE dalam rancangan ini—baris menjadi permanen setelah ditulis.

CREATE TABLE account_events (
  id           BIGSERIAL PRIMARY KEY,
  account_id   BIGINT      NOT NULL,
  event_type   TEXT        NOT NULL,
  payload      JSONB,
  occurred_at  TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

Menambahkan Peristiwa

Setiap tindakan pengguna—masuk, menyetor uang, atau mengubah alamat surel—menjadi baris baru. Anda tidak pernah kembali dan mengedit peristiwa sebelumnya. Jika ada yang perlu diperbaiki, Anda menambahkan peristiwa kompensasi sebagai gantinya.

Dengan demikian, seluruh urutan kejadian tetap terjaga sesuai urutannya.

INSERT INTO account_events (account_id, event_type, payload)
VALUES
  (42, 'account_opened',  '{"plan": "free"}'),
  (42, 'email_verified',  '{"email": "alice@example.com"}'),
  (42, 'plan_upgraded',   '{"from": "free", "to": "pro"}');

Membaca Seluruh Riwayat

Karena setiap perubahan keadaan disimpan sebagai baris, kueri untuk membaca seluruh riwayat suatu akun cukup berupa SELECT yang diurutkan berdasarkan waktu. Anda dapat memutar ulang seluruh perjalanan sebuah rekaman, dari peristiwa pertama hingga yang terbaru.

SELECT
  id,
  event_type,
  payload,
  occurred_at
FROM account_events
WHERE account_id = 42
ORDER BY occurred_at ASC;

Menurunkan Keadaan Saat Ini

Dengan tabel hanya-tambah, Anda tidak menyimpan keadaan saat ini secara langsung—Anda menurunkannya dengan membaca peristiwa relevan yang terbaru. Dalam contoh ini, paket saat ini untuk akun 42 adalah apa pun yang dinyatakan oleh peristiwa peningkatan paket atau pembukaan akun yang paling baru.

Menggunakan ORDER BY occurred_at DESC LIMIT 1 akan mengambil snapshot terbaru secara efisien.

SELECT payload->>'to'  AS current_plan
FROM   account_events
WHERE  account_id = 42
  AND  event_type IN ('account_opened', 'plan_upgraded')
ORDER BY occurred_at DESC
LIMIT 1;

Menegakkan Ketidakberubahan dengan Aturan

Jaminan bahwa tabel hanya-tambah dapat ditegakkan pada tingkat basis data menggunakan RULE yang diam-diam mengabaikan UPDATE atau DELETE apa pun pada tabel tersebut. Ini mencegah perubahan yang tidak disengaja dari aplikasi mana pun yang memiliki akses tulis.

Pemicu yang memunculkan pengecualian merupakan alternatif yang bahkan lebih kuat karena secara aktif menolak operasi tersebut dengan sebuah kesalahan.

CREATE RULE no_update_events AS
  ON UPDATE TO account_events
  DO INSTEAD NOTHING;

CREATE RULE no_delete_events AS
  ON DELETE TO account_events
  DO INSTEAD NOTHING;

Ketidakberubahan melalui Pemicu

Pemicu yang memunculkan pengecualian lebih ketat daripada aturan yang diam-diam mengabaikan operasi—aplikasi segera menerima kesalahan jika mencoba mengubah peristiwa sebelumnya. Dengan begitu, bug terlihat dan tidak diam-diam ditelan.

CREATE OR REPLACE FUNCTION deny_event_mutation()
RETURNS TRIGGER AS $$
BEGIN
  RAISE EXCEPTION 'Event table is append-only: % is not allowed', TG_OP;
END;
$$ LANGUAGE plpgsql;

CREATE TRIGGER trg_deny_event_mutation
BEFORE UPDATE OR DELETE ON account_events
FOR EACH ROW EXECUTE FUNCTION deny_event_mutation();

Menghitung Peristiwa dari Waktu ke Waktu

Tabel hanya-tambah memudahkan analitik berbasis waktu. Karena setiap peristiwa memiliki stempel waktu, Anda dapat mengelompokkannya berdasarkan hari, minggu, atau bulan tanpa kolom tambahan. Contoh di bawah menghitung jumlah peristiwa dari setiap jenis yang terjadi setiap hari.

SELECT
  DATE_TRUNC('day', occurred_at) AS day,
  event_type,
  COUNT(*)                        AS total
FROM account_events
GROUP BY 1, 2
ORDER BY 1, 2;

Merekonstruksi Keadaan pada Titik Waktu

Salah satu sifat paling kuat dari catatan peristiwa adalah kemampuan untuk merekonstruksi keadaan suatu rekaman sebagaimana adanya pada suatu waktu di masa lalu. Cukup filter peristiwa hingga stempel waktu yang diinginkan—tidak diperlukan ekstensi perjalanan waktu.

Hal ini sangat berguna untuk penelusuran bug, audit, dan kepatuhan terhadap peraturan.

-- What plan was account 42 on at the end of last month?
SELECT payload->>'to' AS plan_at_snapshot
FROM   account_events
WHERE  account_id = 42
  AND  event_type IN ('account_opened', 'plan_upgraded')
  AND  occurred_at <= DATE_TRUNC('month', NOW()) - INTERVAL '1 second'
ORDER BY occurred_at DESC
LIMIT 1;

Peristiwa Kompensasi, Bukan Koreksi

Ketika kesalahan ditemukan—misalnya, tagihan yang keliru—Anda tidak menghapus peristiwa yang salah. Sebagai gantinya, Anda menambahkan peristiwa kompensasi yang membatalkan atau mengoreksinya. Kedua peristiwa tetap terlihat dalam catatan, sehingga menunjukkan dengan tepat apa yang terjadi dan kapan koreksi dibuat.

Hal ini menjaga jejak audit tetap lengkap dan membuat perubahan yang dilakukan tanpa izin mudah terdeteksi.

-- A charge was applied by mistake; record a reversal
INSERT INTO account_events (account_id, event_type, payload)
VALUES (
  42,
  'charge_reversed',
  '{"reason": "billing_error", "reverses_event_id": 17}'
);

Mempartisi Tabel Peristiwa Besar

Tabel peristiwa berkembang dengan cepat. Mempartisinya berdasarkan rentang waktu membuat setiap partisi tetap kecil, mempercepat kueri rentang, dan memungkinkan partisi lama diarsipkan atau dihapus tanpa menyentuh data terbaru.

Pemartisian deklaratif PostgreSQL membuatnya sederhana: tentukan partisi RANGE pada occurred_at dan biarkan basis data mengarahkan penambahan secara otomatis.

CREATE TABLE account_events_2025
  PARTITION OF account_events
  FOR VALUES FROM ('2025-01-01') TO ('2026-01-01');

CREATE TABLE account_events_2026
  PARTITION OF account_events
  FOR VALUES FROM ('2026-01-01') TO ('2027-01-01');

Uji Pemahaman tentang Tabel Hanya-Tambah

Uji pemahaman Anda tentang rancangan tabel peristiwa hanya-tambah.

Ringkasan: Tabel Peristiwa Hanya-Tambah

Dalam pelajaran ini, Anda mempelajari cara merancang dan menggunakan tabel peristiwa hanya-tambah:

  • Ketidakberubahan—baris ditambahkan sekali dan tidak pernah diubah. Peristiwa masa lalu adalah fakta.
  • Riwayat lengkap—setiap perubahan keadaan dipertahankan, sehingga memungkinkan jejak audit lengkap dan kueri pada titik waktu.
  • Peristiwa kompensasi—kesalahan diperbaiki dengan menambahkan peristiwa pembalikan baru, bukan dengan menghapus peristiwa lama.
  • Penegakan—aturan atau pemicu pada tingkat basis data mencegah perubahan yang tidak disengaja.
  • Skalabilitas—partisi rentang menjaga kinerja catatan peristiwa besar dari waktu ke waktu.

Tabel hanya-tambah merupakan tulang punggung sumber peristiwa, arsitektur CQRS, dan sistem apa pun yang memerlukan kemampuan audit serta ketepatan historis.

Pertanyaan yang Sering Diajukan

Apakah pelajaran “Tabel Peristiwa Hanya-Tambah” gratis?

Ya — teks lengkap “Tabel Peristiwa Hanya-Tambah” gratis dibaca di sini di web. Untuk praktiknya secara interaktif (editor kode bawaan dan tutor AI 24/7) dan buka sisa kursus SQL Academy, upgrade ke CoddyKit PRO. Kursus SQL Academy mencakup 4 pelajaran total.

Apa yang akan aku pelajari di “Tabel Peristiwa Hanya-Tambah”?

Catat apa yang terjadi, jangan pernah menimpa data. Kamu berlatih SQL Academy dengan kode praktik yang langsung kamu jalankan di browser, dan tutor AI 24/7 menjawab pertanyaanmu saat kamu mengerjakan pelajaran ini.

Apakah aku perlu pengalaman untuk memulai SQL Academy?

Tidak diperlukan pengalaman sebelumnya. SQL Academy di CoddyKit dirancang untuk pemula hingga pelajar tingkat lanjut, jadi kamu bisa memulai di sini atau dari awal dan belajar sesuai kecepatan kamu sendiri. Ini adalah pelajaran 2 dari 4.

Berapa lama pelajaran “Tabel Peristiwa Hanya-Tambah” memakan waktu?

Sebagian besar pelajaran CoddyKit memakan waktu sekitar 5–10 menit. Setiap pelajaran ringkas dan interaktif, jadi kamu membuat kemajuan stabil dan melanjutkan dari tempat kamu tinggalkan di web dan aplikasi.

Bisakah aku menulis dan menjalankan kode dalam pelajaran SQL Academy ini?

Ya. Setiap pelajaran SQL Academy menyertakan editor kode bawaan, jadi kamu menulis dan menjalankan kode nyata langsung di browser dan mendapatkan umpan balik AI instan — tidak diperlukan penyiapan lokal.

Semua pelajaran dalam kursus ini

  1. Mengapa Menyimpan Riwayat
  2. Tabel Peristiwa Hanya-Tambah
  3. Baris Temporal dan Berversi
  4. Membangun Ulang Status dari Peristiwa
← Kembali ke SQL Academy