Ketika merancang skema database, salah satu keputusan penting adalah memilih jenis primary key yang digunakan. Dua opsi yang paling umum adalah INT auto increment dan UUID. Keduanya memiliki kelebihan dan kekurangan, tergantung kebutuhan aplikasi.
1. INT Auto Increment
Kelebihan:
- Ringan & efisien: Ukuran lebih kecil (4/8 byte), index lebih ramping.
- Performa tinggi: Query join dan lookup berdasarkan primary key biasanya lebih cepat.
- Mudah dipahami: Nilai sequential, gampang dibaca dan diprediksi.
- Optimal untuk sistem terpusat: Cocok jika database hanya berjalan pada satu server.
Kekurangan:
- Kurang aman untuk public exposure: Mudah ditebak (misalnya ID 101 → 102).
- Potensi konflik pada sistem distributed: Beberapa server bisa menghasilkan ID yang sama.
- Migrasi data: Lebih sulit jika menggabungkan data dari beberapa sumber.
2. UUID (Universally Unique Identifier)
Kelebihan:
- Unik secara global: Tidak perlu khawatir tabrakan meski data dibuat di server berbeda.
- Lebih aman untuk di-expose: Sulit ditebak dibanding INT.
- Mudah untuk migrasi: Tidak butuh remapping ID ketika menggabungkan data.
- Skalabilitas lebih baik: Ideal untuk sistem distributed dan multi-region.
Kekurangan:
- Lebih besar: 16 byte, membuat index lebih berat.
- Kurang efisien di query: Lookup dan join lebih lambat dibanding INT.
- Fragmentasi index: UUID v4 bersifat acak, insert bisa tersebar di seluruh index tree.
- Kurang ramah manusia: Sulit dibaca atau dikelola manual.
3. Dampak pada Indexing
PostgreSQL (dan MySQL) menggunakan B-Tree index secara default:
- INT → sequential, insert selalu di ujung, sangat efisien.
- UUID v4 (random) → insert acak, menyebabkan fragmentasi index.
Solusi mitigasi UUID:
- Gunakan UUID v1/v7 (time-based/ordered) agar lebih terurut.
- Alternatif lain: ULID/KSUID.
4. Masalah Keamanan ID
-
INT → mudah ditebak. Resource publik (seperti
/users/124
) jadi gampang diakses. - UUID → lebih aman untuk exposed identifier.
Catatan: Meski validasi otorisasi bisa menahan akses ilegal, UUID tetap lebih baik sebagai identifier publik karena sulit ditebak.
5. Pola Hybrid: Best of Both Worlds
Banyak sistem besar memakai pola gabungan:
CREATE EXTENSION IF NOT EXISTS "pgcrypto";
CREATE TABLE users (
id BIGSERIAL PRIMARY KEY, -- internal PK untuk efisiensi DB
public_id UUID UNIQUE NOT NULL DEFAULT gen_random_uuid(), -- exposed ke client
name TEXT
);
-- Index hash khusus untuk public_id
CREATE INDEX idx_users_public_id_hash
ON users USING hash (public_id);
- INT → dipakai untuk operasi internal (join, relasi, FK).
- UUID → dipakai untuk public identifier.
-
Index Hash → efisien untuk query exact match (
WHERE public_id = ...
).
Dengan pola ini:
- Database tetap efisien.
- Public API lebih aman.
- Overhead penyimpanan tambahan masih dalam batas wajar.
6. Alternatif UUID
Selain UUID, ada opsi lain untuk identifier unik:
- UUID v7 → lebih terurut, mengurangi fragmentasi index.
- ULID/KSUID → unik global, tetap preserve urutan waktu.
- Snowflake ID → integer 64-bit unik global (banyak dipakai di sistem besar seperti Twitter).
Kesimpulan
- Gunakan INT Auto Increment untuk internal PK jika performa DB jadi prioritas.
- Gunakan UUID/ULID untuk public exposure agar lebih aman.
- Kombinasi keduanya dengan strategi indexing (B-Tree untuk INT, Hash Index untuk UUID) memberi keseimbangan terbaik.
💡 Praktik terbaik:
"PK internal = INT, Public ID = UUID dengan hash index."
Dengan begitu, performa database tetap optimal, dan aplikasi tetap aman saat mengekspose identifier ke publik.
Top comments (0)