Що сталося з обмеженнями в базі даних?


46

Переглядаючи моделі баз даних для RDBMS, я зазвичай здивований, виявляючи мало-ніяких обмежень (окрім PK / FK). Наприклад, відсоток часто зберігається у стовпчику типу int(хоча це tinyintбуло б більш доцільно), і немає CHECKобмежень обмежувати значення діапазоном 0..100. Аналогічно на SE.SE, у відповідях, що пропонують перевірити обмеження, часто надходять коментарі, які свідчать про те, що база даних є неправильним місцем для обмежень.

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

  • Або що вони навіть не знають, що такі функції існують у їх улюбленій базі даних. Це зрозуміло лише для програмістів, які використовують ORM, але набагато менше від DBA, які стверджують, що мають 5+ років досвіду роботи з даними RDBMS.

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

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

Запитуючи команди про вибір не використовувати ФК, вони відповідають:

  • Наприклад, PITA, коли потрібно видалити елемент, на який посилаються в інших таблицях.

  • NoSQL гойдається, і сторонніх ключів там немає. Тому вони нам не потрібні в RDBMS.

  • Це не велика справа з точки зору продуктивності (контекст, як правило, це невеликі веб-додатки інтрамережі, що працюють на малих наборах даних, тому, навіть, навіть індекси не мали б великого значення; нікому не буде байдуже, чи ефективність даного запиту переходить за 1,5 с до 20 мс.)

Переглядаючи саму програму, я систематично помічаю два зразки:

  • Додаток належним чином дезінфікує дані та перевіряє їх, перш ніж надсилати їх у базу даних. Наприклад, немає можливості зберігати значення 102у відсотках через додаток.

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

  • Хоча більше 99% запитів виконуються однією програмою, з часом починають з'являтися сценарії - або сценарії, які виконуються вручну при необхідності, або завдання Cron. Деякі операції з даними також виконуються вручну над самою базою даних. І сценарії, і ручні запити SQL мають високий ризик введення недійсних значень.

І ось тут виникає моє запитання:

Які причини моделювання реляційних баз даних без обмежень перевірки і, зрештою, навіть без сторонніх ключів?


Оскільки це варте, це запитання та відповіді, які я отримав (особливо цікаве обговорення з Томасом Кіліаном), змусили мене написати статтю зі своїми висновками з приводу обмежень бази даних .


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

1
@JacquesB: ви можете опублікувати відповідь, оскільки "я це бачив десятиліттями" дає зовсім інше бачення того, що у мене виникло явище, яке з'явилося три-чотири роки тому (враховуючи, що я працював в ІТ менше, ніж десятиліття, моє бачення явища, мабуть, неправильне). Таким чином, висновки також були б дуже різними.
Арсеній Муренко

1
Ми працюємо з великою кількістю клієнтів. І хоча розгортання нової версії нашого програмного забезпечення - це шматок пирога, оновлення всіх баз даних скрізь - це біль. Ось чому у нас найбільше обмежень у програмному забезпеченні. О так, крихітний відсоток часто не є хорошою ідеєю, оскільки відсотки можуть бути дробами.
Пітер Б

1
Голосування за повторне відкриття цього питання, оскільки воно було неправильно закрите як "в першу чергу на основі думки", коли відповіді поки що показують, що це не так.
Девід Арно

3
Я з тобою 110%.
Periata Breatta

Відповіді:


28

Важливо розрізняти різні випадки використання для баз даних.

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

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

Коли зустрічаються розробники з різних груп, ви стикаєтеся з культурою.

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


5
+! 1 для згадки про слона в кімнаті: помилкове припущення, що в одній програмі використовується лише одна БД, а одна БД використовується лише однією програмою
Тулайн Кордова

4
@ TulainsCórdova, я думав, що слон у кімнаті тут - система оплати праці Google. :)
Мачадо

5
@Machado Це геніально: "Я готовий зробити ставку, що їх система оплати праці працює на реляційній базі даних з великою кількістю обмежень".
Tulains Córdova

2
Також зручно мати належним чином обмежені бази даних, оскільки код вашої програми не є кислотним.
Матвій Віт

