Bagaimana nama keluarga Null menyebabkan masalah di banyak basis data?

71

Saya membaca sebuah artikel di BBC. Salah satu contoh yang mereka katakan adalah bahwa orang dengan nama keluarga 'Null' mengalami masalah dengan memasukkan detail mereka di beberapa situs web.

Tidak ada penjelasan yang diberikan tentang kesalahan yang mereka hadapi.

Tapi sejauh yang saya tahu string 'Null' dan nilai Null sebenarnya sangat berbeda (dari sudut pandang basis data).

Mengapa ini menyebabkan masalah dalam database?

Nitish
sumber
2
Ini adalah artikel blog yang agak terkenal tentang asumsi yang dibuat oleh pemrogram tentang nama, ditulis oleh salah satu orang yang dikutip dalam artikel BBC itu: kalzumeus.com/2010/06/17/…
Jörg W Mittag
12
Xkcd relevan
Pasang kembali Monica
4
Pertama kali saya melihat orang ini di TV saya berasumsi itu adalah bug basis data. Lalu aku tahu itu sebenarnya namanya.
Nate Eldredge
3
@JarrodRoberson Bagaimana Anda bisa mengatakan "seluruh premis itu salah", mengingat deskripsi masalah yang dihadapi oleh "Jennifer Null" dan nama-nama seperti di tautan yang diposting OP? Ini adalah masalah nyata yang dihadapi pengguna akhir yang nyata.
Gort the Robot

Jawaban:

102

Itu tidak menyebabkan masalah basis data. Ini menyebabkan masalah dalam aplikasi yang ditulis oleh pengembang yang tidak mengerti database. Pada akar masalahnya adalah bahwa banyak perangkat lunak yang berhubungan dengan database menampilkan catatan NULL sebagai string NULL. Ketika suatu aplikasi kemudian bergantung pada bentuk string dari catatan NULL (kemungkinan juga menggunakan operasi perbandingan case-insensitive), maka aplikasi seperti itu akan menganggap "null"string apa pun menjadi NULL. Akibatnya nama Null akan dianggap tidak ada oleh aplikasi itu.

Solusinya adalah dengan mendeklarasikan kolom-kolom non-null seperti NOT NULLpada basis data, dan untuk tidak menerapkan operasi string pada rekaman basis data. Sebagian besar bahasa memiliki API basis data yang sangat baik yang membuat antarmuka tingkat-string tidak perlu. Mereka harus selalu disukai, juga karena mereka membuat kesalahan lain seperti injeksi SQL kurang mungkin.

amon
sumber
30
Namun, dalam hal ini, jika Anda membaca artikel yang dipermasalahkan, membuat bidang nama belakang NOT NULLakan menyebabkan serangkaian masalah bagi orang lain. "Beberapa individu hanya memiliki satu nama, bukan nama depan dan nama keluarga."
MikeTheLiar
41
@Darkhogg banyak orang tidak setuju dengan saya tentang hal ini tetapi saya pikir nama itu seperti alamat email - jangan repot-repot memvalidasi mereka, beri pengguna satu kotak teks dan biarkan mereka meletakkan apa pun yang mereka inginkan. Ini adalah informasi bahwa jika saya benar - benar membutuhkannya, saya akan mendapatkannya dari Anda dengan cara yang pasti benar.
MikeTheLiar
8
@ MikeTheLiar Saya tidak tahu nama untuk ini, tetapi ada seluruh kelas kesalahan yang muncul karena membuat aturan data yang terlalu ketat. Seringkali Anda akan melihat kode pos dan nomor telepon yang didefinisikan sebagai angka dalam aplikasi dan basis data. Mereka tidak benar-benar angka karena tidak masuk akal untuk melakukan operasi matematika pada mereka. Jadi ketika seseorang mencoba memasukkan alamat Kanada, mereka macet.
JimmyJames
19
@ JimmyJames ya, kode pos disimpan sebagai angka dan tiba-tiba siapa pun yang tinggal di sini memiliki kode pos basis-8. "Jika kamu tidak melakukan matematika dengan itu, itu adalah string, Berhenti Penuh."
MikeTheLiar
8
@mikeTheLiar. Masalah dengan memperlakukan nama sebagai string tunggal (biasanya lebih disukai, saya setuju) adalah ketika ada persyaratan untuk mengurutkan abjad berdasarkan nama keluarga.
TRiG
13

