Dalam perancangan skema database, pemilihan strategi penentuan nilai kunci utama merupakan keputusan fundamental yang berdampak langsung pada performa, integritas data, skalabilitas, serta kemudahan integrasi sistem. Setiap pendekatan memiliki karakteristik, kelebihan, dan keterbatasan masing-masing, tergantung pada jenis data, pola akses, dan arsitektur aplikasi yang digunakan. Oleh karena itu, HyperFastApp menyediakan beberapa opsi penentuan nilai kunci utama yang dapat disesuaikan dengan kebutuhan aplikasi, mulai dari mekanisme otomatis yang dikelola database hingga kontrol penuh di sisi pengguna.
HyperFastApp menyediakan 4 pilihan untuk nilai kunci utama atau kunci utama tabel yaitu sebagai berikut:
- Autogenerated
- UUID
- Manual Insert
- Manual All
Keempat pilihan di atas dapat ditentukan pada saat pengguna akan membuat apliakasi, bukan pada saat pengguna membuat skema database. Saat pengguna membuat skema database, pengguna cukup menentukan apakah akan menggunakan tipe data string atau integer pada kunci utama tabel.

Contoh Diagram Hubungan Entitas
Jika tipe kunci utama akan dibuat seragam, pengguna dapat mengaturnya di Preference. Pengaturan ini tidak berlaku surut. Artinya, jika pengguna sudah memiliki beberapa tabel lalu mengubah pengaturan ini, maka tidak akan mempengaruhi tipe kunci utama tabel yang sudah dibuat sebelumnya.