3
Наголошуючи лише на коментарі, зробленому @MatthewWhited, програми не можуть застосовувати деякі обмеження міжрядкових / міжстолових обмежень без виконання блокування та запуску додаткових запитів. RDBMS може це зробити за значно нижчі витрати.
Девід Олдрідж

15

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

При цьому всі програми, які повинні масштабуватися, обмежуються теоремою CAP , де вам потрібно вибрати 2 з 3: послідовність, доступність та толерантність розділів (толерантність мережі).

Вивчаючи теорему CAP, ви побачите, що вибору не так вже й багато, але вибираєте втратити доступність чи послідовність, оскільки ви НІКОЛИ не можете довіряти Мережі 100% часу.

Загалом, кілька програм можуть дозволити собі бути непослідовними протягом певного розумного часу, але не можуть дозволити собі бути недоступними для користувачів. Наприклад, трохи не упорядкована хронологія у Facebook чи Twitter краще, ніж взагалі не мати доступу до часової шкали.

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

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

Msgstr "Модуль оцінки в ребусі". Давайте продовжимо використовувати послідовність DB "низького рівня", коли послідовність є вимогою першого класу. Але іноді відпустити це не є великим гріхом.

- EDIT: -

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

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


"Я просто не можу знайти жодного механізму бази даних, який не підтримує простих обмежень, таких як запропонований в оригінальному запитанні." Чи підтримує MySQL перевірка обмежень?
Вінсент Савард

@VincentSavard, можливо, не точний CHECK MS SQL робить, але якесь обмеження це робить: dev.mysql.com/doc/refman/5.7/en/constraint-invalid-data.html
Machado

@Machado - це не стосується конкретних обмежень, але настільки, щоб визначити, коли запити включають дані, які не можуть бути представлені у відповідних типах. Що явно покращило ситуацію років тому, коли MySQL просто мовчки ігнорував такі значення.
Periata Breatta

1
@PeriataBreatta, зі сторони, я ніколи не повністю розумів, чому MySQL був "фактично" базою даних OSS, обраною розробниками веб-сайтів, коли PostgreSQL був повністю доступний і був більш досконалим. Може, це було легше встановити, я не знаю.
Мачадо

@machado - я не можу бути впевнений , але я знаю, що в перші дні (ще в середині 90-х) я прагну віддавати перевагу mysql postgres (який не перейменований на postgresql пізніше) через неправильне уявлення про postgres не підтримував SQL (його ранні версії не мали - у нього була своя мова запитів під назвою "postquel" - і я не був в курсі його розробки, тому не зрозумів, що вони додали підтримку SQL приблизно в той же час mysql став доступний). Якщо ця помилка була поширеною, можливо, mysql випереджав саме через це. І як тільки це було попереду, мережеві ефекти перейняли.
Periata Breatta

10

Які причини моделювання реляційних баз даних без обмежень перевірки і, зрештою, навіть без сторонніх ключів?

Спочатку давайте зрозуміємо, що я говорю тут лише про RDBM, а не про бази даних без SQL.

Я бачив декілька баз даних без ФК або ПК, не кажучи вже про обмеження, але якщо чесно, вони меншість. Можливо тому, що я працюю у великій компанії.

