Topik ini menjelaskan cara menulis stempel waktu penerapan untuk setiap operasi penyisipan dan pembaruan yang Anda lakukan dengan Spanner. Untuk menggunakan fitur ini, tetapkan opsi
allow_commit_timestamp
pada kolom TIMESTAMP
, lalu tulis
stempel waktu sebagai bagian dari setiap transaksi.
Ringkasan
Stempel waktu commit, berdasarkan teknologi TrueTime, adalah waktu saat transaksi di-commit dalam database. Opsi kolom allow_commit_timestamp
memungkinkan Anda menyimpan stempel waktu commit ke dalam kolom secara atomik.
Dengan menggunakan stempel waktu commit yang disimpan dalam tabel, Anda dapat menentukan urutan mutasi yang tepat dan membuat fitur seperti log perubahan.
Untuk menyisipkan stempel waktu commit di database Anda, selesaikan langkah-langkah berikut:
Buat kolom dengan jenis
TIMESTAMP
dengan opsi kolomallow_commit_timestamp
yang ditetapkan ketrue
dalam definisi skema. Misalnya:CREATE TABLE Performances ( ... LastUpdateTime TIMESTAMP NOT NULL OPTIONS (allow_commit_timestamp=true) ... ) PRIMARY KEY (...);
Jika Anda melakukan penyisipan atau pembaruan dengan DML, gunakan fungsi
PENDING_COMMIT_TIMESTAMP
untuk menulis stempel waktu penerapan.Jika Anda melakukan penyisipan atau pembaruan dengan mutasi, gunakan string pengganti
spanner.commit_timestamp()
pada penyisipan atau pembaruan ke kolom stempel waktu penerapan Anda. Anda juga dapat menggunakan konstanta stempel waktu commit yang disediakan oleh library klien. Misalnya, konstanta ini di klien Java adalahValue.COMMIT_TIMESTAMP
.
Saat Spanner melakukan transaksi menggunakan placeholder ini sebagai nilai
kolom, stempel waktu commit sebenarnya akan ditulis ke kolom yang ditentukan (Misalnya: kolom LastUpdateTime
). Kemudian, Anda dapat menggunakan nilai kolom ini
untuk membuat histori pembaruan pada tabel.
Nilai stempel waktu commit tidak dijamin unik. Transaksi yang menulis ke kumpulan kolom yang tidak tumpang-tindih mungkin memiliki stempel waktu yang sama. Transaksi yang menulis ke kumpulan kolom yang tumpang-tindih memiliki stempel waktu yang unik.
Stempel waktu commit Spanner memiliki perincian mikrodetik,
dan dikonversi menjadi nanodetik saat disimpan di kolom TIMESTAMP
.
Membuat dan menghapus kolom stempel waktu commit
Gunakan opsi kolom allow_commit_timestamp
untuk menambahkan dan menghapus dukungan untuk stempel waktu commit:
- Saat membuat tabel baru untuk menentukan bahwa kolom mendukung stempel waktu penerapan.
- Saat mengubah tabel yang ada:
- untuk menambahkan kolom baru yang mendukung stempel waktu commit,
- untuk mengubah kolom
TIMESTAMP
yang ada agar mendukung stempel waktu commit, - untuk mengubah kolom
TIMESTAMP
yang ada guna menghapus dukungan stempel waktu commit
Kunci dan indeks
Anda dapat menggunakan kolom stempel waktu commit sebagai kolom kunci utama atau sebagai kolom non-kunci. Kunci utama dapat ditentukan sebagai ASC
atau DESC
.
ASC
(default) - Kunci menaik ideal untuk menjawab kueri dari waktu tertentu ke depan.DESC
- Tombol menurun akan mempertahankan baris terbaru di bagian atas tabel. Mereka menyediakan akses cepat ke data terbaru.
Opsi allow_commit_timestamp
harus konsisten di seluruh kunci
utama tabel induk dan turunan. Jika opsi tidak konsisten di seluruh
kunci utama, Spanner akan menampilkan error. Satu-satunya saat opsi
dapat tidak konsisten adalah saat Anda membuat atau memperbarui skema.
Penggunaan stempel waktu commit dalam skenario berikut akan membuat hotspot yang mengurangi performa data:
Kolom stempel waktu penerapan sebagai bagian pertama dari kunci utama tabel:
CREATE TABLE Users ( LastAccess TIMESTAMP NOT NULL, UserId INT64 NOT NULL, ... ) PRIMARY KEY (LastAccess, UserId);
Bagian pertama kunci utama indeks sekunder:
CREATE INDEX UsersByLastAccess ON Users(LastAccess)
atau
CREATE INDEX UsersByLastAccessAndName ON Users(LastAccess, FirstName)
Hotspot mengurangi performa data, bahkan dengan kecepatan tulis yang rendah. Tidak ada overhead performa jika stempel waktu penerapan diaktifkan pada kolom non-kunci yang tidak diindeks.
Membuat kolom stempel waktu commit
DDL berikut membuat tabel dengan kolom yang mendukung stempel waktu penerapan.
CREATE TABLE Performances (
SingerId INT64 NOT NULL,
VenueId INT64 NOT NULL,
EventDate Date,
Revenue INT64,
LastUpdateTime TIMESTAMP NOT NULL OPTIONS (allow_commit_timestamp=true)
) PRIMARY KEY (SingerId, VenueId, EventDate),
INTERLEAVE IN PARENT Singers ON DELETE CASCADE
Menambahkan opsi akan mengubah kolom stempel waktu sebagai berikut:
- Anda dapat menggunakan string pengganti
spanner.commit_timestamp()
(atau konstanta yang disediakan oleh library klien) untuk penyisipan dan update. - Kolom hanya dapat berisi nilai di masa lalu. Untuk mengetahui informasi selengkapnya, lihat Memberikan nilai Anda sendiri untuk stempel waktu.
Opsi allow_commit_timestamp
peka huruf besar/kecil.
Menambahkan kolom stempel waktu commit ke tabel yang ada
Untuk menambahkan kolom stempel waktu commit ke tabel yang ada, gunakan pernyataan ALTER TABLE
. Misalnya, untuk menambahkan kolom LastUpdateTime
ke tabel Performances
, gunakan pernyataan berikut:
ALTER TABLE Performances ADD COLUMN LastUpdateTime TIMESTAMP
NOT NULL OPTIONS (allow_commit_timestamp=true)
Mengonversi kolom stempel waktu menjadi kolom stempel waktu commit
Anda dapat mengonversi kolom stempel waktu yang ada menjadi kolom stempel waktu commit, tetapi tindakan ini mengharuskan Spanner memvalidasi bahwa nilai stempel waktu yang ada sudah berlalu. Contoh:
ALTER TABLE Performances ALTER COLUMN LastUpdateTime
SET OPTIONS (allow_commit_timestamp=true)
Anda tidak dapat mengubah jenis data atau anotasi NULL
kolom dalam pernyataan
ALTER TABLE
yang menyertakan SET OPTIONS
. Untuk mengetahui detailnya, lihat
Bahasa Definisi Data.
Menghapus opsi stempel waktu commit
Jika Anda ingin menghapus dukungan stempel waktu commit dari kolom, gunakan opsi
allow_commit_timestamp=null
dalam pernyataan
ALTER TABLE
. Perilaku stempel waktu commit dihapus, tetapi kolom tersebut masih berupa stempel waktu. Mengubah opsi tidak akan mengubah karakteristik kolom lainnya, seperti jenis atau kemampuan null (NOT NULL
). Misalnya:
ALTER TABLE Performances ALTER COLUMN LastUpdateTime
SET OPTIONS (allow_commit_timestamp=null)
Menulis stempel waktu commit menggunakan pernyataan DML
Anda menggunakan fungsi PENDING_COMMIT_TIMESTAMP
untuk menulis stempel waktu commit dalam pernyataan DML. Spanner memilih stempel waktu commit saat transaksi di-commit.
Pernyataan DML berikut memperbarui kolom LastUpdateTime
di tabel
Performances
dengan stempel waktu commit:
UPDATE Performances SET LastUpdateTime = PENDING_COMMIT_TIMESTAMP()
WHERE SingerId=1 AND VenueId=2 AND EventDate="2015-10-21"
Contoh kode berikut menggunakan fungsi
PENDING_COMMIT_TIMESTAMP
untuk menulis stempel waktu penerapan di kolom LastUpdateTime
.
C++
C#
Go
Java
Node.js
PHP
Python
Ruby
Ruby
Stempel waktu penerapan hanya dapat ditulis ke kolom yang diberi anotasi dengan opsi
allow_commit_timestamp=true
.
Jika Anda memiliki mutasi pada baris di beberapa tabel, Anda harus menentukan
spanner.commit_timestamp()
(atau konstanta
library klien) untuk kolom stempel waktu penerapan di setiap tabel.
Membuat kueri kolom stempel waktu commit
Contoh berikut membuat kueri kolom stempel waktu penerapan tabel.
C++
C#
Go
Java
Node.js
PHP
Python
Ruby
Memberikan nilai Anda sendiri untuk kolom stempel waktu commit
Anda dapat memberikan nilai Anda sendiri untuk kolom stempel waktu commit, alih-alih
meneruskan spanner.commit_timestamp()
(atau konstanta library klien) sebagai
nilai kolom. Nilai harus berupa stempel waktu di masa lalu. Pembatasan ini
memastikan bahwa penulisan stempel waktu adalah operasi yang murah dan cepat. Server
akan menampilkan error FailedPrecondition
jika stempel waktu mendatang ditentukan.
Membuat log perubahan
Misalkan Anda ingin membuat log perubahan setiap mutasi yang terjadi pada tabel, lalu menggunakan log perubahan tersebut untuk audit. Contohnya adalah tabel yang menyimpan histori perubahan pada dokumen pengolah kata. Stempel waktu commit mempermudah pembuatan log perubahan, karena stempel waktu dapat menerapkan pengurutan entri log perubahan. Anda dapat membuat log perubahan yang menyimpan histori perubahan pada dokumen tertentu menggunakan skema seperti contoh berikut:
CREATE TABLE Documents (
UserId INT64 NOT NULL,
DocumentId INT64 NOT NULL,
Contents STRING(MAX) NOT NULL,
) PRIMARY KEY (UserId, DocumentId);
CREATE TABLE DocumentHistory (
UserId INT64 NOT NULL,
DocumentId INT64 NOT NULL,
Ts TIMESTAMP NOT NULL OPTIONS (allow_commit_timestamp=true),
Delta STRING(MAX),
) PRIMARY KEY (UserId, DocumentId, Ts),
INTERLEAVE IN PARENT Documents ON DELETE NO ACTION;
Untuk membuat log perubahan, sisipkan baris baru di DocumentHistory
dalam transaksi yang sama dengan saat Anda menyisipkan atau memperbarui baris di Document
. Saat menyisipkan
baris baru di DocumentHistory
, gunakan placeholder
spanner.commit_timestamp()
(atau konstanta library klien) untuk memberi tahu
Spanner agar menulis stempel waktu commit ke kolom Ts
. Menyisipkan
tabel DocumentsHistory
dengan tabel Documents
akan memungkinkan lokalitas
data serta penyisipan dan pembaruan yang lebih efisien. Namun, tindakan ini juga menambahkan batasan bahwa baris induk dan turunan harus dihapus bersama. Untuk mempertahankan baris di DocumentHistory
setelah baris
di Documents
dihapus, jangan selang-selingi tabel.
Mengoptimalkan kueri data terbaru dengan stempel waktu commit
Stempel waktu penerapan memungkinkan pengoptimalan Spanner yang dapat mengurangi I/O kueri saat mengambil data yang ditulis setelah waktu tertentu.
Untuk mengaktifkan pengoptimalan ini, klausa WHERE
kueri harus menyertakan
perbandingan antara kolom stempel waktu commit tabel dan waktu tertentu
yang Anda berikan, dengan atribut berikut:
Berikan waktu tertentu sebagai ekspresi konstanta: literal, parameter, atau fungsi yang argumennya sendiri dievaluasi ke konstanta.
Bandingkan apakah stempel waktu commit lebih baru daripada waktu yang diberikan, melalui operator
>
atau>=
.Secara opsional, tambahkan batasan lebih lanjut pada klausa
WHERE
denganAND
. Memperluas klausul denganOR
akan mendiskualifikasi kueri dari pengoptimalan ini.
Misalnya, pertimbangkan tabel Performances
berikut, yang mencakup
kolom stempel waktu commit:
CREATE TABLE Performances (
SingerId INT64 NOT NULL,
VenueId INT64 NOT NULL,
EventDate DATE,
Revenue INT64,
LastUpdateTime TIMESTAMP NOT NULL OPTIONS (allow_commit_timestamp=true)
) PRIMARY KEY (SingerId, VenueId, EventDate);
Kueri ini diuntungkan dari pengoptimalan stempel waktu commit yang dijelaskan sebelumnya, karena memiliki perbandingan lebih besar dari atau sama dengan antara kolom stempel waktu commit tabel dan ekspresi konstanta—dalam hal ini, literal:
SELECT * FROM Performances WHERE LastUpdateTime >= "2022-05-01";
Kueri berikut juga memenuhi syarat untuk pengoptimalan, karena memiliki perbandingan lebih besar dari antara stempel waktu penerapan dan fungsi yang semua argumennya dievaluasi ke konstanta selama eksekusi kueri:
SELECT * FROM Performances
WHERE LastUpdateTime > TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 30 DAY);
Langkah berikutnya
- Gunakan stempel waktu commit untuk membuat log perubahan dengan Go.