1. Autogenerated
Autogenerated adalah nilai yang otomatis diberikan oleh sistem tanpa bisa diintervensi oleh pengguna. Autogenerated terbagi menjadi 2 yaitu bilangan bulat atau integer dan string.
Autoincrement
Bilangan bulat autogenerated ditangani oleh database. Nilai ini dikenal luas dengan istilah autoincrement. Nilainya selalu naik dimulai dari 1. Pada database MySQL dan MariaDB, data ini disimpan sebagai sebuah properti dari tabel dan dapat diekspor saat tabel diekspor. Pada database PostgreSQL, nilai ini disimpan di sequence yang namanya defaultnya merupakan kombinasi antara nama tabel dan nama kunci utama tabel. Pada database SQLite, nilai ini disimpan pada tabel internal dengan nama sqlite_sequence dengan kolom name dan seq di mana name adalah nama tabel sedangkan seq adalah nilai terakhirnya.
Kelebihan Auto Increment
-
Sederhana dan mudah digunakan
Nilai kuci utama dihasilkan otomatis oleh database tanpa intervensi pengguna, sehingga mengurangi kompleksitas pada sisi aplikasi. -
Performa tinggi
Integer auto increment sangat efisien untuk indexing dan pencarian karena ukurannya kecil dan terurut secara natural. -
Urutan data terjaga
Nilai selalu bertambah, sehingga memudahkan analisis urutan insert, debugging, dan audit data. -
Didukung secara native oleh hampir semua database
MySQL, MariaDB, PostgreSQL, SQL Server, dan SQLite mendukung mekanisme auto increment dengan pendekatan masing-masing. -
Menghemat ruang penyimpanan
Integer membutuhkan storage lebih kecil dibandingkan UUID atau string, sehingga lebih hemat disk dan cache. -
Mudah untuk relasi antar tabel
Foreign key berbasis integer lebih ringan dan lebih cepat dibandingkan foreign key berbasis string. -
Kompatibel dengan ORM dan tool migrasi
Hampir semua ORM (Hibernate, Doctrine, Sequelize, dll.) memiliki dukungan default untuk auto increment.
Kekurangan Auto Increment
-
Tidak aman untuk diekspos ke publik
Nilai yang berurutan mudah ditebak, sehingga berisiko untuk digunakan sebagai identifier publik (misalnya di URL atau API). -
Kurang cocok untuk sistem terdistribusi
Pada sistem multi-node atau distributed system, auto increment sulit disinkronkan tanpa mekanisme tambahan. -
Potensi konflik saat migrasi atau merge data
Menggabungkan data dari beberapa database dapat menyebabkan bentrok nilai kuci utama. -
Ketergantungan pada database
Logika penentuan ID sepenuhnya berada di database, sehingga menyulitkan kontrol penuh dari sisi aplikasi. -
Masalah pada replikasi dan restore tertentu
Dalam beberapa skenario replikasi atau restore, nilai auto increment dapat meloncat atau tidak berurutan. -
Tidak portable antar database tanpa penyesuaian
Implementasi auto increment berbeda-beda (AUTO_INCREMENT, SEQUENCE, IDENTITY, sqlite_sequence), sehingga membutuhkan mapping saat migrasi. -
Tidak menjamin urutan waktu yang presisi
Walaupun nilainya naik, auto increment tidak selalu merepresentasikan urutan waktu secara akurat dalam sistem dengan transaksi paralel. -
Keterbatasan pada database PostgreSQL
Pada database PostgreSQL, nama sequence terbatas bahkan lebih pendek dibandingkan dengan kombinasi nama tabel dan kolom yang diperbolehkan. Itu artinya, pada HyperFastApp, yang mana database dibuat secara otomatis oleh sistem berdasarkan skema yang dibuat oleh pengguna, berpotensi terjadi kesalahan jika nama tabel cukup panjang. Aplikasi harus menangani nama sequence yang tidak standard demi mendapatkan nilai baru kunci utama. -
Keterbatasan pada database SQLite
Pada database SQLite, nilai disimpan pada tabel dengan nama sqlite_sequence yang artinya pengguna dilarang menggunakan nama tersebut sebagai nama tabel aplikasi.
Time-Based
Nilai kunci utama berbasis waktu adalah nilai yang secara otomatis dibuat berdasarkan waktu dengan panjang 20 angka heksadesimal dengan rincian 17 angka heksadesimal mewakili waktu pembuatan dan 3 angka heksadesimal yang diambil secara acak yaitu 000-fff.
Kelebihan Time-Based
-
Tidak bergantung pada database
Nilai kunci utama dihasilkan sepenuhnya oleh aplikasi, sehingga tidak memerlukan fitur khusus dari database (sequence, auto increment, atau trigger). -
Cocok untuk sistem terdistribusi
Karena ID dibuat di sisi aplikasi, beberapa service atau node dapat menghasilkan kuci utama secara paralel tanpa koordinasi ke database. -
Kemungkinan tabrakan sangat kecil
Kombinasi waktu resolusi tinggi dan angka acak (000–fff) membuat collision sangat jarang terjadi dalam praktik. -
Tidak mudah ditebak
Berbeda dengan auto increment, pola ID tidak terlihat jelas sehingga lebih aman untuk diekspos ke publik (URL, API, dsb). -
Portabel antar database
Tidak ada ketergantungan pada mekanisme spesifik database, sehingga lebih mudah dipindahkan antar MySQL, PostgreSQL, SQLite, dan database lainnya. -
Mendukung offline insert
Aplikasi tetap dapat membuat data baru meskipun koneksi ke database sementara tidak tersedia. -
Relatif lebih informatif dibanding UUID acak
Bagian waktu pada ID dapat digunakan untuk perkiraan kapan data dibuat, meskipun tidak presisi.
Kekurangan Time-Based
-
Tidak menjamin urutan absolut
Walaupun berbasis waktu, insert paralel atau perbedaan clock antar server dapat menghasilkan urutan yang tidak sesuai waktu sebenarnya. -
Ketergantungan pada sinkronisasi waktu
Perbedaan jam antar server (clock drift) dapat meningkatkan risiko collision dan menyebabkan urutan data tidak konsisten. -
Ukuran lebih besar dibanding integer
ID berbentuk string 20 karakter membutuhkan storage dan index yang lebih besar dibandingkan integer auto increment. -
Performa index lebih rendah dibanding integer
Index berbasis string cenderung lebih lambat dibandingkan index integer, terutama pada tabel dengan volume data besar. -
Tidak sepenuhnya bebas collision
Meskipun sangat kecil, kemungkinan tabrakan tetap ada karena adanya komponen acak. -
Tidak didukung secara native oleh database
Tidak ada mekanisme database untuk memverifikasi atau mengelola nilai ini; validasi sepenuhnya menjadi tanggung jawab aplikasi. -
Kurang ideal untuk analisis berbasis urutan waktu
Karena urutan ID tidak selalu merepresentasikan urutan waktu aktual, penggunaan ID untuk analisis kronologis dapat menyesatkan.
2. UUID
UUID (Universally Unique Identifier) adalah nilai kunci utama berbentuk string dengan panjang tetap 36 karakter (termasuk tanda -), yang dihasilkan menggunakan algoritma tertentu sehingga memiliki kemungkinan tabrakan yang sangat kecil. UUID umumnya direpresentasikan dalam format heksadesimal 8-4-4-4-12, misalnya:
550e8400-e29b-41d4-a716-446655440000
UUID dapat dihasilkan oleh aplikasi maupun oleh database (tergantung jenis database dan versinya), dan tidak bergantung pada urutan atau kondisi data di dalam tabel.
Kelebihan UUID
-
Kemungkinan tabrakan sangat kecil
UUID dirancang agar unik secara global, sehingga hampir mustahil terjadi duplikasi meskipun data dibuat pada banyak sistem yang berbeda. -
Cocok untuk sistem terdistribusi
UUID dapat dihasilkan secara independen di banyak server atau service tanpa koordinasi pusat. -
Aman untuk diekspos ke publik
Pola UUID tidak berurutan dan sulit ditebak, sehingga aman digunakan sebagai identifier pada URL atau API publik. -
Tidak bergantung pada database
UUID dapat dihasilkan oleh aplikasi tanpa memerlukan fitur khusus dari database. -
Portabel antar database
UUID dapat digunakan secara konsisten di berbagai database seperti MySQL, PostgreSQL, SQLite, dan lainnya. -
Mendukung offline insert
Aplikasi tetap dapat membuat data baru meskipun koneksi ke database belum tersedia. -
Standar industri yang luas digunakan
UUID didukung secara luas oleh bahasa pemrograman, framework, dan ORM modern.
Kekurangan UUID
-
Ukuran besar
UUID membutuhkan storage dan index yang jauh lebih besar dibandingkan integer atau time-based ID. -
Performa index lebih rendah
Index berbasis UUID cenderung lebih lambat karena sifatnya yang acak dan tidak berurutan, sehingga menyebabkan fragmentasi index. -
Tidak merepresentasikan urutan waktu
UUID tidak mengandung informasi waktu sehingga tidak dapat digunakan untuk analisis kronologis. -
Kurang ramah untuk manusia
UUID sulit dibaca, diingat, atau diketik secara manual. -
Overhead jaringan lebih besar
UUID menambah ukuran payload saat dikirim melalui API dibandingkan integer. -
Kurang optimal untuk laporan dan debugging
UUID tidak memberikan konteks urutan atau waktu, sehingga kurang membantu dalam proses analisis manual. -
Beberapa database memerlukan konfigurasi tambahan
Tidak semua database memiliki tipe UUID native; pada beberapa kasus UUID disimpan sebagai CHAR(36) atau VARCHAR, yang kurang efisien. -
Memerlukan kolom tambahan untuk mengurutkan data
Karena UUID tidak merepresentasikan waktu, pengurutan data transaksi memerlukan kolom khusus dan tidak dapat dilakukan hanya dengan menggunakan kunci utama.
Catatan Tambahan
Pada skala besar, penggunaan UUID sebagai kuci utama sebaiknya dipertimbangkan dengan:
- penggunaan UUID v7 atau ULID untuk performa index yang lebih baik
- kombinasi UUID sebagai public ID dan auto increment sebagai internal ID
3. Manual Insert
Manual Insert adalah metode penentuan nilai kunci utama di mana nilai kuci utama ditentukan secara langsung oleh pengguna pada saat pembuatan data. Sistem tidak melakukan pembuatan nilai otomatis dan tidak melakukan modifikasi terhadap nilai yang dimasukkan.
Pendekatan ini umumnya digunakan untuk data referensi (master data) yang jumlahnya terbatas dan memiliki makna semantik yang jelas, seperti:
- kode negara
- kode bahasa
- kode mata uang
- jenjang pendidikan
- kode agama dan kepercayaan
- kode status atau kategori tertentu
Nilai kuci utama pada Manual Insert biasanya berupa string pendek yang memiliki arti khusus dan digunakan secara konsisten di seluruh sistem.
Kelebihan Manual Insert
-
Nilai sepenuhnya dikendalikan oleh pengguna
Pengguna memiliki kontrol penuh atas nilai kunci utama tanpa ketergantungan pada sistem atau database. -
Mudah dibaca dan dipahami manusia
Nilai kuci utama bersifat deskriptif dan representatif, sehingga memudahkan pemahaman, debugging, dan analisis data. -
Stabil dan konsisten lintas sistem
Karena nilainya bersifat eksplisit, Manual Insert sangat cocok untuk integrasi antar sistem dan pertukaran data. -
Tidak bergantung pada mekanisme database tertentu
Dapat digunakan pada semua jenis database tanpa memerlukan fitur auto increment atau sequence. -
Cocok untuk data referensi jangka panjang
Nilai tidak berubah seiring waktu dan tidak dipengaruhi oleh urutan insert.
Kekurangan Manual Insert
-
Berisiko terjadi duplikasi nilai
Tanpa konvensi dan validasi yang ketat, pengguna dapat secara tidak sengaja memasukkan nilai kuci utama yang sama. Meskipun pada akhirnya akan ditolak oleh database, namun ini tetap mengurangi produktivitas. -
Membutuhkan konvensi penamaan yang jelas
Diperlukan aturan mengenai format, panjang, dan pola nilai untuk menjaga konsistensi, terutama jika jumlah data bertambah. -
Kurang cocok untuk data transaksional
Manual Insert tidak praktis untuk data yang dibuat secara masif atau otomatis dalam jumlah besar. -
Performa index lebih rendah dibanding integer
Jika menggunakan string sebagai kuci utama, performa indexing dan relasi cenderung lebih lambat dibandingkan integer. -
Pengurutan data tidak selalu intuitif
Urutan alfabetik pada kuci utama belum tentu mencerminkan urutan prioritas atau logika bisnis. -
Sering memerlukan kolom tambahan untuk pengurutan
Dalam banyak kasus, dibutuhkan kolom khusus (misalnya sort_order atau priority) untuk mengatur urutan data.
4. Manual All
Manual All adalah metode penentuan nilai kunci utama di mana pengguna dapat menentukan dan mengubah nilai kuci utama, baik pada saat pembuatan data maupun setelah data tersebut tersimpan.
Dalam pendekatan ini, kunci utama diperlakukan sebagai data biasa yang dapat dimodifikasi. Beberapa sistem database secara teknis mengizinkan perubahan nilai kuci utama, terutama pada tabel referensi atau master data tertentu.
Pendekatan ini memberikan fleksibilitas maksimum, tetapi juga membawa konsekuensi besar terhadap integritas dan konsistensi data.
Kelebihan Manual All
-
Memiliki seluruh kelebihan Manual Insert
Semua keunggulan pada metode Manual Insert tetap berlaku, termasuk keterbacaan, makna semantik, dan kontrol penuh oleh pengguna. -
Fleksibilitas maksimal
Pengguna dapat memperbaiki kesalahan penentuan kunci utama tanpa harus menghapus dan membuat ulang data. -
Cocok untuk data referensi yang dapat berevolusi
Dalam beberapa kasus bisnis, kode referensi memang berubah mengikuti regulasi, standar eksternal, atau kebijakan organisasi. -
Mengurangi duplikasi data akibat kesalahan awal
Perubahan kuci utama memungkinkan koreksi langsung tanpa menciptakan data baru yang hampir identik. -
Lebih ramah untuk data yang dikurasi manual
Sesuai untuk sistem dengan pengelolaan data yang sangat dikontrol dan jumlah perubahan relatif kecil.
Kekurangan Manual All
-
Risiko tinggi terhadap integritas data
Perubahan kuci utama dapat memutus relasi foreign key jika tidak ditangani dengan benar. -
Membutuhkan mekanisme propagasi perubahan
Jika kuci utama berubah, semua tabel yang mereferensikannya harus ikut diperbarui, baik melalui:- cascade update
- trigger
- event khusus
- atau logika aplikasi
-
Kompleksitas tinggi pada sisi aplikasi
Aplikasi harus secara eksplisit menangani perubahan kunci utama, yang meningkatkan kompleksitas kode dan potensi bug. -
Kurang didukung oleh ORM
Sebagian besar ORM (Hibernate, Doctrine, Sequelize, dll.) mengasumsikan bahwa kuci utama bersifat immutable dan tidak menyediakan dukungan bawaan untuk mengubahnya. -
Berisiko menimbulkan inkonsistensi data historis
Data historis atau log audit dapat kehilangan keterkaitan jika kuci utama berubah tanpa pencatatan yang tepat. -
Tidak cocok untuk data transaksional
Manual All sangat berbahaya jika digunakan pada tabel transaksi atau tabel dengan volume data besar. -
Menyulitkan caching dan indexing
Perubahan kuci utama dapat mengacaukan cache, index, dan referensi internal pada sistem.
Catatan Penggunaan
Manual All hanya disarankan untuk:
- tabel referensi tertentu
- data master dengan volume kecil
- sistem dengan kontrol perubahan data yang ketat
- pengguna berpengalaman dengan konsekuensi perubahan kunci utama
Manual All tidak disarankan untuk:
- tabel transaksi
- sistem dengan ORM berat
- sistem dengan banyak relasi foreign key
- arsitektur microservices tanpa koordinasi ketat