Topik ini menjelaskan cara menulis stempel waktu commit untuk setiap operasi penyisipan dan pembaruan yang Anda lakukan dengan Spanner.
Ringkasan stempel waktu commit
Stempel waktu commit, berdasarkan teknologi TrueTime, adalah waktu ketika 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 fitur build seperti log perubahan.
Untuk menyisipkan stempel waktu commit ke 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 pembaruan dengan DML, gunakan fungsi
SPANNER.PENDING_COMMIT_TIMESTAMP()
untuk menulis stempel waktu commit.Jika Anda melakukan penyisipan atau pembaruan dengan pernyataan atau mutasi yang telah 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 pada klien Java ini adalahValue.COMMIT_TIMESTAMP
.
Saat Spanner meng-commit transaksi dengan menggunakan placeholder ini sebagai nilai kolom, stempel waktu commit yang sebenarnya akan ditulis ke kolom yang ditentukan. Anda kemudian dapat menggunakan nilai kolom ini untuk membuat histori pembaruan pada tabel.
Nilai stempel waktu commit tidak dijamin akan 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) - Tombol menaik ideal untuk menjawab kueri dari waktu tertentu ke depan.DESC
- Kunci menurun menyimpan baris terbaru di bagian atas tabel. Dasbor ini memberikan akses cepat ke data terbaru.
Menghindari hotspot
Menggunakan stempel waktu commit dalam skenario berikut akan membuat hotspot, yang mengurangi performa data:
Meng-commit kolom stempel waktu sebagai bagian pertama dari kunci utama tabel.
CREATE TABLE Users ( LastAccess SPANNER.COMMIT_TIMESTAMP NOT NULL, UserId INT64 NOT NULL, ... PRIMARY KEY (LastAccess, UserId) ) ;
Meng-commit kolom kunci utama stempel waktu sebagai bagian pertama dari 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 commit 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 sudah 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
NOT NULL;
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 commit transaksi.
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 akan 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 memiliki mutasi pada baris dalam 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 akan 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. 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 memiliki mutasi pada baris dalam beberapa tabel, Anda harus menentukan spanner.commit_timestamp()
(atau konstanta library klien) untuk kolom stempel waktu commit di setiap tabel.
Mengkueri kolom stempel waktu commit
Contoh berikut mengkueri kolom stempel waktu commit dalam tabel.
C++
C#
Go
Java
Node.js
PHP
Python
Ruby
Berikan nilai Anda sendiri untuk kolom stempel waktu commit
Dalam kode, Anda dapat memberikan nilai sendiri untuk kolom stempel waktu commit,
bukan meneruskan spanner.commit_timestamp()
(atau konstanta library klien
yang tersedia) sebagai
nilai kolom. Nilai harus berupa stempel waktu di masa lalu. Batasan ini
memastikan bahwa penulisan stempel waktu adalah operasi yang murah dan cepat. Cara
mudah untuk mengonfirmasi bahwa nilai berada di masa lalu
adalah membandingkannya dengan nilai yang ditampilkan oleh fungsi SQL CURRENT_TIMESTAMP
.
Server menampilkan error FailedPrecondition
jika stempel waktu di masa mendatang ditentukan.
Membuat {i>changelog<i}
Anggaplah Anda ingin membuat log perubahan untuk setiap mutasi yang terjadi pada tabel, lalu menggunakan log perubahan tersebut untuk mengaudit. Contohnya adalah tabel yang menyimpan riwayat perubahan pada dokumen pengolahan kata. Stempel waktu commit mempermudah pembuatan log perubahan, karena stempel waktu dapat memberlakukan pengurutan entri log perubahan. Anda dapat membuat log perubahan yang menyimpan histori perubahan pada dokumen tertentu menggunakan skema seperti dalam 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 tempat Anda menyisipkan atau memperbarui baris di Document
. Dalam penyisipan
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
. Menggabungkan
tabel DocumentsHistory
dengan tabel Documents
akan memungkinkan lokalitas
data serta penyisipan dan pembaruan yang lebih efisien. Namun, cara ini juga menambahkan batasan sehingga baris induk dan turunan harus dihapus bersama. Untuk mempertahankan baris di DocumentHistory
setelah baris
di Documents
dihapus, jangan menyisipkan tabel.
Mengoptimalkan kueri data terbaru dengan stempel waktu commit
Commit stempel waktu mengaktifkan 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 konstan: literal, parameter, atau fungsi yang argumennya sendiri dievaluasi ke konstanta.
Bandingkan apakah stempel waktu commit lebih baru daripada waktu tertentu, melalui operator
>
atau>=
.Secara opsional, tambahkan pembatasan lebih lanjut ke klausa
WHERE
denganAND
. Memperluas klausa denganOR
akan mendiskualifikasi kueri dari pengoptimalan ini.
Misalnya, perhatikan tabel Performances
berikut, yang menyertakan 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 mendapatkan manfaat dari pengoptimalan stempel waktu commit yang dijelaskan sebelumnya, karena memiliki perbandingan yang lebih besar dari atau sama dengan antara kolom stempel waktu commit tabel dan ekspresi konstan—dalam hal ini, literal:
SELECT * FROM Performances WHERE LastUpdateTime >= '2022-01-01';