Membuat pengidentifikasi unik untuk setiap baris dalam tabel merupakan kebutuhan umum dalam desain database, mirip dengan fitur AUTO_INCREMENT di MySQL. Di PolarDB for PostgreSQL Distributed Edition, Anda dapat menggunakan objek sekuens dengan tipe seperti SERIAL atau BIGSERIAL untuk mengimplementasikan fitur ini. Namun, memastikan bahwa ID yang dihasilkan di seluruh node bersifat unik secara global merupakan tantangan dalam lingkungan terdistribusi. PolarDB menyediakan mekanisme implementasi berbeda untuk mengatasi tantangan tersebut. Perilaku dan batasan mekanisme ini bergantung pada tipe sekuens yang Anda pilih, yang terutama ditentukan oleh ukuran bilangan bulatnya.
Perbedaan tipe sekuens
Sebelum memilih tipe sekuens untuk tabel terdistribusi, tinjau perbedaan utama dalam tabel berikut untuk membuat keputusan yang tepat.
Atribut | Sekuens 64-bit ( | Sekuens 16-bit/32-bit ( |
Penggunaan yang direkomendasikan | Sangat direkomendasikan untuk semua tabel terdistribusi. | Tidak direkomendasikan untuk tabel terdistribusi, kecuali jika Anda dapat menerima batasannya. |
Implementasi | Generasi terdistribusi: ID terdiri dari | Generasi terpusat: Permintaan pembuatan ID harus diarahkan ke node komputasi utama (CN utama). |
Pembuatan ID | - Dapat dihasilkan di node komputasi mana pun (CN). - Unik secara global, tetapi tidak dijamin berurutan. | - Hanya dapat dihasilkan di CN utama. - Berurutan saat dihasilkan di CN utama. |
Batasan utama | Nilai ID yang dihasilkan memiliki celah besar ketika dibuat di node sumber yang berbeda. | Mencoba menghasilkan ID di node selain CN utama akan menghasilkan kesalahan. |
Perilaku terperinci dan contoh
Sekuens 64-bit
Ini adalah cara yang direkomendasikan untuk menghasilkan ID unik untuk tabel terdistribusi.
Cara kerjanya
Untuk menghasilkan ID secara aman di semua node, PolarDB for PostgreSQL Distributed Edition membagi ruang bilangan bulat 64-bit. 16 bit orde tinggi menyematkan ID unik dari node saat ini. 48 bit orde rendah digunakan untuk nilai sekuens yang bertambah di node tersebut. Struktur ini memastikan bahwa ID yang dihasilkan dari node berbeda tidak pernah bentrok.
Analisis perilaku
Keuntungan: Anda dapat menjalankan operasi
INSERTdi node komputasi mana pun, seperti CN utama atau sekunder. Hal ini memberikan ketersediaan tinggi dan throughput tinggi.Catatan: Karena ID berisi informasi node, penyisipan data di node berbeda menyebabkan lompatan besar pada nilai ID. Nilai-nilai tersebut tidak berurutan secara numerik.
Contoh
-- Buat tabel terdistribusi yang menggunakan BIGSERIAL
CREATE TABLE student (id BIGSERIAL, name TEXT);
SELECT create_distributed_table('student', 'id');
-- (Terhubung ke CN utama) Sisipkan dua baris data
INSERT INTO student (name) VALUES ('Alice'); -- id: 1
INSERT INTO student (name) VALUES ('Bob'); -- id: 2 (berurutan)
-- (Alihkan koneksi ke CN sekunder) Sisipkan satu baris data lagi
INSERT INTO student (name) VALUES ('Charlie'); -- id: 281474976710657 (terjadi lompatan)
-- Lihat hasilnya
=> SELECT * FROM student ORDER BY id;
id | name
-------------------+---------
1 | Alice
2 | Bob
281474976710657 | Charlie
(3 baris)ID 281474976710657 tampak sebagai angka yang sangat besar. Representasi binernya mengungkap strukturnya: ID node 16-bit (0000000000000001) diikuti oleh nilai sekuens 48-bit (000...0001). Ini merepresentasikan ID pertama yang dihasilkan di node 1.
Sekuens 16-bit/32-bit
Karena ruang bilangan bulat terbatas, tipe-tipe ini tidak dapat menyematkan ID node untuk generasi terdistribusi. Oleh karena itu, mereka menggunakan strategi generasi terpusat.
Cara kerjanya
Untuk memastikan keunikan global, semua permintaan pembuatan ID untuk sekuens 16-bit atau 32-bit harus diarahkan ke dan diproses oleh node komputasi utama (CN utama).
Analisis perilaku
Keuntungan: ID yang dihasilkan di CN utama bersifat berurutan. Ini sesuai dengan perilaku database mandiri.
Batasan: Anda tidak dapat menjalankan operasi
INSERTyang memicu pembuatan ID di node selain CN utama, seperti CN sekunder atau node data (DN). Tindakan ini menyebabkan kesalahanoperation is not allowed on this node.
Contoh
-- Buat tabel terdistribusi yang menggunakan SERIAL
CREATE TABLE animal (id SERIAL, name TEXT);
SELECT create_distributed_table('animal', 'id');
-- (Terhubung ke CN utama) Sisipkan data. Operasi berhasil.
INSERT INTO animal (name) VALUES ('cat'); -- id: 1
SELECT * FROM animal;
id | name
----+------
1 | cat
(1 baris)
-- (Alihkan koneksi ke CN sekunder) Coba sisipkan data. Operasi gagal.
INSERT INTO animal (name) VALUES ('dog');
ERROR: nextval(sequence) calls in worker nodes are not supported for column defaults of type int or smallint
HINT: If the command was issued from a worker node, try issuing it from the coordinator node instead.Pesan kesalahan tersebut dengan jelas menyatakan bahwa pemanggilan nextval (untuk menghasilkan nilai sekuens) untuk kolom int atau smallint tidak didukung di node pekerja, seperti CN sekunder.
Rangkuman dan praktik terbaik
Selalu gunakan
BIGSERIAL. Saat merancang ID auto-increment untuk tabel terdistribusi, pilihBIGSERIALatau kolomIDENTITYyang berbasisBIGINT.Terima ID yang tidak berurutan. Saat menggunakan
BIGSERIAL, logika bisnis Anda tidak boleh bergantung pada ID yang benar-benar berurutan. Keunikan dan peningkatan monotonik ID dijamin di satu node.Gunakan
SERIALdengan hati-hati. GunakanSERIALatauSMALLSERIALhanya jika skenario bisnis Anda dapat menerima semua operasi tulis diarahkan melalui CN utama dan jika ketersediaan menulis di CN sekunder bukan menjadi perhatian.