Apa kelemahan menggunakan UUID atau GUID sebagai kunci utama?

61

Saya ingin membangun sistem terdistribusi. Saya perlu menyimpan data dalam database dan akan sangat membantu jika menggunakan UUID atau GUID sebagai kunci utama pada beberapa tabel. Saya menganggap itu adalah kelemahan dengan desain ini karena UUID / GUID cukup besar dan hampir acak. Alternatifnya adalah dengan menggunakan INT atau LONG yang bertambah otomatis.

Apa kekurangannya dengan menggunakan UUID atau GUID sebagai kunci utama untuk tabel saya?

Saya mungkin akan menggunakan Derby / JavaDB (di klien) dan PostgreSQL (di server) sebagai DBMS.

Jonas
sumber
Mengapa ini membantu? Apa kekurangan yang paling Anda fokuskan? Jawaban untuk setiap Pertanyaan DB yang tidak jelas ini adalah "itu tergantung." Bisakah Anda memberi kami detail lebih lanjut? Apakah Anda paling tertarik dengan kinerja membaca atau menulis? tingkat distribusi apa yang sedang kita bicarakan?
Brian Ballsun-Stanton
@Brian: UUID dalam sistem terdistribusi sangat membantu karena Anda dapat membuat kunci utama pada klien dan kemudian mengunggah data secara tidak sinkron ke server. Saya kebanyakan berpikir tentang kelemahan kinerja baca. Menggunakan banyak GABUNGAN pada UUID mungkin tidak sebagus itu? Dalam contoh klien menambahkan item (UUID, nama, pemasok, pencipta) ke sistem inventaris, dan kemudian database lokal disinkronkan dengan database pusat di server.
Jonas
1
Saya pikir tanpa beberapa komentar yang lebih jelas tentang hal ini yang paling banyak akan "tergantung". Tanpa itu, saya akan menggunakan VtC.
jcolebrand
Ada sebuah artikel yang berbicara tentang GUID vs non-GUID mempengaruhi indeks berkerumun di SQL Server yang mungkin Anda temukan menarik meskipun itu terkait dengan produk SQL yang berbeda: x.co/Twpp
Jeff
Saya perhatikan bahwa Derby doc tidak mencantumkan UUID sebagai tipe data. Anda mungkin ingin mempertimbangkan alternatif seperti H2 Database Engine (database Java murni seperti Derby) yang memang mencantumkan tipe data UUID . Tentu saja Postgres memang memiliki dukungan yang sangat baik untuk menyimpan , mengindeks, dan menghasilkan nilai UUID secara efisien .
Basil Bourque

Jawaban:

29

Itu tergantung pada fungsi generasi Anda dan ukuran tabel akhir

GUID dimaksudkan untuk menjadi pengidentifikasi unik secara global . Seperti yang dibahas dalam dokumentasi Postgres 8.3 tidak ada metodologi yang secara universal sesuai untuk menghasilkan pengidentifikasi ini, tetapi postgreSQL tidak dikirimkan dengan beberapa kandidat yang lebih berguna.

Dari ruang lingkup masalah Anda, dan kebutuhan akan penulisan offline , Anda telah dengan rapi mengotak-atik penggunaan apa pun selain GUID, dan oleh karena itu tidak ada keuntungan kompensasi dari skema lain.

Dari sudut pandang fungsional, panjang kunci biasanya tidak menjadi masalah pada segala jenis sistem modern, tergantung pada jumlah bacaan dan ukuran tabel. Sebagai metodologi alternatif, klien offline dapat mengumpulkan catatan baru tanpa kunci primer dan cukup memasukkannya saat menghubungkan kembali. Karena postgreSQL menawarkan tipe data "Serial", klien tidak perlu menentukan ID jika mereka dapat melakukan penulisan sederhana ke database.

Brian Ballsun-Stanton
sumber
3
Sialan kamu tidur, kamu sudah pergi dan membiarkan Brian menjawab pertanyaan itu. Ya, persyaratan untuk "pembaruan offline" benar-benar mengubah keseluruhan konsep di sana.
jcolebrand
Muahahahaah! ::
Twirls Moustache Evilly
1
Bahkan dengan offline-menulis akan mungkin untuk menggunakan INT. Misalnya menggunakan dua kolom di {Node_ID, Item_ID}mana setiap node memiliki Node_ID, dan Item_IDyang secara otomatis bertambah per node.
Jonas
@Jonas ~ Ya, itu layak. Namun, salah satu alasan kebanyakan orang bahkan merenungkan GUID adalah untuk replikasi konten yang dipisahkan secara global ke database lain. Maksud saya istilah itu sendiri agak QED di sana.
jcolebrand
Sehubungan dengan arsitektur master / slave atau klien koneksi-jarang + arsitektur server utama, mungkinkah menggunakan global_id (SERIAL) pada master dan global_id (BIGINT) + local_id (SERIAL) pada slave. Budak melakukan pekerjaan lokal mereka menggunakan local_id dan komit ketika mereka dapat menuju master, master menerima data dan memberikannya global_id yang dikembalikan ke slave, perbaruan budak global_id bidang (untuk penggunaan referensi dalam berbicara dengan server atau ke yang lain budak).
Mihai Stancu
22

