Обмеження у реляційних базах даних - чому б їх не видалити повністю?


20

Чи є сьогодні причина для побудови обмежень між таблицями (всередині SQLserver)? Якщо так, коли? Більшість застосувань у моїй області побудовані на об'єктних принципах, а таблиці з'єднуються на вимогу. Попит ґрунтується на потребі програми. Я не завантажую купу обмежених таблиць для простого пошуку, які в свою чергу (після дії) вимагають одна від одної простого пошуку.

Інструменти ORM, такі як EntityContext, Linq2Data, NHibernate, також вирішують обмеження самостійно, принаймні ви знаєте, які таблиці потрібні один одному. Виконання обмежень всередині сервера полягає лише в тому, щоб двічі змінити (примусити)?

Зазвичай це не питання для вирішення, але ця база даних розроблена зовсім по-іншому. Дизайн виглядає регулярно добре, в основному це дзеркальні предмети, які використовуються додатками. Мене турбують всі обмеження, налаштовані всередині SQLserver з "не каскадом". Що означає, що вам потрібно грати "шукати і знаходити" при кодуванні нових запитів до бази даних. Деякі випадки вимагають до 10 рівнів точного порядку, щоб зробити одне видалення.

Це мене дивує, і я не впевнений, як з цим впоратися.

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

Як би ви діяли в цьому сценарії?
Чому б просто не видалити всі обмеження з db і тримати їх на рівні програми?


6
Ви планували завжди отримувати доступ до даних за допомогою одного інструмента ORM? Або ви планували "весело" правильно копіювати всі обмеження в кожному використовуваному інструменті ORM?
Стипендіати доналу

1
За моїм останнім коментарем до Петра я повинен погодитися. Точка покладання всіх обмежень на базу коду (і видалення їх з db) була дуже вузькою і, ймовірно, повністю застосовна для короткочасних додатків. Можливо, також для деяких розробників / проектів RAD.
Незалежна

4
Незначна нітпік: Я думаю, що це стає дещо заплутаним, коли ви називаєте зовнішні ключові зв'язки між таблицями "відносини". "Відносини" у реляційній базі даних - це самі таблиці, а не з'єднання. Особливо, коли ми продовжуємо та говоримо про "реляційний дизайн" - це означає таблиці, чи це означає іноземні ключі?
Томас Падрон-Маккарті

Спасибі. Я називаю "з'єднання між таблицями" для обмежень. Отже, ви, мабуть, вірно, що я бачу "реляційну базу даних" для принципів дизайну таблиць (структури таблиць). Ще більш точним описом буде "модель дизайну", коли стосується бази даних "відношення проти об'єкта".
Незалежний

1
Ваша база даних переживе ваш код програми. Крім того, ваш ORM шкодить продуктивності вашої програми, і є велика ймовірність, що ви нарешті захочете обійти її хоча б у певних випадках використання. Якщо ви цього не знаєте, ви дізнаєтесь з часом. samsaffron.com/archive/2011/03/30/… . Крім того, усунення всіх обмежень залишає вашу базу даних повністю нездатною захистити власну цілісність, коли вона зловживає додатками, окрім ваших, що може бути чим-небудь від іншого фактичного додатка до виконавця в залі за допомогою Excel.
Крейг

Відповіді:


46

