Що робити, коли не вдається визначити булеве значення?


38

Ми будуємо веб-додаток для компанії, адміністрація якої досі існувала лише на листах Excel. Ми вже майже закінчились, але нещодавно мені було поставлено завдання імпортувати всі їх дані з цих аркушів до нашої нової системи. Система побудована на Java, але оскільки цей імпорт - це лише разова річ, я вирішив замість цього написати сценарії в Python та імпортувати їх безпосередньо із запитами SQL. Тут виникає проблема. Нові моделі даних містять деякі нові атрибути, які не включені до їх наявних даних. У більшості випадків це не проблема, я просто кладу нуль, де я не можу знайти інформацію. Але тоді я зіткнувся з кількома атрибутами, які є булевими і не можуть бути NULL за замовчуванням. Спочатку я спробував дозволити нуль для цих полів у нашій базі даних, але мій старший розробник сказав мені, щоб цього не робити, як це може спричинити проблеми в нашій системі в майбутньому. І зараз я не зовсім впевнений, що робити. Очевидним рішенням є встановлення за замовчуванням кожного невідомого булевого значення false, але я думаю, що це теж неправильно, тому що я насправді не знаю, чи це false.

Приклад: Скажімо, у вас є автомобіль сутності, який має параметр hasRadio. Тепер вам потрібно імпортувати дані в цю модель даних, але в даних є лише стовпці "Модель" і "Колір", нічого про це не має або не має радіо. Що ви ставите в стовпчик "hasRadio", якщо дизайн не може бути нульовим?

Який найкращий підхід у цій ситуації? Чи варто просто сказати компанії вручну заповнити відсутні дані? Або за замовчуванням це значення false?


70
Для мене дозвіл NULL було б правильним рішенням. Чи був ваш старший більш конкретним, ніж "викликати проблему в нашій системі в майбутньому"? Якщо ні, попросіть його з більш конкретних причин.
larsbe

48
FileNotFoundОчевидно, ви повинні встановити це за замовчуванням .
Ти

7
Чи можна було б додати булеве поле, "isValidHasRadio" чи щось таке, чи це занадто порушило б речі?
Гайда

9
Правильним рішенням є розгляд вхідних даних сміття та переривання всієї транзакції, а потім вимагати коригування визначення завдання, якщо ці дані не повинні вважатися сміттям. Іншого шляху тут немає.
Sarge Borsch

17
До речі, я не великий фанат нульових значень. Я вважаю за краще використовувати «Невідомо», «Має радіо» та «Не має радіо». Таким чином, ви покриваєтесь своїми вимогами та маєте можливість зростати, якщо вам доведеться в майбутньому вказати тип радіо, наприклад, "Радіо з інтегрованим телебаченням" чи щось подібне.
Мачадо

Відповіді:


129

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

Зазвичай це призводить до одного з таких випадків:

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

  • є правило, як визначити ідеальне значення за замовчуванням з іншої інформації, тому ви можете ввести це правило в код

  • користувачі або ваш клієнт розширять вхідні дані та нададуть відсутні значення (можливо вручну), перш ніж вони будуть імпортовані в базу даних

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

В останньому випадку потрібно щось на зразок NULL для представлення неініціалізованого або невідомого стану, навіть для булевого значення, якщо вам це подобається чи ні. Якщо є якась незрозуміла технічна причина, яка забороняє використовувати значення NULL для конкретного стовпця, вам потрібно імітувати стан "невідомого" по-іншому, або шляхом введення додаткового булевого стовпчика (наприклад hasRadioIsUnknown), або за допомогою 3 значне перерахування замість булева (наприклад HasNoRadio=0, HasRadio=1, Unknown=2). Але знову поговоріть зі своїм старшим після того, як ви зробили ретельний аналіз вимог, щоб переконатися, що такий спосіб дійсно необхідний.


29
Також слід зазначити, що така ж відповідь стосується й інших стовпців, де ви зручно користувались NULL. Ви повинні перевірити, чи це правильне значення за замовчуванням. Наприклад, якщо в якомусь іншому стовпці написано "обробкаIsFinished", і ви імпортуєте старі дані з історії замовлень клієнтів (думаючи про веб-магазин), можливо, вам знадобиться встановити значення "справжнє", а не "NULL", щоб уникнути запуску деяких процесів. коли вони стикаються з записами, які ще не оброблені (відповідно до їх інтерпретації цього стовпця).
Френк Хопкінс

1
Це функціональне питання. Через те, що моделі (відмінності та нова) не відповідають, процес міграції слід переглянути, враховуючи ці випадки. Єдине, що може сказати, як діяти, - це / це зацікавлені сторони (замовник чи хтось). Технічно ви можете вирішити це багатьма способами, але функціонально лише одним. Право.
Laiv

12
Мені подобається ця поломка. Моє неприємність до нуля в цьому контексті здебільшого пояснюється відсутністю чіткого сенсу. Невідомо зрозуміло. Але чи означає null невідомий чи не застосовується? Як би хто знав? Тільки тому, що для вас це має сенс, не означає, що всі інші побачать це однаково.
candied_orange

Варіант 4: Записи, у яких відсутнє певне значення стовпця, насправді марні і їх слід виключити з імпорту. Варіант 5: комусь потрібно виправити всі вхідні дані, перш ніж вони будуть імпортовані. Багато варіантів, просто залежить від потреб та бюджетів. Імпорт старих даних - це завжди безлад.
jpmc26

