Mengapa Menyimpan Riwayat
Audit, pembatalan, dan analitik dari masa lalu.
Mengapa Menyimpan Riwayat adalah pelajaran SQL Academy gratis di CoddyKit. Ini adalah pelajaran 1 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.
Masalah Penimpaan
Setiap kali Anda menjalankan UPDATE atau DELETE, data lama menghilang selamanya. Hal ini memang terdengar efisien, tetapi menimbulkan masalah nyata: Anda tidak dapat menjawab pertanyaan seperti berapa harga pada hari Selasa lalu? atau siapa yang mengubah catatan ini dan kapan?
Menyimpan riwayat berarti menyimpan setiap versi suatu baris, bukan hanya versi terbaru. Pelajaran ini membahas alasan hal tersebut penting dan cara SQL membantu Anda melakukannya.
Tiga Alasan untuk Menyimpan Riwayat
Ada tiga alasan klasik untuk mempertahankan data historis dalam basis data:
1. Audit—membuktikan bahwa suatu perubahan terjadi, siapa yang melakukannya, dan kapan.
2. Pembatalan—membatalkan kesalahan tanpa memulihkan seluruh basis data.
3. Analitik—menjawab pertanyaan tentang masa lalu, menemukan tren, dan membandingkan periode.
Strategi riwayat yang dirancang dengan baik memenuhi ketiga kebutuhan tersebut tanpa menggandakan terlalu banyak penyimpanan.
Tabel Audit Sederhana
Pendekatan paling sederhana adalah tabel audit terpisah yang mencatat setiap perubahan. Setiap baris menyimpan nilai lama, nilai baru, siapa yang melakukan perubahan, dan kapan perubahan itu terjadi.
Di bawah ini adalah tabel audit untuk tabel products. Kolom operation menyimpan INSERT, UPDATE, atau DELETE.
CREATE TABLE products_audit (
audit_id SERIAL PRIMARY KEY,
product_id INT NOT NULL,
operation VARCHAR(6) NOT NULL, -- INSERT / UPDATE / DELETE
old_price NUMERIC(10,2),
new_price NUMERIC(10,2),
changed_by TEXT NOT NULL,
changed_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);Mengisi Tabel Audit
Anda dapat menulis ke tabel audit secara manual, tetapi pendekatan yang paling andal adalah pemicu basis data yang dijalankan secara otomatis setiap kali data berubah. Dengan cara ini, tidak ada kode aplikasi yang dapat melewati pencatatan tersebut.
Di sini, kita memasukkan satu baris audit secara langsung untuk menjelaskan strukturnya sebelum membahas pemicu.
INSERT INTO products_audit (product_id, operation, old_price, new_price, changed_by)
VALUES (42, 'UPDATE', 9.99, 12.49, 'alice');
SELECT * FROM products_audit ORDER BY changed_at DESC LIMIT 5;Membaca Jejak Audit
Setelah baris-baris terkumpul dalam tabel audit, Anda dapat menguerinya untuk menjawab pertanyaan audit. Kueri di bawah ini menampilkan riwayat harga lengkap untuk satu produk, dimulai dari yang paling baru.
SELECT
changed_at,
changed_by,
operation,
old_price,
new_price
FROM products_audit
WHERE product_id = 42
ORDER BY changed_at DESC;Tanggal Keberlakuan: Riwayat Waktu Valid
Tabel audit mencatat kapan Anda melakukan perubahan (waktu transaksi). Terkadang Anda juga perlu melacak kapan sesuatu benar-benar berlaku di dunia nyata—hal ini disebut waktu valid.
Menambahkan kolom valid_from dan valid_to ke tabel utama menghasilkan riwayat berdasarkan waktu berlaku, yang terkadang disebut dimensi yang berubah perlahan (SCD Type 2).
CREATE TABLE employee_history (
id SERIAL PRIMARY KEY,
employee_id INT NOT NULL,
department TEXT NOT NULL,
salary NUMERIC(10,2) NOT NULL,
valid_from DATE NOT NULL,
valid_to DATE -- NULL means current record
);
-- Current record for employee 7
INSERT INTO employee_history (employee_id, department, salary, valid_from)
VALUES (7, 'Engineering', 85000, '2023-01-01');Memperbarui Catatan yang Berubah Perlahan
Ketika seorang karyawan berpindah departemen, Anda tidak memperbarui barisnya dengan UPDATE. Sebagai gantinya, Anda menutup baris lama dengan menetapkan valid_to lalu memasukkan baris baru yang masih terbuka. Cara ini mempertahankan riwayat lengkap.
-- Step 1: close the current record
UPDATE employee_history
SET valid_to = '2024-06-01'
WHERE employee_id = 7 AND valid_to IS NULL;
-- Step 2: insert the new record
INSERT INTO employee_history (employee_id, department, salary, valid_from)
VALUES (7, 'Product', 90000, '2024-06-01');
-- Verify history
SELECT department, salary, valid_from, valid_to
FROM employee_history
WHERE employee_id = 7
ORDER BY valid_from;Membuat Kueri pada Titik Waktu
Dengan kolom waktu berlaku, Anda dapat menanyakan apa yang benar pada tanggal tertentu—kueri yang mustahil dilakukan dengan model UPDATE biasa.
Klausa WHERE memeriksa apakah tanggal target berada dalam jendela keberlakuan baris.
-- What department and salary did employee 7 have on 2023-09-15?
SELECT department, salary, valid_from, valid_to
FROM employee_history
WHERE employee_id = 7
AND valid_from <= '2023-09-15'
AND (valid_to > '2023-09-15' OR valid_to IS NULL);Tabel Temporal Berversi Sistem
Basis data SQL modern (PostgreSQL 16+, SQL Server, MySQL 8) mendukung tabel temporal berversi sistem. Basis data secara otomatis melacak waktu transaksi dalam kolom tersembunyi, dan Anda dapat mengueri keadaan sebelumnya dengan sintaks khusus.
Contoh SQL Server—konsepnya sama di berbagai mesin basis data:
-- SQL Server / MariaDB style (illustrative)
CREATE TABLE orders (
order_id INT PRIMARY KEY,
status VARCHAR(20),
total NUMERIC(10,2),
SysStartTime DATETIME2 GENERATED ALWAYS AS ROW START,
SysEndTime DATETIME2 GENERATED ALWAYS AS ROW END,
PERIOD FOR SYSTEM_TIME (SysStartTime, SysEndTime)
) WITH (SYSTEM_VERSIONING = ON);
-- Query historical state
SELECT * FROM orders FOR SYSTEM_TIME AS OF '2024-01-15 12:00:00'
WHERE order_id = 100;Menggunakan Riwayat untuk Membatalkan Perubahan
Tabel riwayat bukan hanya untuk dibaca—Anda dapat menggunakannya untuk membatalkan kesalahan. Jika tugas batch merusak 500 catatan harga, Anda dapat memulihkannya dari tabel audit tanpa menyentuh cadangan.
-- Undo all price changes made by the bad batch job at a specific time
UPDATE products p
SET price = a.old_price
FROM products_audit a
WHERE p.id = a.product_id
AND a.operation = 'UPDATE'
AND a.changed_by = 'batch_job'
AND a.changed_at BETWEEN '2024-03-10 02:00:00' AND '2024-03-10 02:05:00';
-- Confirm affected rows
SELECT COUNT(*) AS rows_restored FROM products_audit
WHERE changed_by = 'batch_job'
AND changed_at BETWEEN '2024-03-10 02:00:00' AND '2024-03-10 02:05:00';Analitik dari Waktu ke Waktu
Data riwayat membuka peluang untuk analitik deret waktu. Anda dapat melacak perubahan suatu metrik, membandingkan angka antarbulan, atau mendeteksi anomali—semuanya tanpa menyentuh gudang data terpisah.
Kueri ini menampilkan harga rata-rata suatu produk pada setiap bulan kalender menggunakan tabel audit.
SELECT
DATE_TRUNC('month', changed_at) AS month,
ROUND(AVG(new_price), 2) AS avg_price
FROM products_audit
WHERE product_id = 42
AND operation IN ('INSERT', 'UPDATE')
GROUP BY 1
ORDER BY 1;Uji Pemahaman
Uji pemahaman Anda tentang penyimpanan data historis dalam SQL.
Ringkasan: Mengapa Menyimpan Riwayat
Dalam pelajaran ini, Anda mempelajari mengapa penimpaan data berisiko dan bagaimana pola SQL mempertahankan riwayat untuk audit, pembatalan perubahan, dan analitik.
Hal-hal penting:
- Tabel audit mencatat setiap INSERT, UPDATE, dan DELETE, beserta pelakunya dan waktunya.
- Waktu berlaku (SCD Tipe 2) menggunakan baris dengan kolom
valid_from/valid_tountuk mencatat linimasa dunia nyata. - Kueri pada titik waktu menjawab pertanyaan historis dengan memfilter kolom tanggal tersebut.
- Tabel temporal berversi sistem mengotomatiskan pelacakan waktu transaksi pada tingkat basis data.
- Data riwayat memungkinkan pembatalan perubahan secara presisi dan analitik deret waktu yang kaya tanpa memerlukan cadangan.
Mempertahankan masa lalu bukanlah beban tambahan—melainkan fondasi bagi sistem yang dapat dipercaya dan diaudit.
Belajar SQL dengan tutor AI — gratis
Tulis dan jalankan kode asli di browser kamu, dapatkan bantuan instan dari tutor AI 24/7, dan lanjutkan di mana kamu tinggalkan di web atau aplikasi.
- Kursus
- 46
- Pelajaran
- 183
Pertanyaan yang Sering Diajukan
Apakah pelajaran “Mengapa Menyimpan Riwayat” gratis?
Ya — teks lengkap “Mengapa Menyimpan Riwayat” 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 “Mengapa Menyimpan Riwayat”?
Audit, pembatalan, dan analitik dari masa lalu. 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 1 dari 4.
Berapa lama pelajaran “Mengapa Menyimpan Riwayat” 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
- Mengapa Menyimpan Riwayat
- Tabel Peristiwa Hanya-Tambah
- Baris Temporal dan Berversi
- Membangun Ulang Status dari Peristiwa