Дві загальні причини не видаляти протипоказання з БД :

  • Зараз або в майбутньому доступ до нього може отримати більше додатків , які можуть або не можуть використовувати ORM. Навіть якщо розробники цих додатків сумлінно копіюють усі обмеження, які існують там (що може бути значно складніше, якщо використовувати рішення, що не мають ORM нижчого рівня), це завжди зайва робота. А якщо ні, навіть одного невеликого упущення достатньо, щоб порушити цілісність схеми ... це те, що ви не хочете ризикувати. У більшості компаній дані, що зберігаються в їх БД, є життєвою ланкою їхнього бізнесу, тому її цілісність повинна забезпечуватися будь-якими способами. І перевірений і перевірений найкращий спосіб досягти цього - це втілити якомога більше обмежень у БД.
  • Оптимізатор запитів багато в чому покладається на обмеження, відомі на рівні БД. Якщо ви усунете обмеження, продуктивність запитів може почати погіршуватися . Ви можете не одразу помітити це, але одного дня він вдарить вас, і до того часу це може бути занадто пізно, щоб легко це виправити. Природа полягає в тому, що продуктивність БД має тенденцію до збою в час пікового навантаження, коли є найменша можливість зробити ретельне, продумане вдосконалення дизайну, підкріплене точними вимірюваннями продуктивності та детальним аналізом, щоб визначити першопричини.

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


5
@ Jonas, потім поговоріть з хлопцем про проблеми, які виникають у його дизайні БД. Реляційне та об’єктно-орієнтоване - це два різних світи - жодне з них не є «покращенням» над іншим, і обидва мають своє місце. Проектування програми C # на реляційних принципах є настільки ж великою помилкою, як і проектування БД способом OO.
Péter Török

3
@ Jonas, відображаючи ваші оновлення: якщо вам потрібно написати надмірно складні запити, щоб досягти, здавалося б, простих речей проти схеми DB, це або ознака того, що дизайн БД недостатній за своїм призначенням - або що ви недостатньо кваліфіковані (будь ласка не ображайтесь, з вашої публікації не очевидно, наскільки ви досвід роботи з SQL. Як відмова, я сам далекий від того, щоб бути експертом.)
Péter Török

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

8
"Доступ до нього можуть отримати більше додатків зараз чи в майбутньому." Не кажучи вже про деякого адміністратора баз даних, запускаючи необроблені запити SQL, щоб виправити проблему з базою даних, а користувачі чекають ...
Томас Падрон-Маккарті

5
+1: якщо db зберігає бізнес-дані (а не лише конфігурацію додатків тощо), то ймовірність того, що база даних
вимкнеться

27

Програми можуть надходити та йти, але дані живуть назавжди. У моїй компанії БД більше 30-40 років, вона буде жити, поки існує компанія. Програми змінюються, розробники приходять та йдуть. Краще мати цілісність і гарну логічну модель даних. Таким чином, хтось може переглядати дані та отримувати змістовне розуміння, не проходячи складну базу коду. Це також допомагає значно звітувати. Також програми можуть і матимуть помилки, а обмеження БД є захистом від цього. Моя позиція за замовчуванням - мати якомога більше обмежень (FK та чек).
Єдиною причиною не мати обмежень буде те, якщо модель дизайну цього не дозволяє, наприклад, проблеми « Таблиця за ієрархією» або продуктивністю.


Я скажу, ви робите тут дуже мудру пораду. Моя думка може краще відповідати розробці RAD або будь-якій іншій розробці, де додатки мають короткий термін служби - Просто заради мінімізованого обслуговування при розробці.
Незалежний

15

Мене турбують всі обмеження, налаштовані всередині SQLserver з "не каскадом".

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

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

База даних, як правило, діє у багатьох програмах = один або кілька веб-сайтів або додатків для настільних ПК, додаток для звітування, веб-служби, вікно запитів, процеси ETL тощо. Якщо ви не застосовуєте протипоказань на рівні бази даних, ви спочатку втрачаєте цілісність даних, оскільки одна з цих програм може не дотримуватися всіх правил. По-друге, вам доведеться кілька разів кодувати ці протипоказання і переписувати їх, якщо ви вирішите використовувати інший додаток пізніше. По-третє, ви не можете заздалегідь контролювати, чи буде потрібно виконувати якесь завдання з обслуговування даних, яке не відбудеться через додаток (виправлення даних за умови неправильного імпорту даних клієнта, наприклад, або зміна всіх 1000000000 записів від одного клієнта іншому клієнту, коли компанія купується конкурентом). Зазвичай розробники програм не '