З мого досвіду за ці роки я можу сказати, що деякі причини можуть бути:

  • Що стосується початківців або хобі- програмістів, то все, що стосується навичок моделювання
  • Широке або майже ексклюзивне використання ORM без реального контакту зі світом баз даних
  • Відсутність спеціаліста з питань внутрішніх справ або іншого експерта з моделювання даних у команді чи невеликому проекті
  • Відсутність залучення до участі в роботі DBA або експерта з моделювання даних на перших етапах розробки
  • Навмисні дизайнерські рішення тієї частини спільноти розробників, яка вважає, що навіть обмеження перевірки, яке примушує певний стовпець може мати 1,2 or 3лише значення, або що стовпець "вік" повинен бути >= 0, "має ділову логіку в базі даних" . Навіть пропозиції за замовчуванням деякі вважають діловою логікою, яка не належить до бази даних, як ви бачите в кількох останніх питаннях та відповідях на цьому самому сайті. Цей розробник, який так вважає, очевидно використовував би якомога менше обмежень і зробить усе в коді, навіть референтну цілісність та / або єдиність. Я думаю, що це надзвичайна позиція.
  • Використання RDBM в якості сховищ ключових значень , або для емуляції поведінки без SQL, оскільки вимоги, де досить просто, щоб їх задовольнити, використовуючи таблиці RDBMS як ізоляцію сховищ ключових значень.
  • Якщо припустити, що база даних завжди буде записана "додатком", і нікому ніколи не доведеться робити велике завантаження даних або редагувати або вставляти рядки через клієнт SQL (у багатьох випадках для виправлення поганих даних, доданих додатком). У кращому випадку escenario завжди буде інший додаток (окрім "додатка"), що видає інструкції DML до бази даних: клієнт SQL.
  • Не розуміючи, що дані належать власнику бізнесу , а не додатку.

З цього приводу я хочу зазначити, що RDBMS - це дуже вдосконалене програмне забезпечення, яке було побудоване за плечима гігантів і виявилося дуже ефективним для багатьох бізнес-вимог, звільняючи програмістів від повсякденних завдань забезпечення референтної цілісності на серію бінарних або текстових файлів. Як я завжди кажу: «ми більше не живемо у світі« одна програма-одна-база даних » . Принаймні, клієнт SQL видасть DML, крім "програми". Таким чином, база даних повинна захищатись від помилок людини або програмування в розумній мірі

У тих добре відомих типах вимог, коли RDBMS не буде добре масштабуватись, усіма силами застосовують технологію no-SQL . Але турбує поширення реляційних баз даних без обмежень, коли тисячі рядків коду (згенерованих або набраних) присвячені виконанню того, що RDBMS повинно застосовувати для вас більш ефективними способами.


3

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

  1. Підприємства мають розробників як для додатків, так і для баз даних разом з DBA, але більшість розробників не працюють у цьому середовищі. Вони роблять стільки, скільки можуть у коді. Крім того, деякі на базі даних не втягуються в бізнес-правила. Вони в першу чергу є там, щоб тримати справи. Вони ніколи не наполягатимуть на обмеженнях у db. Якщо мати справу з застарілими програмами, інтеграціями, міграціями, злиттями, придбаннями, обмеження на db може бути найкращим рішенням.
  2. Перевантаження db може створити вузьке місце, яке не легко вирішити, кинувши на цю проблему більше машин. Існують деякі ситуації, коли мова db не справляється з деякими проблемами програмування без серйозного удару щодо продуктивності, тому ви не можете планувати використання обмежень для всього. У Stackoverflow є один сервер баз даних, тому що викид 2 на проблему є проблемою.
  3. Автоматизоване тестування - вони потрапляють туди, але багато розробників db запізнюються на вечірку разом із IDE / тестуючими рамками.
  4. Розгортання - більше db матеріалів ускладнює. Що відбувається, коли оновлення бази даних клієнта заборонено, оскільки є дані, що порушують обмеження? Гра закінчена, якщо у вас немає способу вирішити це питання. У вашому додатку ви можете вирішити дозволити користувачеві обробляти це за потребою або доручити адміністратору це робити пакетно.
  5. Тільки додаток / api / послуга коли-небудь записуватиме дані в базу даних, то чому б це турбувати? Це затримує більшу частину часу, тому це не часто.
  6. Поводження з db-помилками досить важке, без сотень порушень обмежень, з якими можна боротися, якщо все вийде з удару. Більшість із задоволенням налагоджують зв’язок і правильну назву таблиці.

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


2

