Baris Temporal dan Berversi
Kueri waktu valid dan kondisi pada waktu tertentu.
Baris Temporal dan Berversi adalah pelajaran SQL Academy gratis di CoddyKit. Ini adalah pelajaran 3 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 Temporal?
Tabel temporal memungkinkan Anda melacak perubahan data dari waktu ke waktu. Alih-alih menimpa baris ketika terjadi perubahan, tabel temporal menyimpan setiap versi baris tersebut dan memberi masing-masing versi periode waktu saat baris itu berlaku.
Ada dua konsep utama: waktu berlaku (kapan fakta tersebut benar di dunia nyata) dan waktu transaksi (kapan basis data mencatat fakta tersebut). Jika digabungkan, keduanya menghasilkan tabel bitemporal yang lengkap.
Waktu Berlaku vs. Waktu Transaksi
Waktu berlaku menunjukkan kapan suatu fakta benar di dunia nyata—misalnya, gaji seorang pegawai dari 2020-01-01 hingga 2022-06-30. Waktu transaksi adalah saat baris basis data ditambahkan atau dinyatakan berakhir. Keduanya menjawab dua pertanyaan: Apa yang benar? dan Kapan kita mengetahuinya?
Sebagian besar penggunaan praktis dimulai dengan pelacakan waktu berlaku, yang dapat Anda terapkan secara manual menggunakan kolom valid_from dan valid_to.
Membuat Tabel Waktu Berlaku
Cara paling sederhana untuk menyimpan baris berversi adalah menambahkan kolom stempel waktu valid_from dan valid_to. Nilai valid_to berupa NULL (atau penanda khusus yang jauh di masa depan seperti 9999-12-31) berarti baris tersebut masih aktif.
CREATE TABLE employee_salary (
id SERIAL PRIMARY KEY,
employee_id INT NOT NULL,
salary NUMERIC(12, 2) NOT NULL,
valid_from DATE NOT NULL,
valid_to DATE
);
INSERT INTO employee_salary (employee_id, salary, valid_from, valid_to)
VALUES
(1, 50000, '2020-01-01', '2022-06-30'),
(1, 60000, '2022-07-01', NULL);Mengueri Versi Saat Ini
Untuk menemukan baris yang sedang aktif bagi setiap pegawai, filter baris yang memiliki valid_to IS NULL (tanpa batas akhir), atau baris yang tanggal hari ini berada dalam rentang berlakunya. Menggunakan nilai penanda seperti '9999-12-31' menyederhanakan perbandingan rentang.
SELECT employee_id, salary
FROM employee_salary
WHERE valid_to IS NULL
ORDER BY employee_id;Kueri pada Waktu Tertentu
Kueri pada waktu tertentu menanyakan: Bagaimana keadaan data pada titik waktu tertentu? Anda memfilter baris yang stempel waktunya berada dalam periode berlaku yang ditentukan. Ini merupakan salah satu fitur paling kuat dari tabel temporal.
-- What was employee 1's salary on 2021-03-15?
SELECT employee_id, salary, valid_from, valid_to
FROM employee_salary
WHERE employee_id = 1
AND valid_from <= '2021-03-15'
AND (valid_to IS NULL OR valid_to > '2021-03-15');Memperbarui Baris Berversi
Ketika suatu fakta berubah, Anda tidak melakukan UPDATE pada baris yang ada. Sebagai gantinya, Anda menutup baris saat ini dengan menetapkan nilai valid_to, lalu menambahkan baris baru dengan nilai yang baru. Dengan demikian, seluruh riwayat tetap terjaga.
-- Employee 1 gets a raise effective 2023-01-01
BEGIN;
-- Close the current open row
UPDATE employee_salary
SET valid_to = '2022-12-31'
WHERE employee_id = 1
AND valid_to IS NULL;
-- Insert the new version
INSERT INTO employee_salary (employee_id, salary, valid_from, valid_to)
VALUES (1, 72000, '2023-01-01', NULL);
COMMIT;Menggunakan Rentang Tanggal untuk Periode Keberlakuan
Tipe daterange PostgreSQL memodelkan periode keberlakuan dengan baik sebagai satu kolom. Anda dapat menggunakan operator @> (memuat) untuk memeriksa apakah suatu tanggal berada dalam rentang, lalu menambahkan batasan pengecualian untuk mencegah periode yang tumpang tindih bagi entitas yang sama.
CREATE TABLE employee_salary_v2 (
id SERIAL PRIMARY KEY,
employee_id INT NOT NULL,
salary NUMERIC(12, 2) NOT NULL,
valid_period DATERANGE NOT NULL,
EXCLUDE USING GIST (employee_id WITH =, valid_period WITH &&)
);
INSERT INTO employee_salary_v2 (employee_id, salary, valid_period)
VALUES
(1, 50000, '[2020-01-01, 2022-07-01)'),
(1, 60000, '[2022-07-01, infinity)');Kueri pada Waktu Tertentu dengan Rentang Tanggal
Dengan pendekatan daterange, kueri pada waktu tertentu menjadi sangat mudah dibaca. Operator @> memeriksa apakah tanggal yang diberikan berada dalam rentang tersebut, sekaligus menangani batas bawah dan batas atas secara otomatis.
-- What was employee 1's salary on 2021-03-15?
SELECT employee_id, salary, valid_period
FROM employee_salary_v2
WHERE employee_id = 1
AND valid_period @> '2021-03-15'::date;Tabel Berversi Sistem (Standar SQL)
Standar SQL:2011 memperkenalkan tabel temporal berversi sistem. Basis data secara otomatis mengelola kolom waktu transaksi row_start dan row_end. Di PostgreSQL, Anda menyimulasikan fitur ini; di SQL Server dan MariaDB, fitur ini tersedia secara bawaan dengan SYSTEM VERSIONING.
Contoh di bawah menampilkan sintaks SQL Server / MariaDB sebagai acuan konsep.
-- SQL Server / MariaDB syntax (reference)
CREATE TABLE dbo.Product (
ProductID INT PRIMARY KEY,
Name VARCHAR(100),
Price DECIMAL(10,2),
SysStart DATETIME2 GENERATED ALWAYS AS ROW START,
SysEnd DATETIME2 GENERATED ALWAYS AS ROW END,
PERIOD FOR SYSTEM_TIME (SysStart, SysEnd)
)
WITH (SYSTEM_VERSIONING = ON (HISTORY_TABLE = dbo.Product_History));Penggabungan Temporal: Menyelaraskan Dua Tabel Berdasarkan Waktu
Tantangan yang umum adalah menggabungkan dua tabel temporal berdasarkan periode waktu yang cocok. Misalnya, menggabungkan gaji pegawai dengan penempatan departemen ketika keduanya memiliki periode waktu berlaku. Anda menggabungkannya berdasarkan kunci entitas DAN kondisi tumpang tindih menggunakan && pada rentang atau perbandingan tanggal secara eksplisit.
CREATE TABLE dept_assignment (
employee_id INT,
department VARCHAR(50),
valid_period DATERANGE
);
INSERT INTO dept_assignment VALUES
(1, 'Engineering', '[2020-01-01, infinity)'),
(1, 'Marketing', '[2019-01-01, 2020-01-01)');
-- Periods where employee 1 was in Engineering AND had salary > 55000
SELECT s.salary, d.department,
s.valid_period * d.valid_period AS overlap_period
FROM employee_salary_v2 s
JOIN dept_assignment d
ON s.employee_id = d.employee_id
AND s.valid_period && d.valid_period
WHERE s.employee_id = 1
AND s.salary > 55000;Mencegah Celah dan Tumpang Tindih
Dua masalah kualitas data yang umum pada tabel temporal adalah celah (periode tanpa rekaman) dan tumpang tindih (dua baris yang berlaku secara bersamaan). Batasan pengecualian dengan && mencegah tumpang tindih pada tingkat basis data. Untuk mendeteksi celah, Anda perlu memeriksa cakupan yang hilang menggunakan kueri.
-- Find gaps in salary history for employee 1
-- (periods where upper(prev) < lower(next))
SELECT
upper(a.valid_period) AS gap_start,
lower(b.valid_period) AS gap_end
FROM employee_salary_v2 a
JOIN employee_salary_v2 b
ON a.employee_id = b.employee_id
AND upper(a.valid_period) < lower(b.valid_period)
WHERE a.employee_id = 1
AND NOT EXISTS (
SELECT 1 FROM employee_salary_v2 c
WHERE c.employee_id = 1
AND lower(c.valid_period) > upper(a.valid_period)
AND lower(c.valid_period) < lower(b.valid_period)
)
ORDER BY gap_start;Uji Pemahaman
Uji pemahaman Anda tentang tabel temporal dan kueri pada waktu tertentu.
Ringkasan: Baris Temporal dan Berversi
Dalam pelajaran ini, Anda mempelajari cara memodelkan data yang berubah seiring waktu menggunakan kolom waktu berlaku dan tipe daterange PostgreSQL. Hal-hal penting:
- Jangan pernah menimpa baris historis—tutup baris lama dan tambahkan versi baru.
- Gunakan kueri pada waktu tertentu (
valid_from <= target AND valid_to > target) untuk mengambil data pada waktu mana pun di masa lalu. - Tipe
daterangedengan operator@>membuat kueri temporal ringkas dan mudah dibaca. - Batasan pengecualian pada
&&(tumpang tindih rentang) menegakkan integritas data pada tingkat basis data. - Penggabungan temporal menyelaraskan dua riwayat dengan mencari irisan periode berlakunya.
Pola-pola ini menjadi fondasi sumber peristiwa, pencatatan audit, dan sistem apa pun yang mengutamakan ketepatan historis.
Pertanyaan yang Sering Diajukan
Apakah pelajaran “Baris Temporal dan Berversi” gratis?
Ya — teks lengkap “Baris Temporal dan Berversi” 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 “Baris Temporal dan Berversi”?
Kueri waktu valid dan kondisi pada waktu tertentu. 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 3 dari 4.
Berapa lama pelajaran “Baris Temporal dan Berversi” 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