Дякую за відповідь. Усі процеси та типи застосувань, про які ви говорите, повинні спілкуватися з DAL (що, в свою чергу, міститиме обмеження). АЛЕ! Ваша думка ідеальна, і ваш коментар хороший. Сторінка: Так. Я прагну спробувати способи полегшити розвиток. Для мене менша складність може стояти менше способів зробити неправильно. Це не "хочу, щоб розробку було легше / швидше", навіть якщо це могло бути - якщо це обробляється неправильно. Тому я ставлю це питання! Я б також бачив у когось хорошого сенсу, якби цей каскад був обраний з розумом, а не на 100%, як у цьому сценарії. Я маю з’ясувати причини.
Незалежна

@ Jonas, також можуть бути причини роботи. Залежить від кількості записів дітей. Гаразд, якщо ви видаляєте невеликі групи, але якщо мільйони записів можуть спрацьовувати, вам краще робити партії, а не зачиняти всі таблиці, поки відбувається весь процес. Як правило, багато dbas не дозволяють каскадно видаляти лише з цієї причини, оскільки це може заблокувати систему prod, якщо видалення впливає на занадто багато записів.
HLGEM

2
Жоден з усіх процесів не повинен спілкуватися з DAL. Процеси ETL зазвичай ні, ні речі, які мають відбуватися на рівні бази даних, що впливають на багато записів, коли відбуваються великі зміни (наприклад, клієнт викуповується). Ви також не можете заборонити нікому використовувати вікно запиту для одноразової зміни. Я ніколи не бачив базу даних, яка б не застосовувала обмежень на рівні бази даних, які не мали проблем із цілісністю з часом.
HLGEM

10

Я десь десь прочитав, де в основному сказано: Дані - це ключ вашої програми . Якщо ви отримаєте доступ до даних лише через ваш інтерфейс користувача (а я маю на увазі коли-небудь , як зараз, так і назавжди, на всю вічність ... або весь час вашої програми, все одно), вам не потрібно обмежувати бази даних. Але є ймовірність, що щось, крім самого додатка, потрібно буде торкнутися даних, наприклад веб-сервіс, публічний API, завдання граблі / SQL завдання / cron / автоматизований сценарій, тоді ви заощадите собі багато потенційних проблем дорога, дотримуючись обмежень БД.

Я твердо переконаний, що це єдина сфера розробки програмного забезпечення, де ви не повинні застосовувати DRY (і я повністю сподіваюсь на те, що за цим твердженням є суттєвий аналіз). Ваші дані є серцем і душею вашої програми - якщо вона коли-небудь пошкоджена після ремонту, то це: гра закінчена. Варто ІМО виконувати обмеження, де вони потрібні. Якщо це означає у вигляді тригерів та обмежень на рівні БД, перевірки на сервері проміжного програмного забезпечення та JavaScript на стороні клієнта в інтерфейсі користувача (для веб-додатків), то IMO є необхідним злом для того, щоб дані завжди були незайманими .


6

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

Якщо ви вважаєте реляційну концепцію дратівливою, то чому ви не використовуєте об'єктну базу даних? Деякий час тому вони були повільними (саме тому більшість людей все ще використовують RDBMS), але від того, що я чув, речі дещо змінилися. Ви позбулися б усіх реляційних нітпіків. Просто об'єкти в, об'єкти з.


Тема полягає в тому, щоб вимкнути функціональні можливості обмеження з БД і покластися на налаштування / розвиток в кодовій базі (наприклад, .net кажучи: Entity / Linq2Sql).
Незалежна

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

Перенесли! Не впав. Я розумію, ти шкодуєш про знання кюрінгу, про яке не йшлося.
Незалежний

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