Untuk menjawab pertanyaan spesifik Anda, ada banyak langkah di sepanjang rantai peristiwa antara formulir web dan database. Jika nama belakang Nullditafsirkan secara keliru sebagai NULLnilai maka sistem dapat menolak nama yang benar-benar valid sebagai tidak valid. Ini bisa terjadi pada lapisan basis data seperti yang dijelaskan oleh amon . Kebetulan jika ini adalah masalah khusus maka database juga mungkin terbuka untuk injeksi SQL AKA serangan Bobby Tables . Langkah lain dalam rantai yang dapat menyebabkan masalah adalah proses serialisasi .

Secara keseluruhan artikel itu tentang masalah yang lebih besar. Dunia adalah tempat berantakan besar yang tidak selalu sesuai dengan asumsi kita. Ini terutama terlihat ketika Anda mencoba menginternasionalkan aplikasi Anda. Pada akhirnya kami perlu memastikan aplikasi kami menangani dan menyandikan data kami dengan benar . Terserah bisnis untuk memutuskan berapa banyak sumber daya yang kami dedikasikan untuk mendukung kasus tepi yang semakin rumit. Sementara saya sepenuhnya mendukung inklusif, saya akan mengerti jika bisnis memutuskan bahwa "artis yang secara resmi dikenal sebagai Pangeran" perlu menggunakan karakter Unicode untuk mewakili namanya dalam database kami.

Erik
sumber
Sulit membayangkan ini disebabkan oleh semacam interpolasi string yang tidak aman yang dapat menyebabkan injeksi SQL. Jika Anda lupa mengutip input pengguna dalam kueri SQL (misalnya INSERT INTO users (first, last) VALUES($first, $last)dievaluasi INSERT INTO users (first, last) VALUES(Jennifer, Null)), setiap orang yang namanya tidak sah, kata kunci atau kolom, hanya akan membuat kesalahan dan tidak memasukkan catatannya juga. Penyebabnya harus lebih kompleks.
Andrew Medico
@AndrewMedico dalam contoh pria jerami Anda ya tapi ada banyak cara untuk melakukan sesuatu yang salah. Jangan pernah meremehkan kekuatan kebodohan <strike> <\ strike>. Intinya adalah kita tidak tahu apa masalah sebenarnya karena kita tidak dapat meninjau kode yang dimaksud
Erik
7

Nah, sebelum dimasukkan ke dalam basis data, itu adalah elemen DOM, lalu variabel javascript dilewatkan, divalidasi, dan dimanipulasi, lalu nilai JSON, lalu variabel di pustaka JSON backend apa pun yang Anda gunakan, lalu variabel yang diedarkan, divalidasi, dan dimanipulasi dalam bahasa pemrograman backend Anda, kemudian elemen semacam DAO, kemudian bagian dari string SQL. Kemudian untuk mendapatkan kembali nilainya, Anda melakukan semuanya secara terbalik. Itu banyak tempat bagi programmer untuk membuat kesalahan, dan biasanya banyak itu tanpa manfaat dari pengetikan statis.

Karl Bielefeldt
sumber
2

Kemungkinan besar itu masalah pemrograman. Jika Anda melihat jawaban ini di sini tentang bagaimana NULL sedang dikirimkan, Anda dapat dengan mudah menyebabkan beberapa perilaku yang tidak diinginkan jika Anda adalah "Mr. Null".

https://stackoverflow.com/questions/4620391/mysql-and-php-insert-null-rather-than-empty-string

Anda dapat melihat bahwa jika beberapa elemen data dilewatkan sebagai NULL, data tersebut akan diinterpolasi sebagai database null dalam database.

"NULL"! = Database Null

Beberapa kasus penggunaan dan perilaku terkait ...

Katakanlah nama belakang ditandai dalam database sebagai bukan nol, sekarang ketika data dimasukkan akan ditafsirkan sebagai NULL dan gagal memasukkan.

