it-swarm.asia

Mengapa kita tidak mengizinkan NULL?

Saya ingat membaca artikel yang satu ini tentang desain database dan saya juga ingat dikatakan bahwa Anda harus memiliki properti bidang NOT NULL. Saya tidak ingat mengapa ini terjadi.

Yang bisa saya pikirkan hanyalah bahwa, sebagai pengembang aplikasi, Anda tidak perlu menguji NULL dan kemungkinan nilai data yang tidak ada (misalnya, string kosong untuk string).

Tapi apa yang Anda lakukan dalam hal tanggal, waktu, dan waktu (SQL Server 2008)? Anda harus menggunakan tanggal yang bersejarah atau terbawah.

Ada ide tentang ini?

127
Thomas Stringer

Saya pikir pertanyaannya tidak tepat, karena kata-kata itu menyiratkan bahwa Anda sudah memutuskan bahwa NULL itu buruk. Mungkin maksud Anda, "Haruskah kita mengizinkan NULL?"

Bagaimanapun, inilah pendapat saya: Saya pikir NULL adalah hal yang baik. Saat Anda mulai mencegah NULL hanya karena "NULL buruk" atau "NULL sulit", Anda mulai mengarang data. Misalnya, bagaimana jika Anda tidak tahu tanggal lahir saya? Apa yang akan Anda taruh di kolom sampai Anda tahu? Jika Anda seperti banyak orang anti-NULL, Anda akan memasukkan 1900-01-01. Sekarang saya akan ditempatkan di bangsal geriatrik dan mungkin mendapat telepon dari stasiun berita lokal saya memberi selamat kepada saya atas umur panjang saya, meminta saya rahasia saya untuk menjalani umur panjang, dll.

Jika sebuah baris dapat dimasukkan di mana Anda mungkin tidak tahu nilai kolom, saya pikir NULL jauh lebih masuk akal daripada memilih beberapa nilai token sewenang-wenang untuk mewakili fakta bahwa itu tidak diketahui - nilai yang orang lain harus sudah tahu, merekayasa balik, atau bertanya-tanya untuk mencari tahu apa artinya.

Ada keseimbangan, meskipun - tidak setiap kolom dalam model data Anda harus nullable. Sering ada bidang opsional pada formulir, atau potongan informasi yang jika tidak dikumpulkan pada saat baris dibuat. Tapi itu tidak berarti Anda dapat menunda populating semua dari data. :-)

Juga kemampuan untuk menggunakan NULL dapat dibatasi oleh persyaratan penting dalam kehidupan nyata. Di bidang medis, misalnya, bisa menjadi masalah hidup atau mati untuk mengetahui mengapa nilainya tidak diketahui. Apakah detak jantung NULL karena tidak ada Denyut Jantung, atau karena kita belum mengukurnya? Dalam kasus seperti itu, dapatkah kita meletakkan NULL di kolom detak jantung, dan memiliki catatan atau kolom berbeda dengan alasan NULL-karena?

Jangan takut pada NULLs, tetapi berkeinginan untuk belajar atau menentukan kapan dan di mana mereka harus digunakan, dan kapan dan di mana mereka seharusnya tidak.

232
Aaron Bertrand

Alasan yang ditetapkan adalah:

  • NULL bukan nilai, dan karenanya tidak memiliki tipe data intrinsik. Nulls perlu penanganan khusus di semua tempat ketika kode yang bergantung pada tipe aktual juga dapat menerima NULL yang tidak diketik.

  • NULL memecah logika dua-nilai (familiar Benar atau Salah), dan membutuhkan logika tiga-nilai. Ini jauh lebih kompleks untuk diterapkan dengan benar, dan tentu saja kurang dipahami oleh sebagian besar DBA dan hampir semua non-DBA. Sebagai akibatnya, itu positif mengundang banyak bug halus dalam aplikasi.

  • Arti semantik dari NULL tertentu diserahkan ke aplikasi , tidak seperti nilai aktual.

    Semantik seperti "tidak berlaku" dan "tidak dikenal" dan "penjaga" adalah umum, dan ada juga yang lain. Mereka sering digunakan secara bersamaan dalam database yang sama, bahkan dalam hubungan yang sama; dan tentu saja makna tidak jelas dan tidak bisa dibedakan dan tidak kompatibel .

  • Mereka tidak diperlukan untuk basis data relasional , seperti yang diperdebatkan dalam "Cara Menangani Informasi yang Hilang Tanpa Nulls" . Normalisasi lebih lanjut adalah langkah pertama yang jelas untuk mencoba membersihkan tabel NULL.

Ini tidak berarti NULL tidak boleh diizinkan. Ini tidak berpendapat bahwa ada banyak alasan bagus untuk melarang NULL di mana pun dimungkinkan.

Secara signifikan, ia berpendapat untuk berusaha sangat keras - melalui desain skema yang lebih baik, dan mesin database yang lebih baik, dan bahasa database yang lebih baik - untuk make layak untuk menghindari NULL lebih sering.