@ jpmc26: ну, я не включив варіант 4, оскільки я хотів дотримуватися того, що написав ОП буквально (випадок, коли відсутні дані точно не включені до даних про імпорт, без запису). Варіант 5 дійсно варто згадати, оскільки це ще один спосіб уникнути необхідності NULL-значень. Відповідно відредагував мою відповідь.
Док Браун

39

Це не технічне питання; це питання ділових правил. Отже, вам потрібно запитати "бізнес".

Підійдіть до власника продукту та / або зацікавлених сторін і скажіть щось на зразок:

У нас є неповні дані для одного з полів, про які ви запитували в додатку. Хочете, щоб ми використовували значення за замовчуванням? Ви хочете, щоб ми додали "невідомо" як дійсне значення? Або ви хочете, щоб хтось із вашої команди виправляв дані перед імпортом?

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


9

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

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

Певна різниця, ймовірно, пов'язана з невідповідністю моделі даних. Справа з цим значною мірою полягає в тому, щоб (тісно) ознайомитись з обома моделями даних та знати, як віднести стару до нової. До тих пір , як новий один є здатним захоплювати старий. (Якщо ні, у вашої команди, швидше за все, є дуже велика проблема.) Це може зажадати більше роботи, ніж просто копіювання стовпців. Darkwing дає чудовий приклад цього (а також, чому сліпо вставляти NULLs - це неправильно). Розвиваючи це, якщо у старої моделі було ReceivedDateі InProgressтрохи, а в новій моделі є StartDateі ProcessingEndTime, вам потрібно буде вирішити, чи і як встановити ProcessingEndTime. Залежно від способу його використання, розумним (але довільним) вибором може бути встановлення його таким же, як іStartDate (або незабаром після цього, якщо це спричинить проблеми).

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

Наприклад, уявіть рахунок-фактуру, який мав кількість та загальну кількість одиниць товару (але не одиницю ціни), за винятком того, що деякі кількості були незрозуміло відсутніми. Розмовляючи з особою, яка обробляє такі рахунки, може створити один (або більше) з наступних сценаріїв: 1) "о, порожня кількість означає кількість 1", 2) "о, я знаю, що ці товари коштують приблизно за 1000 доларів, Очевидно, це замовлення на 2 ", 3)" коли це трапляється, я шукаю ціну в цій іншій системі і розділяю і округляю ", 4)" Я шукаю її в іншій системі ", 5)" це не реальні дані ", 6)" ніколи раніше цього не бачив ".

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


14
Підсумовуючи це: якщо ви вважаєте, що працювати зі застарілим кодом неприємно, спробуйте розібратися зі застарілими даними.
Пітер Тейлор

0

Зміна моделю даних.

Ви можете нормалізувати hasradio, і тоді у вас більше не буде нічого.

Якщо ви не можете визначити булеве значення, не використовуйте булеве значення.

Дозволяючи булевому значенню стати нульовим, він перестає бути булевим. Булева може мати 2 стани: хибне, істинне.

Те, що вам потрібно, це 3 стани: хибне, істинне, невідоме.

Чи є у вас можливість змінити модуль даних?

(І ще одне, про що я подумав, якщо в python або java ви отримаєте дані зі своєї бази даних. Ви отримаєте запис, перевірте поле hasradio. Що буде, якщо ви перевірите, чи це правда чи помилка, і якщо це стане недійсним?)


2
Змінюючи модель даних і «нормалізує з hasRadio», я вважаю , ви маєте в виду що - щось на зразок додавання нової таблиці CarFeaturesз полями Car_ID, Feature_ID, Has_Feature? Здається, гарна ідея.
jpa

2
@jpa це трохи хитра ситуація. Ви повинні бути чітко зрозумілими, чим займаєтесь, адже відсутність запису в нашій ситуації означає невідоме. Хоча часто відсутність запису означає, що він не має цієї функції.
Пітер Б

1
Ви дивитесь на це неправильно, Пітер. Ніхто не каже, що а boolмає більше двох значень, тому що, як ви вже сказали, це не так. А boolє trueабо false. Однак у випадку з ОП ОП має справу не boolбезпосередньо, а скоріше із тим Option<bool>/Maybe<bool>, що може мати Some -> true/falseабо None.
Енді

@DavidPacker мій аргумент полягає в тому, що через це це, можливо, <bool>, ви повинні перестати називати це щось віддалено схоже, або ви отримаєте плутанину. І якщо ви наполягаєте на використанні булева, то знайдіть безпечний спосіб це зробити.
Пітер Б

4
На мою думку, нульовий булевий повністю чудово. У мене ніколи не було проблем з нульовими значеннями, хоча я зустрічав розробників, які це робили.
Енді

-1

Як зазначали інші, те, що ви маєте тут, є булевим значенням, яке не є справді булевим, і проблема полягає в тому, щоб або змусити його бути булевим, або обробити його інакше.

Що ви можете зробити - це замість того, щоб мати єдиний булевий результат, мати два булевих результату. Вони можуть або погодитися, або не погодитися. Якщо вони згодні, то у вас є прямий істинний / хибний результат.

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

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

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