Satu saran lagi - jangan pernah menggunakan GUID sebagai bagian dari indeks berkerumun. GUID tidak berurutan, jadi jika itu adalah bagian dari indeks berkerumun, setiap kali Anda memasukkan catatan baru, basis data akan perlu mengatur ulang semua halaman memorinya untuk menemukan tempat yang tepat untuk penyisipan, dalam kasus dengan peningkatan otomatis int (bigint), itu akan menjadi halaman terakhir.

Sekarang jika kita melihat beberapa realisasi db: 1.) MySQL - kunci utama dikelompokkan, tanpa opsi untuk mengubah perilaku - rekomendasi tidak menggunakan GUID sama sekali di sini 2.) Postgres, MS-SQL - Anda dapat menjadikan GUID sebagai kunci utama tidak acak, dan gunakan bidang lain sebagai indeks berkerumun, misalnya int autoincrement.

Ross Ivantsiv
sumber
Apa yang Anda usulkan untuk Postgres dapat dilakukan di MySQL juga, dengan struktur yang sedikit berbeda - auto_increment PK (kunci berkerumun), GUID dengan indeks unik (tidak terbelah).
ypercubeᵀᴹ
Ini tidak selalu benar. Bergantung pada throughput sistem disk, menyinkronkan akses ke halaman terakhir itu mungkin menjadi hambatan Anda. blog.kejser.org/2011/10/10/05 ...
mwilson
2
"Tidak seperti Microsoft SQL Server, pengelompokan pada indeks di PostgreSQL tidak mempertahankan urutan itu. Anda harus mengajukan permohonan kembali proses CLUSTER untuk mempertahankan pesanan." Bagaimana CLUSTER ON meningkatkan kinerja indeks
bartolo-otrit
Versi informasi @ bartolo-otrit yang lebih ringkas yang ditautkan ke: stackoverflow.com/a/4796685/1394393 . Jawaban ini benar-benar tampaknya tidak relevan bagi saya, karena pertanyaan ini tentang PG dan tampaknya mengasumsikan kesamaan dengan SQL Server dan MySQL yang tidak ada.
jpmc26
database would need to rearrange all its memory pages to find the right place for insertion=> Saya tidak berpikir demikian halnya dengan Postgres, karena pengelompokan adalah opsional dan baris baru disimpan tanpa urutan.
Flavien
3

Tergantung.

Serius, dengan semua yang Anda berikan sejauh ini, ini adalah tentang sejauh yang Anda bisa lakukan.

Mengapa bermanfaat jika menggunakan UUID? Mengapa Anda tidak akan menggunakan INT? Mengapa Anda tidak bisa hanya mengindeks UUID nanti? Apakah Anda mengerti apa artinya memiliki daftar yang disortir dengan kunci UUID dan memasukkan UUID acak (tidak berurutan) setelah beberapa juta baris?

Platform apa yang akan dijalankan ini? Berapa banyak disk? Berapa banyak pengguna? Berapa banyak catatan?

jcolebrand
sumber
7
Seperti yang saya tulis dalam komentar saya, jika saya menggunakan UUID klien dapat menambahkan baris ke database tanpa koneksi ke server, dan kemudian disinkronkan dengan server. Saya tidak bisa melakukan itu jika saya menggunakan INT untuk kunci utama, karena beberapa klien dapat menggunakan kunci utama yang sama untuk item yang berbeda. Yah, tidak ada gunanya untuk mengurutkan daftar pada kolom UUID, akan lebih berguna untuk mengurutkannya pada kolom stempel waktu. Tidak, saya tidak tahu apa artinya memasukkan UUID acak tanpa sekuensial setelah beberapa juta baris, itu sebabnya saya mengajukan pertanyaan ini.
Jonas
Aplikasi akan ditulis dalam Java dan klien saya menggunakan Windows, Mac atau Linux. Klien akan menggunakan komputer desktop umum yang biasanya memiliki satu disk. Jumlah pengguna dan catatan tergantung pada berapa banyak pelanggan yang saya dapatkan, tetapi itu akan menjadi sekitar 5.000 per klien dan pelanggan.
Jonas
1
Komentar offline mengubah segalanya. Lihat apa rincian lebih lanjut?
jcolebrand