Pentadbir pangkalan data dan pembangun sering menghadapi isu biasa tetapi diabaikan dalam skema mereka: medan yang ditandakan sebagai nullable tetapi sebenarnya tidak pernah mengandungi nilai null. Situasi ini biasanya timbul semasa migrasi pangkalan data apabila pasukan menambah medan baharu sebagai nullable untuk mengelakkan kunci jadual, tetapi kemudian terlupa untuk mengemaskini skema setelah semua data diisi.
Corak Migrasi Yang Mencipta Masalah
Isu ini berpunca daripada aliran kerja migrasi pangkalan data standard. Apabila menambah medan baharu ke pangkalan data pengeluaran, pasukan sering menandakan mereka sebagai nullable pada mulanya untuk mencegah kunci jadual yang panjang semasa penggunaan. Selepas medan ditambah, logik aplikasi mengisi nilai untuk rekod baharu, dan proses backfill mengisi baris sedia ada. Walau bagaimanapun, langkah terakhir untuk menjadikan medan sebagai non-nullable sering terlupa, meninggalkan skema dalam keadaan tidak konsisten.
Ini mencipta apa yang pembangun panggil pembohongan senyap dalam skema pangkalan data. Medan kelihatan pilihan kepada sesiapa yang membaca skema, tetapi dalam amalan, ia sentiasa mengandungi data. Ketidakpadanan ini boleh membawa kepada kekeliruan di kalangan ahli pasukan dan pemeriksaan null yang tidak perlu dalam kod aplikasi.
Langkah-langkah Corak Migrasi Biasa
- Tambah medan baharu sebagai nullable (elakkan penguncian jadual)
- Kemas kini logik aplikasi untuk mengisi medan
- Jalankan kerja backfill untuk rekod sedia ada
- Sering terlupa: Kemas kini skema untuk menjadikan medan tidak-nullable
- Hasil: Medan kekal nullable selama-lamanya walaupun tidak pernah mengandungi null
Kebimbangan Komuniti Mengenai Pengesanan Automatik
Walaupun alat wujud untuk mengenal pasti medan bermasalah ini dengan mengimbas lajur nullable dengan sifar nilai null, komuniti pembangun telah membangkitkan kebimbangan penting mengenai pendekatan ini. Sesetengah berhujah bahawa hanya kerana medan pada masa ini tidak mempunyai nilai null tidak bermakna ia harus dijadikan non-nullable.
Lajur yang nullable tetapi tidak pernah null tidak memberitahu apa-apa secara muktamad, sebenarnya. Itu seperti mengatakan lajur hari lahir yang tidak pernah sebelum 1970 dalam data semasa harus dihadkan kepada tahun selepas tarikh tersebut.
Perbezaan terletak pada memahami niat asal di sebalik reka bentuk medan. Medan yang sentiasa dimaksudkan untuk diperlukan tetapi kekal nullable kerana artifak migrasi adalah berbeza daripada medan yang benar-benar pilihan tetapi kebetulan diisi dalam data semasa.
Penyelesaian Teknikal dan Jalan Keluar
Sistem pangkalan data telah berkembang untuk menangani beberapa cabaran migrasi ini. PostgreSQL , sebagai contoh, telah menyokong penambahan lajur non-null yang cekap dengan nilai lalai sejak versi 11, menghapuskan keperluan untuk pendekatan nullable-first dalam banyak kes. Untuk pangkalan data yang tidak menyokong ciri ini, pembangun telah menemui penyelesaian kreatif seperti menggunakan kekangan semak yang membenarkan nilai null sedia ada sambil mencegah yang baharu.
Sesetengah pasukan telah menggunakan proses yang lebih baik untuk mencegah isu sepenuhnya, termasuk menggunakan senarai semak untuk perubahan skema dan mencipta tiket susulan untuk memastikan penukaran nullable-ke-non-nullable berlaku dalam keluaran berikutnya.
Garis Masa Penambahbaikan PostgreSQL
- PostgreSQL v11 (2018): Menambah keupayaan untuk mengelakkan penulisan semula jadual bagi
ALTER TABLE ... ADD COLUMN
dengan lalai kolum bukan-null - Versi semasa: PostgreSQL v17
- Sekatan: Nilai lalai mestilah bukan-mudah berubah (nilai statik berfungsi, tetapi fungsi seperti
timeofday()
masih memerlukan kunci jadual)
Kesan Yang Lebih Luas Terhadap Kualiti Kod
Kehadiran medan nullable yang tidak perlu mempengaruhi lebih daripada sekadar reka bentuk pangkalan data. Kod aplikasi mesti mengambil kira nilai null yang berpotensi walaupun ia tidak pernah berlaku dalam amalan. Ini membawa kepada pengaturcaraan defensif yang mungkin tidak perlu dan boleh mencipta andaian palsu mengenai integriti data.
Pasukan yang bekerja dengan sistem warisan sering mendapati masalah ini dikompaun merentasi beratus-ratus medan, menjadikannya sukar untuk membezakan antara data yang benar-benar pilihan dan medan yang sepatutnya ditandakan sebagai diperlukan sejak lama dahulu. Situasi menjadi sangat mencabar dalam aplikasi penyewa tunggal di mana penyewa berbeza mungkin mempunyai corak populasi data yang berbeza.
Penyelesaian SQL Server untuk Medan Nullable
-- Tambah kekangan semakan dengan NOCHECK untuk membenarkan null sedia ada
ALTER TABLE foo WITH NOCHECK
ADD CONSTRAINT CheckNotnull CHECK (id IS NOT NULL)
-- Sisipan/kemaskini baharu tidak boleh null, tetapi null sedia ada kekal
-- Nilai null sedia ada boleh dikemaskini dari masa ke masa tanpa menyekat operasi
Bergerak Ke Hadapan Dengan Integriti Skema
Kunci untuk menangani isu ini terletak pada merawat reka bentuk skema sebagai tanggungjawab berterusan dan bukannya tugas persediaan sekali sahaja. Walaupun alat automatik boleh membantu mengenal pasti calon berpotensi untuk pembersihan, pertimbangan manusia kekal penting dalam menentukan sama ada medan sebenarnya harus dijadikan non-nullable berdasarkan keperluan perniagaan dan semantik data.
Semakan skema berkala dan proses migrasi yang diperbaiki boleh mencegah ketidakkonsistenan ini daripada terkumpul dari masa ke masa. Matlamatnya adalah memastikan skema pangkalan data mencerminkan model data yang dimaksudkan dengan tepat, menjadikan sistem lebih boleh dipercayai dan lebih mudah diselenggara untuk pasukan pembangunan masa depan.
Rujukan: Nullable but not null