Причина не використовувати нульове число в Oracle?


12

Наша компанія взаємодіє з іншою програмною компанією для спільного проекту, і нам сказали, що якщо певна цінність не повинна відображатися, ми повинні передавати -5000 (їх довільне значення вартового); Причина полягає в тому, що жоден стовпчик номерів у їхній базі даних Oracle не підтримує нульових значень за рекомендацією їх (тепер уже колишнього) розробника Oracle. Ця компанія також пише переважну більшість своїх кодів у VB6 (повільно переходить на VB.NET, що є ще однією темою для іншого дня ...). Чи є чиста цікавість, чи є якась поважна причина цієї рекомендації? Я не можу думати ні про кого зі свого боку.

--- редагувати

Дякую за відгук усім. Я поставив те саме питання на CodeProject.com ( посилання ) і отримав дуже схожі відгуки. Здається, єдиний раз, коли можна було б почати виправдовувати цю практику, пов’язану із зовнішніми ключами, і я можу констатувати, що вони не використовують жодних сторонніх ключів ніде в системі. Розробник, який прийняв таке визначення (я працював у цій компанії), має значно більший досвід, ніж я, тому я хотів переконатися, що не було поважної причини для цього до появи насмішок.


2
Ви маєте на увазі, крім "це те, що їх API визначає"?
Роберт Харві

Так, мені цікавіше, чому їх API вказував би це в першу чергу; чи є причина такої практики, чи це просто якийсь безумство?

3
Лунаття вищого порядку!
Philᵀᴹ

Відповіді:


17

Реально вимога є шаленою. Як і всі великі божевільні ідеї, проте, ймовірно, вона базується на самороді потенційної розумності, виведеній далеко за рамки контексту людьми, які не розуміють основного обґрунтування.

Можна розробити схему бази даних таким чином, щоб не NULLдопускалося жодних значень. Однак якщо ви це зробите, ви здійснюєте рівень нормалізації, коли кожен необов'язковий елемент розбивається на окрему таблицю з відповідним посиланням на зовнішній ключ назад до батьківського. Це не часто робиться на практиці, але у випадках, коли це має сенс робити, можуть бути користі.

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


+1 і додатковий код для перевірки магічних значень не можуть використовувати добре відомі функції, наприклад COALESCE()- це стає ще складніше.
ypercubeᵀᴹ

І значення потрібно зберігати в будь-якому індексі цього стовпця. Індекси не повинні зберігати нульові значення.
Tripp Kinetics

15

Немає дійсної причини використовувати магічне значення замість NULL. Це може бути процес думки того, хто створює цей безлад. Вони пишуть щось подібне:

 SELECT c1, c2 FROM t1 WHERE c3 < 30;

Коли це не повертає результатів, які вони очікують, вони розуміють, що він не включає NULL, і потрібно було б написати це:

SELECT c1, c2 FROM t1 WHERE c3 < 30 OR c3 IS NULL;

Вони не хочуть писати або забувати в майбутньому писати це, тому вони придумали рішення зробити всі NULLS -5000. Магічно їх оригінальний запит обробляє NULL без будь-яких змін. Що вони не усвідомлюють, це те, що тепер хтось, хто хоче виключити ці значення, повинен написати це:

SELECT c1, c2 FROM t1 WHERE c3 < 30 AND c3 <> -5000;

Або якщо вони хотіли цих значень і шукають більш високий діапазон:

SELECT c1, c2 FROM t1 WHERE c3 > 40 OR c3 = -5000;

Вони також можуть не усвідомлювати, що наступне більше не матиме значення:

SELECT c1, c2 FROM t1 WHERE c3 IS NULL;

Натомість людина повинна пам’ятати про магічну цінність. З кожним використовуваним типом даних вони повинні пам'ятати більше магічних значень, наприклад, 1/1 // 1900, "Z", -5000. Крім того, коли магічне значення є в даних, вони також повинні пам’ятати альтернативні магічні значення.

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


8

Це повне безумство і немає виправдання для цього. NULLстворено для відображення відсутності значення та використання фактичного значення, наприклад -5000 - це бонкери.

Зазвичай я б не писав відповіді на цю коротку відповідь, але це питання заслуговує на те, щоб бути одним із найбільш помітних на dba.se & чим більше відповідей, тим краще.


5

