Sebagai seorang siswa CS, saya telah belajar banyak bahasa pemrograman selama bertahun-tahun, yang sebagian besar memiliki konsep "nullable" atau "opsional". Perhatikan bahwa saya tidak berbicara tentang pointer atau referensi nol, atau bahasa yang diketik dengan lemah seperti JavaScript di mana pun bisa null
. Contoh dari apa yang saya bicarakan meliputi boost::optional
(C ++), java.util.Optional
(Java 8.0), prelude.Maybe
(Haskell), dan semua '?' jenis (mis int?
. float?
, C # dan Kotlin). Ini adalah konstruksi yang menambahkan nullability ke tipe yang sebelumnya tidak dapat nullable dalam sistem tipe statis yang ketat.
SQL memiliki konsep yang sama: tipe seperti INTEGER
dapat dibuat nullable atau non-nullable - tetapi ada twist. Dalam SQL, INTEGER
nullable secara default, dan harus ditulis secara eksplisit INTEGER NOT NULL
agar tidak dapat nullable.
Ini menurut saya sangat kontra-intuitif dan berpotensi berbahaya karena memungkinkan NULL menjadi perilaku default. Jelas SQL sudah ada begitu lama pada saat ini sehingga (kebanyakan) pengembang SQL telah mengembangkan kesadaran yang sehat akan perangkap NULL. Tetapi saya tidak dapat membayangkan bahwa pada masa-masa awal NULL sering merayap di tempat-tempat yang tak terduga dan bermasalah.
SQL memang mendahului semua contoh yang saya berikan, jadi mungkin ini hanyalah masalah bagi evolusi sejarah. Namun, saya harus bertanya, apakah ada alasan bagus untuk bahasa dirancang seperti ini, dengan jenis yang dapat dibatalkan secara default?
Jika demikian, apakah itu hanya alasan historis, atau apakah logika mendukung desain database saat ini?
Sunting: Saya tidak bertanya mengapa NULL adalah bagian dari SQL atau mengapa kolom nullable berguna. Saya hanya bertanya mengapa kolom dapat dibatalkan secara default . Sebagai contoh, mengapa kita menulis:
column1 FLOAT,
column2 FLOAT NOT NULL
Daripada:
column1 FLOAT NULLABLE,
column2 FLOAT
sumber
Jawaban:
Di Uni saya diajari bahwa yang sebaliknya adalah benar. Jauh lebih berbahaya membuat sesuatu
not null
tanpa alasan. Dengan bidang nullable, hal terburuk yang bisa terjadi adalah Anda tersandung aplikasi mengakses data. Oh sayang, kembali dan perbaiki aplikasinya ...Dengan bidang bukan-nol Anda membuatnya tidak mungkin untuk menambahkan catatan karena beberapa bidang arbitrer tidak tersedia. Sekarang Anda perlu mengubah model data dan berpotensi memperbaiki hasilnya di BANYAK tempat yang berbeda ...
Ini baik untuk dianggap
null
sebagai "tidak dikenal". Jika ada alasan yang masuk akal mengapa Anda ingin memasukkan catatan tanpa mengetahui sesuatu maka itu harus dibatalkan.Salah satu dosen universitas saya menggambarkannya seperti ini:
Dalam praktiknya cadangan
not null
untuk bidang yang diperlukan untuk membuat catatan masuk akal. Sebagai contoh:Tabel tempat dengan bidang (ID, Nama Tempat, Negara, Bujur, Lintang) ... "bujur" "lintang" harus dibatalkan sehingga Anda dapat menyimpan keberadaan tempat sebelum Anda tahu di mana itu.
Tetapi jika Anda memiliki tabel yang tujuan utamanya adalah untuk menyimpan koodinat geografis dengan bidang (Item_id, bujur, lintang) seluruh catatan tidak ada artinya jika bujur dan lintang adalah nol. Oleh karena itu dalam hal ini mereka tidak boleh null
Dalam pengalaman profesional saya sejak uni, ada lebih banyak bidang yang dapat opsional daripada harus wajib.
sumber
Intuitif ada di mata yang melihatnya dan pendapat Anda tentang hal itu dibentuk oleh hal-hal yang telah Anda ketahui. Saya berasal dari waktu ketika keselamatan semacam itu tidak standar dan alat tidak menunjukkan ketika Anda melakukan kesalahan. Saya telah menggunakan gergaji rantai tanpa pelindung pisau cukup lama sehingga insting pertama saya adalah untuk menghindari intuisi sepenuhnya, kembali ke DDL dan mencari tahu apa asumsi skema yang akan saya buat tentang datanya.
Saya pikir Anda melebih-lebihkan bahaya relatif.
NOT NULL
memiliki perangkap sendiri yang dapat menyebabkan bug yang sama-sama berbahaya. (Menghitung mereka akan menjadi makanan untuk pertanyaan yang berbeda.)Perancang tabel selalu memiliki opsi untuk membatasi kolom
NULL
atauNOT NULL
dan akan melakukan satu atau yang lain untuk menyiasati default, apa pun itu. Tidak membatasi kolom dengan benar adalah kegagalan pengembang untuk mengikuti aturan bisnis. Tidak melakukan hal yang benar di tempat lain berdasarkan definisi kolom adalah kegagalan pengembang untuk memahami data yang diserahkannya. Tidak ada perbaikan teknis untuk keduanya.Tidak, tidak ada. Karena keduanya memiliki bahaya, tidak ada alasan yang baik untuk bahasa tersebut dirancang sebaliknya. Itu intinya untuk mengambil racun Anda.
sumber
Kolom nullable diperlukan dalam SQL karena gabungan luar (juga dikenal sebagai gabungan kiri atau gabungan kanan). Ketika baris di satu sisi gabungan tidak memiliki kecocokan di sisi lain, bidang untuk sisi lain harus memiliki NULL. Karena output dari gabungan dapat memiliki kolom nullable, tabel dasar juga harus mendukungnya karena prinsip penutupan relasional (yang pada dasarnya menyatakan hasil kueri atau tampilan harus tidak dapat dibedakan dari tabel dasar).
Mengingat hal ini, SQL harus mendukung kolom yang dapat dibatalkan. Di sisi lain, kolom non-nullable adalah fitur sekunder - SQL masih bisa berfungsi tanpa mereka.
sumber
Mari kita balikkan dan katakan Anda benar. Katakanlah integer Anda bukan nol secara default.
Yang berarti harus memiliki nilai default. Bahkan ketika itu tidak diketahui.
Jadi ketika Anda memperbarui tabel orang Anda dan Anda memiliki dua pilihan: Tidak mungkin untuk memperbarui tabel karena Anda tidak memasukkan bobot. Atau ketika Anda tidak memberikan argumen bobot yang dimasukkan ke dalam standar "-1 kilo" ketika tidak diketahui.
Kedua situasi tidak diinginkan. Anda ingin dapat menambah pelanggan, bahkan jika Anda tidak tahu beratnya. Tetapi juga, Anda tidak ingin memiliki nilai "proxy". Nilai yang merupakan tempat penampung tetapi dapat memiliki makna nyata, misalnya: dapat digunakan dalam fungsi matematika seperti "rata-rata" tetapi bukan nilai nyata.
Maksud saya saat menghitung bobot rata-rata, -1 adalah nilai yang valid dalam fungsi rata-rata matematika Anda, tetapi tidak sebagai bobot orang. Anda menggunakan null dan sekarang fungsi rata-rata Anda tahu untuk mengabaikan nilai itu.
Juga, saya tidak akan benar-benar membandingkan SQL dengan bahasa pemrograman ketika membahas nol, mereka secara inheren berbeda, null dalam SQL sangat banyak bagian dari teori desain database relasional.
sumber
Tidak. Tidak ada alasan kuat mengapa SQL default menjadi nullable. Faktanya, banyak peneliti terkemuka dalam teori database relasional tidak setuju dengan keputusan desain ini, mungkin yang paling terkenal adalah Chris Date , seorang kolaborator yang sering dengan perancang asli dari database relasional, Edgar Codd . Date (bersama dengan rekan penulis Hugh Darwen) menerbitkan sebuah buku terkenal tentang teori relasional (" The Third Manifesto ") yang menjelaskan prinsip-prinsip untuk desain alternatif untuk keluarga bahasa relasional yang mereka sebut "D", bersama dengan contoh bahasa yang disebut " Tutorial D ".
Bahasa D dilarang secara eksplisit dari mendukung nilai NULL ("D tidak akan menyertakan konsep" hubungan "di mana beberapa" tuple "menyertakan beberapa" atribut "yang tidak memiliki nilai."). Sebagai gantinya, nilai opsional didukung dengan memiliki tipe data alternatif yang menyertakan penanda tempat "tidak ada" atau nilai serupa. Bahasa D menyediakan model yang kaya untuk jenis yang ditentukan pengguna yang akan memungkinkan jenis asli apa pun diperluas dengan nilai tambahan tersebut.
Ada alasan teoritis yang meyakinkan mengapa ini adalah ide yang bagus, dan Date & Darwen telah menulis banyak tentang ini, serta keputusan lain yang mereka buat dalam desain mereka. Saya sangat merekomendasikan membaca karya mereka tentang topik ini.
sumber
Representing x with null is a bad idea
Jangan menyimpulkan ituallowing x by default is bad
. Ergo tidak menyiratkan bahwaallowing null by default is bad where null is the only available representation of x
Not Present = Not Present
di mana dalam SQL tidak adanull = null
ataunull != null
benar.Saya tidak setuju dengan premis Anda tentang apa yang seharusnya menjadi default, tetapi praktik yang baik untuk tidak menganggap apa pun sebagai pengembang. Memeriksa spesifikasi pada tabel database seharusnya tidak terlalu sulit.
Lebih dari perspektif DBA di mana Anda akan diminta untuk memuat data massal terutama ketika menggabungkan dari sistem lain, Anda lebih baik mengetahui pengaturan untuk setiap bidang apakah Anda memiliki data untuk dimasukkan ke dalamnya atau tidak.
Bisnis dan aplikasi dijalankan oleh orang-orang. Jika mereka bukan seorang programmer, definisi "tidak pernah" dan "selalu" tidak persis sama dan akan berubah seiring waktu. Pengaturan nol saat ini pada bidang yang diberikan tidak boleh kabur.
sumber
Database adalah binatang yang berbeda dari bahasa pemrograman normal.
Karena skema tabel diatur, semua data harus ada saat menyimpan informasi ke baris. Namun banyak dari data ini mungkin tidak diperlukan untuk membuat representasi yang valid dari objek model yang pernah dimuat dalam kode Anda. Dengan mensyaratkan bahwa semua data harus non-nol dan diisi akan berarti bahwa bidang-bidang yang tidak wajib ini harus mengandung nilai, namun mereka belum memilikinya, mereka "tidak dikenal".
Bayangkan harus mengisi SEMUA bidang di formulir web SEMUA waktu karena mereka tidak boleh nol dalam database mereka harus menerima nilai ... resep untuk kegilaan itu!
Anda dapat mengatur beberapa nilai yang dicadangkan untuk mewakili tidak adanya data, string kosong, angka tertentu, tanggal tertentu dll tergantung pada tipe data tetapi nilai apa yang harus dipilih? Maka Anda perlu memastikan bahwa semua orang setuju bahwa nilai-nilai sewenang-wenang ini sebenarnya berarti "tidak dikenal" dan bukan "1 Januari 1970" misalnya. Keengganan kosong dapat mengambil banyak bentuk dan membawa Anda pada jalan memutar berbelit-belit hanya karena seseorang mengatakan nol itu buruk. Seberapa kompleks Anda siap untuk mendapatkan hanya untuk menghindari berurusan dengan nol?
Memiliki nilai universal tunggal untuk segala sesuatu yang tidak diketahui saya temukan jauh lebih disukai daripada menggunakan beberapa set nilai konstan arbitrer. Saya tidak mengatakan nilai konstan buruk dan null lebih baik, jika model Anda dilayani dengan baik oleh konstanta untuk mewakili informasi ini maka dengan segala cara gunakan itu tetapi ada banyak situasi di mana nol adalah yang paling cocok. Untuk semua pembenci nol, ini adalah situasi jika nol ditolak maka harus diciptakan!
Melihat betapa meresapnya konsep "tidak dikenal" dalam database maka ya, saya akan mengatakan bahwa membuat nilai-nilai nullable sebagai default sangat masuk akal.
Pergi lebih dalam dan melihat jawaban lain di sini saya tidak akan terkejut mengetahui bahwa nol bukan hanya "fitur bahasa" tetapi bagian integral dari teori yang mendasari di mana SQL didasarkan. Seseorang dapat menghilangkan C (kecepatan cahaya) dari relativitas, tetapi konsep kecepatan maksimum absolut tetap dan harus tetap diekspresikan sehingga akan kembali dalam beberapa bentuk atau bentuk.
sumber
Jawaban singkat: kompatibilitas ke belakang.
Jawaban panjang:
Dalam database yang sepenuhnya dinormalisasi, NULL tidak diperbolehkan di kolom apa pun. Sebagai contoh, misalkan ada tabel yang disebut MailingAddress yang memiliki kolom PostOfficeBox, yang merupakan bilangan bulat. Karena tidak semua orang memiliki kotak pos, ada dua cara untuk mengimplementasikannya.
Pertama, NULL dapat diizinkan di kolom.
Kedua, PostOfficeBox dihapus dari MailingAddress dan tabel baru, PostOfficeBox dibuat dengan Nomor kolom dan PK-nya menjadi FK ke MailingAddress. Tapi sekarang dua pertanyaan diperlukan untuk mendapatkan alamat surat: satu untuk yang tanpa kotak pos dan satu lagi untuk yang punya.
SQL memungkinkan NULL dalam kolom untuk tujuan praktis.
sumber