Kasus lainnya adalah katakanlah nama belakang tidak dapat dihapus dalam database. Tn. NULL dimasukkan dan ditransformasikan menjadi DBNull.Value yang tidak sama dengan "NULL". Setelah menyisipkan, kami tidak dapat menemukan Tn. Null karena nama belakangnya bukan "NULL" tetapi pada kenyataannya nilai null database.

Jadi, itu akan menjadi 2 kasus masalah. Seperti yang ditunjukkan oleh @Amon, basis data sendiri tidak memiliki masalah dengan nulls, meskipun orang harus memahami bagaimana nulls ditangani dalam setiap instance RDMS karena akan ada perbedaan antara vendor yang berbeda.

Jon Raynor
sumber
"Anda dapat melihat bahwa jika beberapa elemen data dilewatkan sebagai NULL, data tersebut akan diinterpolasi sebagai basis data nol di dalam basis data." - Pertanyaan / jawaban-jawaban SO yang ditautkan tampaknya tidak menunjukkan ini?
MrWhite
2

Saya akan menghubungkan masalah ini dengan pemrograman yang ceroboh dan desain yang buruk dari beberapa implementasi SQL. "Null" nama harus selalu disajikan dan ditafsirkan dengan tanda kutip. null, nilai basis data, harus selalu disajikan tanpa tanda kutip; tetapi ketika menulis kode ad-hoc, mudah untuk masuk ke paradigma "apa pun akan melakukan" dan menerima hal-hal yang diyakini sebagai string dalam bentuk tanda kutip.

Ini diperparah oleh fakta bahwa jenis data lainnya; angka misalnya, dapat dan diterima dalam bentuk apa pun karena interpretasinya tidak ambigu.

ddyer
sumber
Maksud Anda implementasi aplikasi yang buruk menggunakan SQL, tentunya? Tidak ada implementasi serius dari RDBMS itu sendiri akan rentan terhadap ini (sama seperti tidak ada aplikasi serius!)
underscore_d
0

Masalahnya, pada dasarnya, adalah bahwa istilah "null" diterapkan dua konsep database yang berbeda, kadang-kadang menggunakan konteks untuk membedakannya:

  1. Sesuatu tidak memiliki nilai yang diketahui
  2. Sesuatu diketahui tidak memiliki nilai

Sementara konteks kadang-kadang cukup untuk membedakan antara konsep-konsep itu, ada saat-saat ketika itu sebenarnya tidak. Jika seseorang menggunakan catatan untuk menyimpan permintaan pencarian, misalnya, harus ada perbedaan antara mengatakan "Saya ingin seseorang dengan nama [apa pun], tanpa nama belakang", dibandingkan "Saya ingin seseorang yang nama depannya adalah [ terserah] tetapi yang nama belakangnya tidak diketahui. " Banyak mesin database memiliki bias terhadap satu arti atau yang lain, tetapi mereka tidak semuanya sama. Kode yang mengharapkan mesin basis data bekerja satu arah dapat mengalami kegagalan fungsi jika dijalankan pada mesin berbeda yang berjalan secara berbeda.

supercat
sumber
Jika sebuah string diketahui tidak memiliki nilai, maka nilainya harus berupa string kosong, bukan string nol.
Byron Jones
0

Sebagian besar jawaban yang ada fokus pada bagian-bagian non-SQL dari suatu aplikasi, tetapi mungkin ada masalah dalam SQL juga:

Jika diperintahkan untuk memfilter catatan di mana nama belakang pengguna tidak tersedia, seseorang yang tidak mengerti SQL dapat menulis filter WHERE u.lastname != 'NULL'. Karena cara SQL bekerja, ini akan muncul untuk memeriksa apakah u.lastname IS NOT NULL: semua NULLcatatan disaring. Semua non- NULLrekaman tetap ada.

Kecuali tentu saja untuk catatan di mana u.lastname == 'NULL', tetapi mungkin tidak ada catatan seperti itu tersedia selama pengujian.

Ini menjadi lebih mungkin jika SQL dihasilkan oleh semacam kerangka kerja, di mana kerangka kerja itu tidak memaparkan cara yang mudah diakses untuk memeriksa NULLketaksesuaian dengan parameter, dan seseorang memperhatikan "hei, jika saya meneruskan string NULL, itu melakukan persis apa yang saya inginkan! "

hvd
sumber