Boolean, UUID, dan enum

Menggunakan jenis kolom modern untuk nilai benar-salah, pengenal unik universal, dan daftar nilai tetap.

Daftar isi

Topik ini membahas tiga jenis kolom yang menjawab kebutuhan modern, yaitu boolean untuk nilai benar-salah, UUID untuk pengenal yang unik lintas sistem, dan enum untuk daftar nilai tetap. Dataset utama sudah memakai boolean pada kolom aktif, dan topik ini melengkapinya dengan jenis yang tersisa.

boolean dan literanya#

boolean menyimpan TRUE, FALSE, dan NULL, dan server menerima variasi literal seperti true, false, t, f, yes, no, serta 1 dan 0. Penyaringan kolom boolean tidak memerlukan perbandingan eksplisit, karena kolomnya sendiri sudah berupa ekspresi boolean.

bash
# penyaringan kolom boolean secara langsung
psql -U postgres -d perpustakaan -c "SELECT nama, aktif FROM anggota WHERE NOT aktif;"
text Keluaran
     nama     | aktif
--------------+-------
 Citra Kirana | f
(1 row)

Kolom aktif pada dataset bernilai FALSE hanya untuk Citra Kirana, dan bentuk WHERE NOT aktif membaca seperti kalimat. Penggunaan paling bermakna dari boolean adalah menjaga setiap kolomnya bermakna tunggal, karena kolom boolean yang dipakai menyimpan banyak arti sekaligus cepat menjadi tak terbaca, dan penggantinya adalah enum pada bagian akhir topik ini.

UUID sebagai pengenal lintas sistem#

UUID, kependekan universally unique identifier, adalah pengenal 128 bit yang kemungkinan duplikasinya praktis nol, sehingga pengenal dapat dibuat di mana pun tanpa koordinasi dengan server basis data. PostgreSQL menyediakan jenis uuid bawaan, dan fungsi gen_random_uuid() menghasilkan UUID versi 4 berbasis bilangan acak sejak PostgreSQL 13 tanpa ekstensi.

bash
# tabel dengan kunci uuid dan nilai eksplisit
psql -U postgres -d perpustakaan <<'SQL'
CREATE TABLE sertifikat (
    id      UUID PRIMARY KEY,
    pemilik TEXT NOT NULL
);
INSERT INTO sertifikat VALUES
    ('1b0e6a3e-5f2a-4c8e-9d3b-6f1a2c4d5e6f', 'Ali Rahman'),
    ('7c9e6679-7425-40de-944b-e07fc1f90ae7', 'Budi Santoso');
SELECT pemilik, id FROM sertifikat ORDER BY pemilik;
DROP TABLE sertifikat;
SQL
text Keluaran
CREATE TABLE
INSERT 0 2
   pemilik    |                  id
--------------+--------------------------------------
 Ali Rahman   | 1b0e6a3e-5f2a-4c8e-9d3b-6f1a2c4d5e6f
 Budi Santoso | 7c9e6679-7425-40de-944b-e07fc1f90ae7
(2 rows)

DROP TABLE

Nilai default kolom dapat diatur menjadi gen_random_uuid() sehingga INSERT tanpa id tetap terisi. Keluaran pada topik ini memakai nilai eksplisit agar hasilnya tetap sama pada setiap eksekusi, karena UUID acak memang tidak dapat direkam sebagai keluaran tetap. Pada aplikasi nyata, pilihan antara kunci serial dan UUID dipengaruhi kebutuhan pembuatan pengenal di sisi klien. UUID versi 4 yang acak melindungi privasi tetapi menyulitkan urutan tulis pada index, kelemahan yang dibenahi UUID versi 7 pada PostgreSQL 18.

enum untuk daftar nilai tetap#

enum, kependekan enumeration, adalah jenis yang nilainya dibatasi pada daftar yang dideklarasikan saat jenisnya dibuat. Jenis ini cocok untuk status yang daftarnya kecil dan stabil, misalnya siklus hidup peminjaman.

bash
# jenis enum beserta nilai sah dan penolakan nilai liar
psql -U postgres -d perpustakaan <<'SQL'
CREATE TYPE status_pinjam AS ENUM ('dipinjam', 'kembali', 'hilang');
CREATE TABLE kartu_uji (id INTEGER, status status_pinjam);
INSERT INTO kartu_uji VALUES (1, 'dipinjam'), (2, 'kembali');
SELECT * FROM kartu_uji ORDER BY status;
INSERT INTO kartu_uji VALUES (3, 'tertunda');
DROP TABLE kartu_uji;
DROP TYPE status_pinjam;
SQL
text Keluaran
CREATE TYPE
CREATE TABLE
INSERT 0 2
 id |  status
----+----------
  1 | dipinjam
  2 | kembali
(2 rows)

ERROR:  invalid input value for enum status_pinjam: "tertunda"
LINE 1: INSERT INTO kartu_uji VALUES (3, 'tertunda');
                                         ^
DROP TABLE
DROP TYPE

Urutan pembandingan enum mengikuti urutan deklarasi, sehingga 'kembali' > 'dipinjam' bernilai benar meskipun urutan abjadnya berbeda. Penambahan nilai belakangan memakai ALTER TYPE … ADD VALUE, dan perintah itu berjalan dalam transaksi sendiri, kebiasaan yang perlu diingat sebelum memilih enum.

enum atau tabel rujukan#

Pilihan antara enum dan tabel rujukan dengan foreign key diputuskan oleh masa depan daftar nilainya. enum layak untuk daftar yang ditetapkan desain dan hampir tak berubah, sedangkan tabel rujukan layak ketika daftar dikelola pengguna, membutuhkan kolom keterangan, atau bertumbuh seiring waktu. Tabel rujukan juga memudahkan audit karena perubahannya berupa baris data, bukan perubahan jenis.

Pada dataset utama, relasi buku ke kategori sengaja memakai tabel rujukan karena kategori dikelola pustakawan, bukan ditetapkan kode. Sebaliknya, siklus hidup peminjaman pada contoh di atas cocok dengan enum karena tiga nilainya memang milik desain sistem.

Kesalahan umum#

Kesalahan pertama adalah memakai kolom boolean untuk banyak arti sekaligus, misalnya kolom dihapus yang sekaligus berarti disembunyikan dan dinonaktifkan, dan penggantinya adalah enum dengan nilai yang jujur. Kesalahan kedua adalah memakai enum untuk daftar yang dikelola pengguna, karena setiap penambahan nilai menuntut perubahan skema, sedangkan tabel rujukan menyelesaikannya dengan INSERT biasa. Kesalahan ketiga adalah menyimpan UUID sebagai teks, yang memboroskan penyimpanan dan melumpuhkan perbandingan efisien, padahal jenis uuid tersedia bawaan.

Kesalahan keempat adalah mengira UUID versi 4 berurutan. Nilainya acak, sehingga baris baru mendarat di posisi mana pun pada index dan pola tulisnya lebih lebar daripada serial, pertimbangan yang dijelaskan lagi pada modul index dan performa.

Ringkasan#

  • boolean menyimpan TRUE, FALSE, dan NULL, dan kolomnya dapat disaring tanpa perbandingan eksplisit.
  • uuid menyimpan pengenal 128 bit yang dapat dibuat di mana pun, dan gen_random_uuid() mengisi nilai acak tanpa ekstensi.
  • enum membatasi nilai pada daftar deklarasinya dan membandingkan menurut urutan deklarasi, bukan abjad.
  • enum untuk daftar tetap milik desain, tabel rujukan untuk daftar yang dikelola dan bertumbuh.

Referensi#