Fabian Pascal menanggapi sejumlah argumen, dalam “Nulls Nullified” .

61
bignose

Saya tidak setuju, nulls adalah elemen penting dari desain database. Alternatifnya, seperti yang Anda singgung juga, akan menjadi proliferasi nilai-nilai yang diketahui untuk mewakili yang hilang atau tidak diketahui. Masalahnya terletak pada nol yang begitu banyak disalahpahami dan akibatnya digunakan secara tidak tepat.

IIRC, Codd menyarankan implementasi null saat ini (artinya tidak ada/hilang) dapat ditingkatkan dengan memiliki dua marker nol daripada satu, "tidak ada tetapi dapat diterapkan" dan "tidak ada dan tidak dapat diterapkan". Tidak dapat membayangkan bagaimana desain relasional ditingkatkan oleh ini secara pribadi.

32

Biarkan saya memulai dengan mengatakan saya bukan seorang DBA, saya seorang pengembang pada dasarnya dan saya memelihara dan memperbarui basis data kami berdasarkan kebutuhan kami. Yang sedang berkata, saya punya pertanyaan yang sama karena beberapa alasan.

  1. Nilai kosong membuat pengembangan lebih sulit dan rawan bug.
  2. Nilai kosong membuat kueri, prosedur tersimpan, dan tampilan lebih kompleks dan rawan bug.
  3. Nilai kosong mengambil ruang (? Byte berdasarkan panjang kolom tetap atau 2 byte untuk panjang kolom variabel).
  4. Nilai kosong dapat dan sering mempengaruhi pengindeksan dan matematika.

Saya menghabiskan waktu yang sangat lama memilah-milah banyak tanggapan, komentar, artikel, dan saran di seluruh internet. Tidak perlu dikatakan bahwa sebagian besar informasinya hampir sama dengan respons @ AaronBertrand. Itulah sebabnya saya merasa perlu menanggapi pertanyaan ini.

Pertama saya ingin meluruskan sesuatu untuk semua pembaca masa depan ... Nilai NULL mewakili data yang tidak diketahui BUKAN data yang tidak digunakan. Jika Anda memiliki tabel karyawan yang memiliki bidang tanggal pemutusan hubungan kerja. Nilai nol pada tanggal terminasi adalah karena ini merupakan bidang wajib di masa depan yang saat ini tidak diketahui. Setiap karyawan baik itu aktif atau diberhentikan pada suatu saat akan memiliki tanggal yang ditambahkan ke bidang itu. Itu menurut saya satu-satunya alasan untuk bidang Nullable.

Itu dikatakan meja karyawan yang sama kemungkinan besar akan menyimpan beberapa jenis data otentikasi. Adalah umum dalam lingkungan perusahaan bahwa karyawan akan terdaftar dalam database untuk HR dan akuntansi tetapi tidak selalu memiliki atau memerlukan detail otentikasi. Sebagian besar tanggapan akan membuat Anda percaya bahwa tidak ada masalah untuk membatalkan bidang tersebut atau dalam beberapa kasus membuat akun untuk mereka tetapi tidak pernah mengirimi mereka kredensial. Yang pertama akan menyebabkan tim pengembangan Anda untuk menulis kode untuk memeriksa NULL dan untuk menghadapinya sesuai dan yang terakhir menimbulkan risiko keamanan besar! Akun yang belum pernah digunakan dalam sistem hanya meningkatkan jumlah titik akses yang mungkin bagi seorang peretas, ditambah lagi mereka mengambil ruang basis data yang berharga untuk sesuatu yang tidak pernah digunakan.

Mengingat informasi di atas, cara terbaik untuk menangani data nullable yang AKAN digunakan adalah untuk memungkinkan nilai-nilai nullable. Ini menyedihkan tetapi benar dan pengembang Anda akan membenci Anda karenanya. Tipe kedua data yang dapat dibatalkan harus diletakkan dalam tabel terkait (IE: Akun, Kredensial, dll) dan memiliki hubungan Satu-ke-Satu. Ini memungkinkan pengguna ada tanpa kredensial kecuali diperlukan. Ini menghilangkan risiko keamanan ekstra, ruang basis data yang berharga, dan menyediakan basis data yang jauh lebih bersih.

Di bawah ini adalah struktur tabel yang sangat sederhana yang menunjukkan kolom nullable yang diperlukan dan hubungan Satu-ke-Satu.

Unknown Nullable and One-to-One relationship

Saya tahu saya sedikit terlambat ke pesta karena pertanyaan ini diajukan bertahun-tahun yang lalu, tetapi mudah-mudahan ini akan membantu untuk menjelaskan masalah ini dan cara terbaik untuk mengatasinya.

14

Terlepas dari semua masalah dengan pengembang membingungkan NULL, NULL memiliki kelemahan lain yang sangat serius: Kinerja