Це проблема, з якою я боровся протягом усієї своєї кар'єри (майже 40 років), а також під час написання СУБД. Опис моєї кінцевої точки знаходиться тут: http://unibase.zenucom.com . Тож ось мої думки.

  1. Взагалі, більшість обмежень краще керуватись у програмі, так що різні частини програми можуть застосовувати різні обмеження. наприклад, код держави може застосовуватися не у всіх юрисдикціях.
  2. Як осторонь остерігайся%. Націнки> 100% або ви перервались :)
  3. Обмеження найкраще описати негативно. тобто якими вони не можуть бути, а не такими, якими вони повинні бути. Це завжди простіший список.
  4. Іноземні ключі завжди хороші і їх слід використовувати. Повна зупинка. FK - одна з небагатьох семантичних конструкцій в RDBMS і дуже корисна. Найбільша складність полягає у вирішенні питання про те, чи дозволяти значення зависати, якщо FK вилучено, або використовувати залежні рядки як причину не видаляти запис FK.
  5. Обмеження в реальному світі зазвичай складніші, ніж обмеження значення одного поля.
  6. Деякі обмеження, навіть на рівні програми, протидіють хорошим операціям. наприклад, агресивна перевірка дати ховає помилки у, мабуть, хороших датах. Вам потрібна помилка оператора, щоб отримати міру помилок в інакше розумних виглядах дат.

1

Обмеження в базі даних могли бути розумною ідеєю, але як щодо їх практичного використання? Візьміть відсоткове обмеження. Якщо ви застосуєте це, ваша БД із задоволенням відкине недійсні відсотки. І потім? Для обробки винятку вам знадобиться ділова логіка. Що насправді означає, що в діловій логіці написання неправильного відсотка в інших місцях вже не вдалося. Отже, коротко: єдиним практичним обмеженням залишаються ті, кого ви бачите (як PK / FK).


15
Я ввічливо не згоден з цим. Якщо вам дійсно потрібна узгодженість даних, обмеження БД є обов'язковими, особливо якщо ваша бізнес-логіка не працює. Таким чином, ви описуєте сценарій, коли станеться беззвучний збій, коли збиток, заподіяний неправильним відсотковим збоєм, поширюватиметься далі в системі. Якщо у вас є обмеження в БД щодо цього, ви швидко провалитесь, і таким чином даєте розробникам бізнес-логіки можливість побачити помилку на початку та виправити систему бізнес-логіки, замість того, щоб допускати пошкодження даних у ній.
Мачадо

5
Я розумію, що якщо порушення процентного обмеження порушується, вам не доведеться поводитися з цим винятком, оскільки таке порушення вказує на те, що у вашому коді помилка в першу чергу (або хтось використовував просте ціле число замість екземпляра Percentageкласу, або є помилка в самій валідації), на відміну від виняткового випадку (наприклад, відключення мережевого з'єднання). Для мене порушення повинно призвести до HTTP 500 для веб-програми або до збоїв для настільного додатка, а потім його слід ввійти та виправити.
Арсеній Муренко

7
@ThomasKilian: nope; саме навпаки. Неправильні дані не потраплять, зокрема, тому, що існують обмеження в базі даних. Якщо ваша бізнес-логіка в коді правильна, ви ніколи не будете порушувати ці обмеження. Якщо в коді сталася помилка, ці обмеження попереджають вас про цю помилку, зберігаючи базу даних від брухту.
Арсеній Муренко

9
@ThomasKilian: Я не думаю, що хтось сперечається проти "правильного в першу чергу" - це, мабуть, більше того, хто має трохи досвіду, знає, що це погана ідея спроектувати систему за умови, що ви будете отримати все правильно в перший раз , і ніяких помилок або помилки будуть завжди відбуватися в протягом усього терміну служби системи. Обмеження БД гарантують, що помилка чи помилка не пошкоджують базу даних.
ЖакB

3
@JacquesB Я борюся проти вітряних млинів. Якщо ви розміщуєте бізнес-логіку в БД, вона може також вийти з ладу, як і в першу чергу, і не врятувати вас так само. Але (!) Тепер у вас ділова логіка там, де вона не належить. Вважати, що БД може зберегти вашу гнилу ділову логіку - просто неправильно. Логіка в БД повинна відповідати тим же правилам, що і вся логіка бізнесу.
qwerty_so

1

Частіше в ці дні люди використовують програмне забезпечення (наприклад, Entity Framework) для автоматичного генерування таблиць і стовпців. Ідея полягає в тому, що їм не потрібні навички SQL, звільняючи ємність мозку.

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

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


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