Penggunaan ID, UUID, ULID pada Laravel


Dalam dunia pengembangan aplikasi web, pemilihan metode yang tepat untuk mengelola identifier unik adalah kunci dalam memastikan skalabilitas, keamanan, dan efisiensi sistem. Laravel, sebagai salah satu framework PHP yang paling populer, menawarkan fleksibilitas dalam menggunakan berbagai jenis identifier unik, termasuk ID auto increment biasa, UUID, dan ULID. 

Secara default, pengaturan identifier yang digunakan aplikasi laravel adalah ID, yaitu primary key yang bertipe integer dan mengimplementasikan auto increment setiap kali terdapat data baru dalam database. Selain ID, terdapat juga identifier unik yang ditawarkan oleh laravel yaitu UUID dan ULID. UUID (Universally Unique Identifier) adalah identifier 128-bit yang digunakan untuk mengidentifikasi informasi secara unik dalam sistem yang terdistribusi tanpa perlu koordinasi pusat. UUID biasanya direpresentasikan dalam format string dengan panjang 36 karakter, misalnya: “123e4567-e89b-12d3-a456-426614174000”. Sedangkan ULID (Universally Unique Lexicographically Sortable Identifier) adalah identifier yang mirip dengan UUID namun dengan beberapa perbedaan penting, seperti kemampuannya untuk diurutkan secara leksikografis dan lebih pendek (26 karakter). ULID menggabungkan waktu dan random bytes sehingga lebih mudah diurutkan berdasarkan waktu. Contoh ULID: “01gd4d3tgrrfqeda94gdbtdk5c”. Setiap tipe primary key ini memiliki kelebihan dan kekurangan yang berbeda, serta kasus penggunaan yang spesifik.

Implementasi ID dengan auto increment

Penggunaan ID pada laravel sudah sangat umum digunakan. Cara menggunakannya pun sangat mudah. Ketika membuat migration baru pada laravel, default primary key nya adalah ID, contohnya sebagai berikut:

Schema::create(‘users’, function (Blueprint $table) {

            $table->id();

            $table->string(‘name’);

            $table->string(’email’)->unique();

            $table->timestamp(’email_verified_at’)->nullable();

            $table->string(‘password’);

            $table->rememberToken();

            $table->timestamps();

        });

Dalam membuat table users primary key yang digunakan adalah ID. Cukup gunakan syntax $table->id() maka primary key yang akan digunakan pada table users adalah ID dengan auto increment.

Sebagai contoh terdapat list user yang terdapat pada table users. ID yang terbentuk bertipe integer dimana setiap kali data baru ditambahkan maka ID akan otomatis bertambah dengan tujuan setiap baris memiliki kolom yang bernilai unik dari lainnya.

Metode ini sudah sangat umum. Kelebihannya antara lain mudah digunakan, ukuran database kecil, kinerja pencarian dan penyimpanan sangat cepat. Meskipun begitu penggunaan ID juga memiliki kekurangan yaitu mudah ditebak, tidak unik secara global, dan level keamanan yang rentan. Hal ini karena ID akan selalu bertipe integer yang mudah ditebak.

Implementasi UUID

Untuk menggunakan UUID di laravel caranya adalah dengan memanfaatkan trait HasUuids dan membuat kolom bertipe uuid. Berikut contohnya:

use Illuminate\Database\Eloquent\Concerns\HasUuids;

class User extends Authenticatable

{

use HasUuids;
}

Gunakan trait HasUuids pada model User untuk mengkonfigurasikan table users akan mengimplementasikan UUID pada tablenya. Berikut contoh migration:

Schema::create(‘users’, function (Blueprint $table) {

            $table->uuid(‘id’)->primary();

            $table->string(‘name’);

            $table->string(’email’)->unique();

            $table->timestamp(’email_verified_at’)->nullable();

            $table->string(‘password’);

            $table->rememberToken();

            $table->timestamps();

        });

Syntax yang digunakan adalah $table->uuid(‘id)->primary(). Berbeda dengan ID, jenis kolom uuid() tidak mengimplementasikan primary key secara default. Oleh karena itu perlu dideklarasikan secara eksplisit.

Dari contoh diatas identifier yang digunakan adalah UUID. UUID yang tergenerate memiliki panjang 36 karakter dengan kombinasi angka dan huruf. Dengan UUID yang kompleks ini tentunya akan meningkatkan level keamanan menjadi lebih tinggi dan tidak rentan. UUID tidak mudah ditebak karena identifiernya bersifat unik secara global, berbeda dengan ID biasa. Meski begitu terdapat juga hal yang menjadi kelemahan UUID yaitu ukuran database akan menjadi lebih besar dan kinerja penyimpanan lebih lambat dari biasanya. Selain itu UUID bersifat tidak sequence, artinya kolom yang bertipe UUID tidak bisa melakukan fungsi sorting. 

