Halaman ini menjelaskan cara menulis stempel waktu commit untuk setiap operasi penyisipan dan pembaruan yang Anda lakukan dengan Spanner di database berdialek PostgreSQL.
Menyisipkan stempel waktu commit
Stempel waktu commit, berdasarkan teknologi TrueTime, adalah waktu saat transaksi di-commit dalam database. Anda dapat menyimpan stempel waktu commit transaksi secara atomik ke dalam kolom. 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 jenis
SPANNER.COMMIT_TIMESTAMP
. Contoh:CREATE TABLE Performances ( ... LastUpdateTime SPANNER.COMMIT_TIMESTAMP NOT NULL, ... PRIMARY KEY (...) ) ;
Jika Anda melakukan penyisipan atau update dengan DML, gunakan fungsi
SPANNER.PENDING_COMMIT_TIMESTAMP()
untuk menulis stempel waktu commit.Jika Anda melakukan penyisipan atau pembaruan dengan pernyataan atau mutasi yang disiapkan, gunakan string placeholder
SPANNER.COMMIT_TIMESTAMP()
untuk kolom stempel waktu commit 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. Selanjutnya, 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 SPANNER.COMMIT_TIMESTAMP
.
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.
Menghindari hotspot
Penggunaan stempel waktu commit dalam skenario berikut akan membuat hotspot, yang mengurangi performa data:
Kolom stempel waktu commit sebagai bagian pertama dari kunci utama tabel.
CREATE TABLE Users ( LastAccess SPANNER.COMMIT_TIMESTAMP NOT NULL, UserId bigint NOT NULL, ... PRIMARY KEY (LastAccess, UserId) ) ;
Menyertakan kolom kunci utama stempel waktu commit sebagai bagian pertama 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.
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 SPANNER.COMMIT_TIMESTAMP;
Menulis stempel waktu commit menggunakan pernyataan DML
Anda menggunakan fungsi SPANNER.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 = SPANNER.PENDING_COMMIT_TIMESTAMP()
WHERE SingerId=1 AND VenueId=2 AND EventDate="2015-10-21"
Menyisipkan baris menggunakan mutasi
Saat menyisipkan baris, Spanner menulis nilai stempel waktu commit hanya
jika Anda menyertakan kolom dalam daftar kolom dan meneruskan string
placeholder spanner.commit_timestamp()
(atau konstanta library klien)
sebagai nilainya. Contoh:
C++
C#
Go
Java
Node.js
PHP
Python
Ruby
Jika Anda memiliki mutasi pada baris di beberapa tabel, Anda harus menentukan
spanner.commit_timestamp()
(atau konstanta library klien) untuk kolom stempel waktu
commit di setiap tabel.
Memperbarui baris menggunakan mutasi
Saat memperbarui baris, Spanner hanya menulis nilai stempel waktu commit
jika Anda menyertakan kolom dalam daftar kolom dan meneruskan
string placeholder spanner.commit_timestamp()
(atau konstanta library klien)
sebagai nilainya. Anda tidak dapat memperbarui kunci utama baris. Untuk memperbarui
kunci utama, hapus baris yang ada dan buat baris baru.
Misalnya, untuk memperbarui kolom stempel waktu commit bernama LastUpdateTime
:
C++
C#
Go
Java
Node.js
PHP
Python
Ruby
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
Dalam kode, Anda dapat memberikan nilai Anda sendiri untuk kolom stempel waktu commit
daripada meneruskan spanner.commit_timestamp()
(atau konstanta
library klien yang tersedia) sebagai nilai kolom. Nilai harus berupa stempel waktu di masa lalu. Pembatasan
ini memastikan bahwa penulisan stempel waktu adalah operasi yang murah dan cepat. Salah satu cara untuk mengonfirmasi bahwa nilai berada di masa lalu adalah dengan membandingkannya dengan
nilai yang ditampilkan oleh fungsi SQL CURRENT_TIMESTAMP
. Server 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 int8 NOT NULL,
DocumentId int8 NOT NULL,
Contents text NOT NULL,
PRIMARY KEY (UserId, DocumentId)
);
CREATE TABLE DocumentHistory (
UserId int8 NOT NULL,
DocumentId int8 NOT NULL,
Ts SPANNER.COMMIT_TIMESTAMP NOT NULL,
Delta text,
PRIMARY KEY (UserId, DocumentId, Ts)
) INTERLEAVE IN PARENT Documents;
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
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
menyelang-nyelingi tabel.
Mengoptimalkan kueri data terbaru dengan stempel waktu commit
Stempel waktu commit mengoptimalkan database Spanner Anda dan 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 bigint NOT NULL,
VenueId bigint NOT NULL,
EventDate timestamp with time zone NOT NULL,
Revenue bigint,
LastUpdateTime spanner.commit_timestamp,
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-01-01';