Як прізвище Null викликає проблеми у багатьох базах даних?


71

Я читав статтю на BBC. Одним із прикладів, про які вони казали, є те, що у людей з прізвищем 'Null' виникають проблеми з введенням їхніх даних на деяких веб-сайтах.

Не пояснюється помилка, з якою вони стикаються.

Але наскільки я знаю, рядок 'Null' і фактичне значення Null абсолютно різні (з точки зору бази даних).

Чому це може спричинити проблеми в базі даних?


2
Це дещо відома стаття в блозі про припущення, що програмісти роблять щодо імен, написана одним із людей, цитованих у цій статті BBC: kalzumeus.com/2010/06/17/…
Jörg W


2
Дивіться також: stackoverflow.com/questions/4456438/…
Foon

4
Перший раз, коли я побачив цього хлопця по телевізору, я припустив, що це помилка в базі даних. Тоді я дізнався, що насправді його звуть.
Нейт Елдредж

3
@JarrodRoberson Як ви можете сказати, що "вся передумова помилкова", враховуючи опис проблем, з якими стикаються "Дженніфер Нулл" та подібні назви у посиланні, яке розміщувало ОП? Це справжнє питання, з яким стикаються реальні кінцеві користувачі.
Стівен Бернап

Відповіді:


102

Це не викликає проблем із базою даних. Це спричиняє проблеми в програмах, написаних розробниками, які не розуміють баз даних. В основі проблеми полягає в тому, що велика кількість програмного забезпечення, пов'язаного з базою даних, відображає запис NULL як рядок NULL. Якщо програма потім покладається на строкову форму запису NULL (ймовірно, також використовуються операції порівняння, нечутливі до регістру), тоді така програма вважатиме будь-яку "null"рядок NULL. Отже, ім'я Null вважається відсутнім у цій програмі.

Рішення полягає в оголошенні ненульових стовпців, як NOT NULLу базі даних, і не застосовувати рядкові операції до записів бази даних. Більшість мов мають чудові API баз даних, які роблять інтерфейси рівнинного рівня непотрібними. Їм завжди слід віддавати перевагу, також оскільки вони роблять інші помилки, такі як інжекція SQL, менш ймовірними.


30
Однак у цьому випадку, якщо ви прочитаєте цю статтю, введення поля прізвища NOT NULLспричинить цілий набір проблем для інших людей. "Деякі особи мають лише одне ім'я, а не прізвище та прізвище."
MikeTheLiar

41
@Darkhogg багато людей не погоджуються зі мною з цього приводу, але я думаю, що імена схожі на адреси електронної пошти - не переймайтеся їх підтвердженням, дайте користувачеві єдине текстове поле і нехай вони ставлять все, що вони хочуть. Це інформація, що якщо мені це дуже потрібно, я отримаю її від вас таким чином, який, безумовно, є правильним.
MikeTheLiar

8
@mikeTheLiar Я не знаю назви цього, але є цілий клас помилок, які виникають при створенні надмірно обмежувальних правил щодо даних. Часто ви бачите поштові індекси та телефонні номери, визначені як цифрові в додатках та базах даних. Вони насправді не числа, тому що не має сенсу робити математичні операції над ними. Тому коли хтось намагається ввести канадську адресу, він застряг.
JimmyJames

19
@JimmyJames Так, поштові індекси, що зберігаються як цифри, і раптом у кожного, хто тут живе , є поштовий індекс базової 8. "Якщо ви не займаєтеся математикою, це струна," Повна зупинка ".
MikeTheLiar

8
@mikeTheLiar. Проблема з поводженням з іменами як з одним рядком (як правило, краще, я згоден) полягає в тому, що є вимога алфавітного сортування за прізвищем.
TRiG

13

Щоб відповісти на ваше конкретне питання, існує багато кроків по ланцюжку подій між веб-формою та базою даних. Якщо прізвище Nullпомилково трактується як NULLзначення, то система може відхилити абсолютно допустиме ім'я як недійсне. Це може статися на рівні бази даних, як пояснив amon . До речі, якщо це конкретна проблема, то база даних, ймовірно, також відкрита для ін'єкції SQL AKA атаки Bobby Tables . Ще одним кроком ланцюга, який може спричинити проблеми, є процес серіалізації .

Загалом стаття стосувалася більшої проблеми. Світ - це велике безладне місце, яке не завжди відповідає нашим припущенням. Це особливо очевидно, коли ви намагаєтеся інтернаціоналізувати свою заявку. Зрештою, нам потрібно забезпечити належним чином обробляти наші програми та кодувати наші дані . Саме бізнес повинен вирішити, скільки ресурсів ми виділяємо на підтримку все складніших справ. Хоча я повністю підтримую всеосяжне включення, я зрозумію, якщо бізнес вирішить, що "художнику, формально відомому як Принц", потрібно використовувати символ Unicode для представлення його імені в нашій базі даних.


