63 poin oleh GN⁺ 2025-04-01 | 4 komentar | Bagikan ke WhatsApp
  • Artikel yang merangkum pola-pola praktis untuk menggunakan Postgres dengan lebih produktif dan aman
  • Setiap pola memang kecil, tetapi jika dikumpulkan akan menghasilkan perbedaan besar

Menggunakan primary key UUID

  • Karena UUID bersifat acak, ada kekurangan dari sisi pengurutan dan performa indeks
  • Memakan ruang lebih banyak dibanding ID numerik
  • Namun, ada kelebihan seperti berikut
    • UUID dapat dibuat tanpa terhubung ke DB
    • Aman untuk diekspos ke pihak luar
  • Dengan gen_random_uuid(), UUID bisa dibuat otomatis sebagai primary key

Selalu tambahkan field created_at dan updated_at

  • Saat debugging, sangat berguna untuk mengetahui kapan record dibuat dan diubah
  • updated_at dapat diatur agar diperbarui otomatis melalui trigger
  • Fungsinya cukup dibuat sekali, tetapi trigger harus diterapkan ke setiap tabel

Atur on update/delete restrict pada foreign key

  • Saat menetapkan constraint foreign key, sebaiknya selalu menggunakan on update restrict on delete restrict
  • Ini mencegah terjadinya penghapusan berantai secara tidak sengaja saat data dihapus
  • Ruang penyimpanan itu murah, tetapi pemulihan data sangat sulit, jadi lebih baik bersikap konservatif

Disarankan menggunakan schema

  • Schema default adalah public, tetapi ketika aplikasi membesar, sebaiknya dipisahkan ke schema tersendiri
  • Schema bekerja seperti namespace, dan join juga bisa dilakukan antar-schema yang berbeda
  • Semakin banyak jumlah tabel, semakin menguntungkan penggunaan schema untuk keterbacaan dan pemeliharaan

Gunakan pola enum table

  • Dibanding enum type atau check constraint milik PostgreSQL, pendekatan memakai enum table lebih fleksibel
  • Jika nilai enum dikelola di tabel terpisah, metadata bisa ditambahkan atau nilai enum diperluas dengan mudah
  • Constraint tetap dijaga dengan mereferensikan nilai dari enum table melalui foreign key

Gunakan nama tabel dalam bentuk tunggal

  • Sebaiknya nama tabel menggunakan bentuk tunggal, bukan jamak
  • Saat menulis query, bentuk tunggal lebih jelas, sedangkan bentuk jamak dapat menimbulkan kebingungan makna

Beri nama join table secara mekanis

  • Untuk join table pada relasi many-to-many, paling aman dan jelas jika menamainya dengan menggabungkan dua nama tabel
  • Contoh: person_pet
  • Tambahkan unique index pada kombinasi tersebut untuk mencegah duplikasi

Gunakan soft delete alih-alih delete

  • Daripada benar-benar menghapus data, lebih baik gunakan field timestamp seperti revoked_at yang menunjukkan kapan data dihapus
  • Ini memungkinkan pelacakan bukan hanya apakah data dihapus, tetapi juga kapan penghapusan terjadi
  • Timestamp memberikan informasi lebih banyak dibanding nilai Boolean

Representasikan status dengan log table

  • Alih-alih menyatakan status dengan satu kolom, simpan riwayat perubahan status di tabel terpisah
  • Waktu terjadinya status dinyatakan secara eksplisit melalui kolom valid_at
  • Agar status terbaru bisa diambil dengan cepat, atur flag latest serta unique index + trigger
  • Ini menguntungkan dalam pemrosesan event asinkron atau situasi ketika urutan bisa tercampur

Tambahkan system_id pada baris khusus

  • Selain enum table, kadang ada kebutuhan akan "baris sistem" tertentu
  • Tambahkan field teks system_id yang nullable lalu atur unique index
  • Dengan system_id, baris tertentu bisa diambil secara jelas

Gunakan view seminimal mungkin

  • View berguna untuk mengabstraksikan query yang kompleks, tetapi sulit dipelihara
    • Jika kolom dihapus, view perlu dibuat ulang
    • Jika membuat view di atas view, bisa timbul masalah performa dan keterbacaan
  • Gunakan secukupnya dan dengan hati-hati

Manfaatkan query JSON secara aktif

  • Postgres bukan hanya kuat untuk menyimpan JSON, tetapi juga sangat andal untuk query yang mengembalikan JSON
  • Relasi bertingkat bisa dikembalikan dalam bentuk JSON lewat satu query saja
  • Semua data yang dibutuhkan bisa diambil sekaligus tanpa masalah N+1
  • Kekurangan: informasi tipe hilang, dan seluruh data harus dimuat ke memori sekaligus
  • Namun dari sisi performa maupun struktur, keuntungannya lebih besar

4 komentar

 
jhj0517 2025-04-01

> Tabel join diberi nama secara mekanis

Menurut saya, fakta bahwa ada aturan penamaan seperti ini sendiri sudah bagus~

 
halfenif 2025-04-01

Kalau mempertimbangkan UUID7, bukankah itu bisa diurutkan berdasarkan waktu?

 
winterjung 2025-04-01

Sepertinya artikel tentang penggunaan UUID sebagai kunci utama di PostgreSQL juga layak dijadikan referensi.

 
t7vonn 2025-04-01

Cara menambahkan timestamp saat melakukan soft delete bagus juga. Jika menggunakan UUID sebagai primary key, data tidak bisa diurutkan berdasarkan waktu, jadi sepertinya memakai snowflake id atau ulid juga merupakan pilihan yang baik. Namun dalam kasus ini, tiap server memang harus menyimpan sequence number.