Я подумав про це, щоб трохи намагатися бути позитивним та обґрунтувати необхідність використання довільного значення замість нуля, і, здається, (мені щонайменше) для цього немає вагомих причин, за винятком, можливо, закритого набору даних обміну даними для покращення та спрощення продуктивності та запитів, а потім лише у випадках, коли цифри не є значеннями, які можуть перекосити дані. Навіть це треба було б уважно розглянути. У всіх ситуаціях у реальному світі надання нуля значення не є хорошою практикою. Це перетворює визначення колонки NOT NULL від вашого друга до вашого ворога, оскільки це дійсно не відповідає дійсності.

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

Більшість проблем, які викликають нулі, зрозуміли, можна вирішити (краща нормалізація, на основі функцій або індексів растрових зображень або простого WHERE x НЕ NULL). Чи вважаєте ви, що на якомусь великому Telco або Amazon на щомісячній зустрічі з ефективністю деякі DBA окреслюють цей чудовий план, щоб трохи прискорити запити на їх величезних наборах даних, "замінивши null на довільне значення, щось на зразок -5000, або що завгодно - Я відкритий на значення ... ". Або ви вважаєте, що вони витрачають свій час на кращий дизайн додатків, щоб відфільтрувати небажані нулі та оптимізацію запитів на основі фактичних даних, які вони отримують ? Гаразд, штраф, можливо, щомісячна зустріч є дещо оптимістичною, але, коли вони відбудуться, я можу запевнити, що "Заміна нульових значень на -5000 (або що завгодно) на кращий API" не є пунктом порядку денного.

Для мене добре сказати, що я не прийму відсутні дані (у вас повинен бути вік, ціна, код регіону чи будь-який інший), а іноді навіть добре сказати, що для цього стовпця є значення за замовчуванням, яке буде введено, якщо ви не ставите щось інше. Недоречно відкладати значення, яке означає нульове значення. Подумайте про приклади середніх імен як приклад. Іноді таких не буде, оскільки батьки ліниві, щоб заповнити всі поля. Чи додаємо ми "жодні" або "відсутні" чи "невідомі" до наших даних, щоб покращити пошук? Ні, тому що можуть бути дивні люди, які змінюють свої імена на ці значення, і тому, коли ми друкуємо дані, ми не знаємо, чи потрібно їх включати чи ні. Це простий, але далекосяжний приклад. Ми знаємо про NULL і маємо передбачувані вбудовані функції для боротьби з ним. Ви не можете це краще кодувати.

Якщо жодна відповідь (або NULL) не є дійсною відповіддю на ваш запит на введення, тоді не дозволяйте цього в додатку чи в базі даних, якщо це хороша відповідь, тоді ви повинні дозволити це як у вашій програмі, так і у вашій базі даних та мати справу з це як дійсна відповідь. Якщо вона є частиною набору дійсних відповідей, ваша база даних повинна бути розроблена для її зберігання. Зрештою, ви не кажете, ей, числові поля настільки нудні, дозволяють зберігати номери в краплі і використовувати зображення диких тварин для представлення кожного числа, адже це горіхи (круто, але горіхи). Ми також не вирішуємо, що нам не подобається літера B, і, як якийсь жорстокий кошмар на вулиці Сезам, замінить її на # у наших даних. Якщо B - не відповідь, ми хочемо сказати користувачеві "Ей, ви не можете поставити B тут" Так навіщо ставитися до нуля по-різному?

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


2
Мої батьки не лінувалися і я до речі не маю прізвища. Не всі люди живуть у США.
ypercubeᵀᴹ

1
Це повинно було бути легким прикладом, жодного образи не означало. Звичайно, багато людей без прізвищ (перший пункт) з багатьох цілком поважних причин (основний пункт). Нуль у цій колонці нічого не говорить про те, чому він відсутній. Не впевнений у своєму геополітичному куті - я не живу в США, але насправді маю прізвище. Важко робити припущення на основі відсутніх даних, я думаю.

Жодного правопорушення не брали. Я фактично підтримав вашу відповідь. Я думаю, що ти чітко зазначив, що існує різниця між неприйняттям / дозволом Nulls в базі даних та заміною Nulls на магічне значення.
ypercubeᵀᴹ

5
Мені б подобалося, якби моє прізвище було «-5000»! : D
Philᵀᴹ
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.