Важко уявити, що це спричинене якоюсь небезпечною інтерполяцією рядків, яка може призвести до ін'єкції SQL. Якщо ви забудете ввести запит користувача у SQL-запиті (наприклад, INSERT INTO users (first, last) VALUES($first, $last)оцінює INSERT INTO users (first, last) VALUES(Jennifer, Null)), усі, чиї імена не є дійсними ключовими словами SQL або іменами стовпців, просто збираються видаляти помилки, а також не вставляти свої записи. Причина повинна бути більш складною.
Ендрю Медіко

@AndrewMedico у прикладі вашої солом'яної людини так, але існує багато способів зробити щось не так. Ніколи не варто недооцінювати силу <страйку> дурості <\ strike> незнання. Суть полягає в тому, що ми поняття не маємо, що є справжньою проблемою, тому що ми не можемо переглянути код, про який йде мова
Ерік,

7

Перед тим, як вводити його в базу даних, це елемент DOM, потім змінна javascript передається навколо, перевіряється і маніпулюється, потім значення JSON, потім змінна в будь-якій бібліотеці JSON, яку ви використовуєте, потім змінна передається навколо, перевірений і маніпульований вашою базовою мовою програмування, то елементом якогось DAO, то частиною рядка SQL. Потім, щоб повернути значення, ви робите це все навпаки. Це багато місць для програмістів, які можуть помилитися, і зазвичай це багато, без користі від статичного набору тексту.


2

Швидше за все, це питання програмування. Якщо ви подивитесь на цю відповідь тут про те, як передаються NULL, ви могли легко викликати небажану поведінку, якби ви були "містером Нуллом".

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

Ви можете бачити, що якщо якийсь елемент даних буде передано як NULL, дані будуть інтерпольовані як нуль бази даних у базі даних.

"NULL"! = Нуль бази даних

Деякі використовують випадки та пов'язані з ними поведінки ...

Скажімо, прізвище було позначене в базі даних як недійсне, тепер, коли дані вставлені, воно буде інтерпретуватися як NULL і не вдасться вставити.

Ще один випадок - скажімо, прізвище було замінено в базі даних. Містер NULL вставляється і перетворюється в DBNull.Value, який не є "NULL". Після вставки ми не можемо знайти містера Нулла, оскільки його прізвище не "NULL", а насправді нульове значення бази даних.

Отже, це були б 2 випадки проблем. Як зазначає @Amon, самі бази даних не мають проблем із нулями, хоча слід розуміти, як обробляються нулі у кожному екземплярі RDMS, оскільки між різними постачальниками будуть різниці.


"Ви можете бачити, що якщо якийсь елемент даних буде передано як NULL, дані будуть інтерпольовані як нуль бази даних у базі даних." - пов'язане запитання SO / прийнята відповідь не відображає це?
MrWhite

2

Я б пояснив проблему неохайним програмуванням і поганим дизайном деяких реалізацій SQL. Ім'я "Недійсне" завжди повинно бути представлене та інтерпретоване цитатами. null, значення бази даних, завжди повинно бути представлено без лапок; але при написанні спеціального коду легко перейти в парадигму «все, що буде робити», і прийняти речі, які вважаються рядком у вигляді без котирування.

Це ускладнюється тим, що інші типи даних; цифри, наприклад, можуть і приймаються в будь-якій формі, оскільки інтерпретація однозначна.


Ви маєте на увазі погану реалізацію програм, що використовують SQL, звичайно? Жодна серйозна реалізація RDBMS сама по собі не буде вразлива для цього (так само, як ніякої серйозної програми!)
underscore_d

0

По суті, проблема полягає в тому, що до терміна "null" застосовуються дві різні концепції бази даних, іноді використовуючи контекст, щоб розрізняти їх:

  1. Щось не має відомого значення
  2. Щось, як відомо, не має значення

У той час як контекст іноді може бути достатнім для розмежування цих понять, бувають випадки, коли цього насправді немає. Якщо, наприклад, використовується запис для проведення пошукового запиту, наприклад, повинна бути різниця між словами "Я хочу когось по імені [що], без прізвища", проти "Я хочу когось, чиє прізвище є [ що завгодно], але прізвище якого невідомо ». Багато двигунів баз даних мають ухил до того чи іншого сенсу, але вони не однакові. Код, який очікує, що двигун бази даних працює в один бік, може працювати несправно, якщо він працює на іншому двигуні, який працює інакше.


Якщо рядки, як відомо, не мають значення, то значення повинно бути порожнім рядком, а не нульовим рядком.
Байрон Джонс

0

Більшість існуючих відповідей зосереджені на частинах програми, що не належить до SQL, але може виникнути проблема і в SQL:

Якщо доручено фільтрувати записи, де прізвище користувача недоступне, той, хто не дуже добре розуміє SQL, може написати фільтр WHERE u.lastname != 'NULL'. Через те, як працює SQL, це з'явиться, щоб перевірити, чи u.lastname IS NOT NULL: усі NULLзаписи фільтруються. Усі незаписи NULLзалишаються.

За винятком записів, де u.lastname == 'NULL', але, можливо, не було таких записів під час тестування.

Це стає більш імовірним, якщо SQL породжується якимось фреймворком, де цей фреймворк не піддається легкодоступному способу перевірити наявність NULLнестабільності з параметрами, і хтось помічає "ей, якщо я передаю рядок NULL, це робить саме те, що я хочу! "

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.