Kolom NULL'able adalah bencana dari perspektif kinerja. Pertimbangkan bilangan bulat aritmatika sebagai contoh. Dalam dunia yang waras tanpa NULL, "mudah" untuk membuat aritmatika integer integer dalam kode mesin basis data menggunakan instruksi SIMD untuk melakukan hampir semua perhitungan dengan kecepatan lebih cepat dari 1 baris per siklus CPU. Namun, saat Anda memperkenalkan NULL, Anda harus menangani semua kasus khusus yang dibuat NULL. Set instruksi CPU modern (baca: x86/x64/ARM dan juga logika GPU) sama sekali tidak dilengkapi untuk melakukan ini secara efisien.

Pertimbangkan pembagian sebagai contoh. Pada level yang sangat tinggi, ini adalah logika yang Anda butuhkan dengan integer non null:

if (b == 0)
  do something when dividing by error
else
  return a / b

Dengan NULL, ini menjadi sedikit lebih rumit. Bersama dengan b Anda akan memerlukan indikator jika b adalah nol dan sama dengan a. Cek sekarang menjadi:

if (b_null_bit == NULL)
   return NULL
else if (b == 0) 
   do something when dividing by error
else if (a_null_bit == NULL)
   return NULL
else 
   return a / b

Aritmatika NULL secara signifikan lebih lambat untuk berjalan pada CPU modern daripada aritmatika bukan nol (dengan faktor sekitar 2-3x).

Semakin buruk saat Anda memperkenalkan SIMD. Dengan SIMD, CPU Intel modern dapat melakukan pembagian integer 4 x 32-bit dalam satu instruksi, seperti ini:

x_vector = a_vector / b_vector
if (fetestexception(FE_DIVBYZERO))
   do something when dividing by zero
return x_vector;

Sekarang, ada cara untuk menangani NULL di tanah SIMD juga, tetapi ini membutuhkan penggunaan lebih banyak vektor dan register CPU dan melakukan beberapa penyembunyian bit pintar. Bahkan dengan trik yang baik, penalti kinerja aritmatika integer NULL merayap ke dalam kisaran 5-10x lebih lambat untuk ekspresi yang bahkan relatif sederhana.

Sesuatu seperti di atas berlaku untuk agregat dan sampai batas tertentu, untuk bergabung juga.

Dengan kata lain: Keberadaan NULL dalam SQL adalah ketidakcocokan impedansi antara teori database dan desain aktual komputer modern. Ada alasan yang cukup bagus NULL membingungkan pengembang - karena integer tidak bisa NULL dalam sebagian besar bahasa pemrograman yang waras - itu bukan cara komputer bekerja.

13
Thomas Kejser

artikel Wikipedia tentang SQL Null memiliki beberapa komentar menarik tentang nilai NULL, dan sebagai jawaban database-agnostik, selama Anda mengetahui potensi dampak memiliki nilai NULL untuk RDBMS spesifik Anda, mereka dapat diterima dalam desain Anda. Jika tidak, Anda tidak akan dapat menentukan kolom sebagai nullable.

Perlu diketahui bagaimana RDBMS Anda menangani mereka dalam operasi SELECT seperti matematika, dan juga dalam Indeks.

10
Derek Downey

Pertanyaan menarik.

Yang bisa saya pikirkan hanyalah bahwa, sebagai pengembang aplikasi, Anda tidak perlu menguji NULL dan kemungkinan nilai data yang tidak ada (misalnya, string kosong untuk string).

Lebih rumit dari itu. Null memiliki sejumlah makna yang berbeda dan satu alasan yang sangat penting untuk tidak membiarkan nol di banyak kolom adalah bahwa ketika kolom tersebut nol, ini berarti satu dan hanya satu hal (yaitu tidak muncul di bagian luar). Selain itu memungkinkan Anda untuk menetapkan standar minimum entri data yang sangat membantu.

Tapi apa yang Anda lakukan dalam hal tanggal, waktu, dan waktu (SQL Server 2008)? Anda harus menggunakan tanggal yang bersejarah atau terbawah.

Itu menggambarkan masalah dengan nulls segera, yaitu bahwa nilai yang disimpan dalam tabel dapat berarti "nilai ini tidak berlaku" atau "kita tidak tahu." Dengan string, string kosong dapat berfungsi sebagai "ini tidak berlaku" tetapi dengan tanggal dan waktu, tidak ada konvensi seperti itu karena tidak ada nilai valid yang secara konvensional berarti ini. Biasanya di sana Anda akan mandek menggunakan NULL.

Ada beberapa cara untuk mengatasi hal ini (dengan menambahkan lebih banyak hubungan dan bergabung) tetapi hal itu menimbulkan masalah kejelasan semantik yang sama persis dengan yang dimiliki NULL dalam database. Untuk database ini saya tidak akan khawatir tentang ini. Tidak ada yang bisa Anda lakukan untuk itu.

EDIT: Satu area di mana NULLs are sangat diperlukan dalam kunci asing. Di sini mereka biasanya hanya memiliki satu makna, identik dengan nol dalam makna gabungan luar. Ini merupakan pengecualian untuk masalah tentunya.

10
Chris Travers