Спасибі! "Переміщення" означає літературний "рух". Що означає, що ви створюєте (добре виражене) обмеження програм у кожній системі. Принаймні кожна система, яка не може ділитися тим самим DAL. Дуже приємним прикладом були прямі запити адміністратора db, які "щось виправляють". Відсутність обмежень на довкілля та відсутність знань щодо дизайну не можуть призвести до осиротілих даних або загартування, повністю знущаються над даними.
Незалежне

6

Це саме те, що зробив eBay, і вони, мабуть, мають одну з найбільших баз даних у світі:

http://www.dba-oracle.com/oracle_news/news_ebay_massive_oracle.htm http://www.addsimplicity.com/downloads/eBaySDForum2006-11-29.pdf

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

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

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


Нарешті хтось, хто мене розуміє :-). Ви абсолютно праві, баланс - це дійсно важливий момент. Переміщення обмежень до рівня програми може бути безпечною альтернативою, якщо це робиться як стратегічний момент. Було б непогано, що з деякими URL-адресами на сайтах доведено погіршення продуктивності через сильні обмеження / цілісність.
Незалежна

10
Так і не забувайте - не забувайте - що Ebay, як і Facebook та Amazon, - у мільйон разів більше, ніж 99,99% баз даних, і те, що для них добре, ймовірно, сильно відрізняється від того, що добре для вашої бази даних.
Тоні Ендрюс

2
І на ebay, Facebook, Amazon, ймовірно, не використовуються бази даних без обмежень для свого фінансового та бухгалтерського програмного забезпечення або свого інвентарного програмного забезпечення або своїх HR-даних або в будь-якому місці, де не втрачаються дані є критично важливим.
HLGEM

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

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

4

По-перше, моя відповідь: Ні, ви не повинні покладатися на програму лише для догляду за вашими даними.

Це вказує на більш широку дискусію: ORM заохочують культуру зневаги до "прямої" взаємодії з БД, часто за рахунок нормалізації / референтної цілісності. Таблиці насильно відображаються у довільній ієрархії об'єктів за рахунок конструкції, що міститься в реляційній моделі. Розв’язання, яке надає перевагу OOP, тут, безсумнівно, жертвується, оскільки додаток дає відчути дизайн у структурі даних. Незважаючи на те, що ORM продемонстрував велику корисність, вона, мабуть, базується на зловживанні або недовірі до SQL.

Нові парадигми (повторно) з'являються, наприклад, функціональне програмування. Якщо команда розробників вирішить застосувати нову методологію програмування, то які наслідки це матиме для даних, структурованих відповідно до вимог ORM?

Я погоджуюся з @Jacek Prucia - я думаю, що ORM - це погана відповідність для RDBMS, я особисто вибираю DBAL на RDBMS або йду на OODB з ORM.


+1 для розмови за альтернативами теми. Інша сторона дебатів - це, звичайно: "Наскільки поганими будуть деякі дані?" і відповідь може бути скасуванням або внесенням мільярдів грошей на кілька мільйонів мільйонів доларових банківських рахунків. А також деякі осиротілі дані, які видаляються за допомогою хорошої процедури очищення. Короткий зміст цієї теми виглядає як узгодженість із витратами на гнучкість. Що в свою чергу повністю залежить від суворості вмісту та використання db.
Незалежний

3

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

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

Розвиваючи, нехай це буде просто. Обмеження дозволяють вам це робити. (Отож, коли обмеження видає помилку, не випромінюйте назад таку саму помилку у користувача. Зробіть помилку зрозумілою.)

(Що стосується питання каскаду: це добре. Я вважаю за краще помилитися з тим, що деякі інші записи спочатку потрібно видалити, а не покладатися на каскад, щоб все вийшло правильно. Каскади теоретично приємні, але не обов'язково так на практиці.)


2

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

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

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

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

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

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


1
Дякую за відповідь. Обмеження будуть в db для цього проекту! Я повністю переконаний :). Я також матиму ширші очі, коли вирішуватиму це щодо майбутніх проектів та в дискусіях з іншими частинами.
Незалежний

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