Administrator database dan developer sering menghadapi masalah umum namun terabaikan dalam skema mereka: field yang ditandai sebagai nullable tetapi tidak pernah benar-benar berisi nilai null. Situasi ini biasanya muncul selama migrasi database ketika tim menambahkan field baru sebagai nullable untuk menghindari table lock, tetapi kemudian lupa memperbarui skema setelah semua data terisi.
Pola Migrasi yang Menciptakan Masalah
Masalah ini berasal dari alur kerja migrasi database standar. Ketika menambahkan field baru ke database produksi, tim sering menandainya sebagai nullable pada awalnya untuk mencegah table lock yang memakan waktu lama selama deployment. Setelah field ditambahkan, logika aplikasi mengisi nilai untuk record baru, dan proses backfill mengisi baris yang sudah ada. Namun, langkah terakhir untuk membuat field menjadi non-nullable sering terlupakan, meninggalkan skema dalam keadaan tidak konsisten.
Ini menciptakan apa yang developer sebut sebagai kebohongan diam-diam dalam skema database. Field tersebut tampak opsional bagi siapa pun yang membaca skema, tetapi dalam praktiknya, selalu berisi data. Ketidaksesuaian ini dapat menyebabkan kebingungan di antara anggota tim dan pemeriksaan null yang tidak perlu dalam kode aplikasi.
Langkah-langkah Pola Migrasi Umum
- Tambahkan field baru sebagai nullable (hindari penguncian tabel)
- Perbarui logika aplikasi untuk mengisi field
- Jalankan backfill job untuk record yang sudah ada
- Sering terlupakan: Perbarui skema untuk membuat field menjadi non-nullable
- Hasil: Field tetap nullable selamanya meskipun tidak pernah berisi null
Kekhawatiran Komunitas tentang Deteksi Otomatis
Meskipun ada tools untuk mengidentifikasi field bermasalah ini dengan memindai kolom nullable yang memiliki nol nilai null, komunitas developer telah mengangkat kekhawatiran penting tentang pendekatan ini. Beberapa berpendapat bahwa hanya karena field saat ini tidak memiliki nilai null tidak berarti field tersebut harus dibuat non-nullable.
Kolom yang nullable tetapi tidak pernah null tidak secara meyakinkan mengatakan apa pun, sungguh. Itu seperti mengatakan kolom tanggal lahir yang tidak pernah sebelum 1970 dalam data saat ini harus dibatasi pada tahun setelah tanggal tersebut.
Perbedaannya terletak pada pemahaman niat asli di balik desain field. Field yang selalu dimaksudkan untuk diperlukan tetapi tetap nullable karena artefak migrasi berbeda dari field yang benar-benar opsional tetapi kebetulan terisi dalam data saat ini.
Solusi Teknis dan Workaround
Sistem database telah berkembang untuk mengatasi beberapa tantangan migrasi ini. PostgreSQL , misalnya, telah mendukung penambahan kolom non-null yang efisien dengan nilai default sejak versi 11, menghilangkan kebutuhan untuk pendekatan nullable-first dalam banyak kasus. Untuk database yang tidak mendukung fitur ini, developer telah menemukan solusi kreatif seperti menggunakan check constraint yang memungkinkan nilai null yang ada sambil mencegah yang baru.
Beberapa tim telah mengadopsi proses yang lebih baik untuk mencegah masalah ini sepenuhnya, termasuk menggunakan checklist untuk perubahan skema dan membuat tiket tindak lanjut untuk memastikan konversi nullable-ke-non-nullable terjadi dalam rilis berikutnya.
Timeline Peningkatan PostgreSQL
- PostgreSQL v11 (2018): Menambahkan kemampuan untuk menghindari penulisan ulang tabel untuk
ALTER TABLE ... ADD COLUMN
dengan default kolom non-null - Versi saat ini: PostgreSQL v17
- Pembatasan: Nilai default harus non-volatile (nilai statis berfungsi, tetapi fungsi seperti
timeofday()
masih memerlukan kunci tabel)
Dampak yang Lebih Luas pada Kualitas Kode
Keberadaan field nullable yang tidak perlu mempengaruhi lebih dari sekadar desain database. Kode aplikasi harus memperhitungkan potensi nilai null bahkan ketika nilai tersebut tidak pernah terjadi dalam praktik. Ini mengarah pada defensive programming yang mungkin tidak perlu dan dapat menciptakan asumsi palsu tentang integritas data.
Tim yang bekerja dengan sistem legacy sering menemukan masalah ini bertambah parah di ratusan field, membuatnya sulit untuk membedakan antara data yang benar-benar opsional dan field yang seharusnya ditandai sebagai required sejak lama. Situasi menjadi sangat menantang dalam aplikasi single-tenant di mana tenant yang berbeda mungkin memiliki pola populasi data yang berbeda.
Solusi Alternatif SQL Server untuk Field yang Dapat Bernilai Null
-- Tambahkan constraint check dengan NOCHECK untuk mengizinkan null yang sudah ada
ALTER TABLE foo WITH NOCHECK
ADD CONSTRAINT CheckNotnull CHECK (id IS NOT NULL)
-- Insert/update baru tidak boleh null, tetapi null yang sudah ada tetap dipertahankan
-- Nilai null yang sudah ada dapat diperbarui secara bertahap tanpa memblokir operasi
Bergerak Maju dengan Integritas Skema
Kunci untuk mengatasi masalah ini terletak pada memperlakukan desain skema sebagai tanggung jawab berkelanjutan daripada tugas setup satu kali. Meskipun tools otomatis dapat membantu mengidentifikasi kandidat potensial untuk pembersihan, penilaian manusia tetap penting dalam menentukan apakah field sebenarnya harus dibuat non-nullable berdasarkan persyaratan bisnis dan semantik data.
Review skema reguler dan proses migrasi yang diperbaiki dapat mencegah inkonsistensi ini menumpuk dari waktu ke waktu. Tujuannya adalah memastikan bahwa skema database secara akurat mencerminkan model data yang dimaksudkan, membuat sistem lebih dapat diandalkan dan lebih mudah dipelihara untuk tim pengembangan masa depan.
Referensi: Nullable but not null