Implementasi ULID

Penggunaan ULID pada laravel tidak jauh berbeda dengan UUID. Tambahkan trait HasUlids pada model User dan buat kolom dengan jenis ulid() pada migration. Berikut contohnya:

use Illuminate\Database\Eloquent\Concerns\HasUlids;

class User extends Authenticatable

{

use HasUlids;
}

Hasil ULID mirip dengan UUID yaitu kombinasi antara angka dan huruf. Panjang dari ULID sedikit lebih pendek dari UUID yaitu 26 karakter. Panjang karakter tersebut sudah cukup agar ULID tidak mudah ditebak sehingga tingkat keamanannya cukup tinggi. Dikarenakan panjang karakter dari ULID sebenarnya cukup panjang maka ukuran database juga akan membesar, namun jika dibandingkan dengan UUID ukuran database ULID lebih rendah. Kompleksitas ULID juga tidak setinggi UUID sehingga kinerja pencarian dan penyimpanan lebih cepat. Dalam proses generate ULID, beberapa karakter yang tergenerate diambil dari variabel waktu. Hal ini membuat ULID bisa support fungsi sorting. Hal yang paling membedakan UUID dengan ULID memang dari bagaimana value yang dihasilkan dapat diurutkan atau tidak. ULID dapat diurutkan secara leksikografis.

Penggunaan Foreign Key untuk masing-masing identifier

Cara menggunakan masing-masing identifier agar dapat dijadikan sebagai foreign key dapat dicek di dokumentasi resmi laravel disini. Terdapat jenis kolom untuk masing masing identifier yaitu foreignId(), foreignUuid(), foreignUlid(). Berikut contohnya:

Schema::create(‘invoices’, function (Blueprint $table) {

            $table->id();

            $table->foreignUlid(‘user_id’);

            $table->string(‘code’);

            $table->integer(‘amount’);

            $table->text(‘note’);

            $table->timestamps();

        });

Pembuatan foreign key dapat disesuaikan berdasarkan jenis identifier yang dipakai. Seperti contoh diatas terdapat migration untuk membuat table invoices yang memiliki foreign key ke user_id dimana id pada table users bertipe ulid().

Kesimpulan

Penggunaan setiap identifier memiliki kelebihan dan kekurangan masing masing. Setiap identifier ada yang sangat cocok pada kasus tertentu. ID sangat cocok untuk aplikasi yang masih cukup kecil dimana setiap datanya mungkin tidak memerlukan global unik. UUID cocok jika id dari suatu data di table ditampilkan ke dalam url sebagai dinamis parameter. Hal ini mengakibatkan orang luar tidak dapat menebak id yang lain karena sangat acak strukturnya. Dengan adanya kompleksitas struktur id maka ini juga akan cocok jika suatu aplikasi membutuhkan global unik tiap datannya. Tapi juga perlu diketahui bahwa resiko yang muncul adalah ukurang database karena untuk menyimpan setiap data ukuran yang diperlukan akan lebih besar. Penggunaan ULID bisa dikatakan mungkin berada di tengah-tengah dari ID dan UUID. Secara keamanan ULID lebih tinggi dari ID. Ukuran database tidak setinggi UUID karena panjang karakternya lebih sedikit. ULID juga dapat memungkinkan fungsi sorting. Sebagai tips tambahan juga penggunaan ID, UUID, dan ULID bisa dikombinasikan sesuai kebutuhan tiap tablenya. Mungkin sebagai contoh pada aplikasi web terdapat url profile dari tiap usernya dimana pada url akan disertakan id dari tiap usernya, maka hal ini akan lebih baik menggunakan UUID atau ULID. Namun jika hanya misal terdapat table role yang memiliki relasi dengan user. Pada table user hanya membutuhkan id dari tiap data pada table role, maka itu cukup menggunakan ID saja. Implementasi ini bisa mengurangi kelemahan tiap identifier sehingga tiap identifier bisa dimanfaat dengan baik.

Refrensi:
https://laravel.com/docs/11.x/eloquent#uuid-and-ulid-keys
https://laravel.com/docs/11.x/migrations#available-column-types
https://laravel.com/docs/11.x/migrations#column-method-foreignId
https://laravel.com/docs/11.x/migrations#column-method-foreignUlid
https://laravel.com/docs/11.x/migrations#column-method-foreignUuid

Ditulis oleh Backend Developer Intern at Digital Amoeba MSIB Batch 6
Afif Rohul Abrori – Universitas Jember (linkedin.com/in/afifrohul)