Чому обмеження застосовуються в базі даних, а не до коду?

Чому обмеження застосовується до бази даних? Чи не буде він більш гнучким, щоб бути в коді?

Я читаю книгу початківців про впровадження баз даних, тому це питання для початківців!

Скажімо, я розробляю модель бази даних, яка має модель цієї особи:

Person, Has subtypes: Employee, Student
Student's subtypes: Graduate, Undergraduate
Employee's subtypes: Teacher, Administrator

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

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

Чому ми піклуємось про правила бізнесу в структурі бази , а не в коді?

18
В основному ми піклуємось про дотримання ділових правил і найкращих для цього способів.
додано Автор Guy, джерело
Ви ніколи не повинні базувати дизайн бази даних на об'єктах у вашій програмі. Ви могли б нормально спроектувати це як особу, а потім мати відповідну таблицю, щоб визначити ролі осіб. Потім проблема не виникає, тому що у вас є реальна таблиця для ролей, так що люди можуть мати кілька ролей. Якщо ви хочете мати лише одну особу ролі, тоді ви стримуєте таблицю, щоб люди peopleID були унікальними. Якщо ви хочете змінити це, зніміть обмеження.
додано Автор David Mcsween, джерело
Ви насправді представляєте дуже поганий приклад того, які обмеження використовуються, оскільки гнучкість ваших об'єктів та розширення можливостей бази даних в основному визначаються шляхом нормалізації. Сказавши це, обмеження - остаточна запобіжна загроза від будь-яких пошкоджених даних, які коли-небудь потрапляють в базу даних, навіть якщо додаток прослуховується, навіть якщо розроблена нова програма, навіть якщо додається зовнішній API, навіть якщо хтось безпосередньо редагує БД. Обмеження захищають базу даних, на додаток до того, що бізнес-логіка також повинна робити власні речі, перш ніж намагатись отримати доступ до БД.
додано Автор Mark Booth, джерело
Фактично, будучи аспірантом, я вважаю студентом, співробітником і вчителем. Так що ваш приклад не є неймовірним.
додано Автор Andrew, джерело
Об'єкт <-> Реляційне відображення - це мистецтво.
додано Автор Thorbjørn Ravn Andersen, джерело

12 Відповіді

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

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

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

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

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

32
додано
+1 часом найкращі відповіді - це ті, у кого більше питань.
додано Автор Kit Roed, джерело
Я зрівняв це. Немає часу, коли обмеження найкраще застосовується лише в програмі . Тон цієї відповіді невірно оцінюється.
додано Автор Dave, джерело
@RustedWithFormsDesigner, звичайно, це дійсно дитяча плакат для зовнішнього обмеження ключа. Припустимо, у вас є три клієнти різних версій/баз даних точки доступу db, що ви збираєтеся зробити, коли ви перестанете перевозити цей продукт червоним? Де ви збираєтеся зберігати список можливих колірних комбінацій? Підказка: для мене є централізоване місце. І якщо ви створите таблицю color_products і color , ви, ймовірно, зможете створити додаткові падіння з більш легкістю - більшість IDE/schema loaders, підтримка наступних феки
додано Автор Dave, джерело
... Я думаю, якщо це так, то я міг би погодитися. Це, ймовірно, буде залежати від програми та від того, наскільки складними можуть стати правила. Якщо це було ситуацією з кількома клієнтськими додатками різних версій, то так, різні правила в різних версіях клієнта можуть безумовно бути мотиватором для переміщення правил у базу даних. Ймовірно, я думав, що в контексті веб-додатки існує лише один екземпляр програми, що розмовляє з однією базою даних. Хоча ви піднімаєте хорошу точку. :)
додано Автор BM-, джерело
@EvanCarroll: повторно прочитайте моє приклад уважно ... Я зробив насправді згадувати таблицю colors , яка міститиме список кольорів. Обмеження, яке я міг сказати, може виходити з-за меж бази даних, було певним типом продукту, яке дозволялось пов'язати лише з певним кольором. Інші продукти можуть мати посилання на інші продукти, рішення про те, що дозволено, це те, що я сказав, що має бути в заявці. Я думаю, що ви віддаєте перевагу правилам того, які продукти можуть мати які кольори також повинні бути в базі даних, так що вживати двигун правил в базі даних теж?
додано Автор BM-, джерело
@loolooyyyy: Так, я думаю, що це правильно. Якщо в базі даних застосовується перше правило (що людина може тільки бути студентом чи працівником), то ситуація, яку ви описали (в якій співробітник хоче зареєструватися для класу), неможливий, оскільки: особа не може бути обидва, і навіть неможливо створити другий запис "особа", оскільки не може поділитися номерами соціального страхування, які, імовірно, видаються від третьої сторони (наприклад, уряду). Звичайно, ця надмірно обмежувальна модель даних може працювати в деяких випадках ...
додано Автор BM-, джерело
@loolooyyyy: Ще один спосіб використати оригінальну модель даних і все ж таки дозволити вчителям бути студентами може мати інший стіл під назвою teachers_as_students , який є іншим підтипом Students і має новий іноземний ключ, що стосується Teachers , а також первинний ключ системи, створений системою замість номера соціального страхування. Таким чином, "студент" насправді є псевдонімом для вчителя, тому вчитель може все ще зареєструватися, щоб взяти клас. Важко сказати напевно, наскільки добре це буде працювати, не бачачи всієї моделі даних.
додано Автор BM-, джерело
@EvanCarroll: Отже, ви вважаєте, що обмеження прикладу кольорів продукту слід застосовувати на рівні бази даних? Чому?
додано Автор BM-, джерело
Отже, згідно з цією відповіддю, правило обмеження. Я правий? (Це був приклад книги). Дякую.
додано Автор Tohir, джерело

Оскільки:

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

Просто деякі причини, які мені важливі.

29
додано
Пов'язані з (1) і (3): помилки в коді програми можуть бути виправлені, помилки у ваших даних часто непоправні.
додано Автор Jon White, джерело

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

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

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

This is not unknown to application language designers, by the way. Read section 3.10 uniqueness in the Ruby on Rails Guides: Active Record Validations and Callbacks

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

15
додано

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

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

14
додано

Переваги обмежень, що застосовуються базою даних:

Simplicity - Declaring a constraint is significantly simpler than declaring a constraint and writing the code that will enforce that declaration.

Accuracy - Code you didn't write will never have a bug that you created. Database vendors spend time making sure their constraint code is accurate, so you don't have to.

Speed - Your application can never have more distributions than the database it is based on. Database vendors spend time making sure their constraint code is efficient, so you don't have to. The database itself also has faster access to the data than an application could ever have no matter how efficient.

Re-use - You may start with one application on one platform, but it may not stay that way. What if you need to access the data from a different OS, different hardware, or from a voice interface? By having constraints in the database this code never has to be re-written for the new platform and never has to be debugged for accuracy or profiled for speed.

Completeness - Applications enforce constraints when data is entered into the database and would require additional effort to verify older data is accurate or to manipulate data already in the database.

Longevity - Your database platform will likely outlive any particular application.

13
додано

Деякі чудові відповіді тут, і з ризиком повторення інших думок:

  • SSN не обов'язково унікальний. Чорт, SSN не завжди відома, і в деяких випадках вона не існує (поки що). SSN можуть бути використані повторно, і не всі співробітники або студенти можуть мати SSN. Це периферійне питання, але демонструє, що незалежно від того, де ти застосовуєш свої обмеження, потрібно дуже добре зрозуміти модель даних та домен, щоб прийняти рішення щодо ділових правил.
  • Особисто я віддаю перевагу, щоб обмеження були максимально наближені до даних. Сама проста причина полягає в тому, що не всі використовуватимуть код програми для зміни даних у базі даних. Якщо ви застосовуєте свої правила бізнесу на рівні програми, і я запускаю виписку UPDATE безпосередньо проти бази даних, як ваша програма запобігає недійсній зміні? Інша проблема з правилами ведення бізнесу в додатку полягає в тому, що перекомпіляція/перерозподіл може бути складно, особливо для розподілених додатків, де можливо, що не всі отримують оновлення одночасно. І, нарешті, зміна ділових правил у додатку абсолютно не стосується даних, які вже існують, які порушують нові правила, - якщо ви додаєте нові обмеження до даних, ви повинні виправити дані.
  • Можливо, ви зможете виправдати декілька надмірних перевірок на різних рівнях. Все це залежить від гнучкості методологій розгортання, наскільки ймовірна зміна, і наскільки важко синхронізувати зміну бізнес-правил в базі даних та інших шарах. Переконливий аргумент для повторення перевірок на рівні додатків полягає в тому, що ви потенційно можете запобігти переадресації в базу даних лише для того, щоб зникнути там обмеження (залежно від характеру обмеження та того, чи він спирається на існуючі дані). Але якщо мені доведеться вибирати той чи інший, я б поставив його в базу даних за наведеними вище причинами.

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

8
додано

Чому обмеження застосовуються на сервері? Тому що ви не можете змусити поганих хлопців використовувати свій клієнт.

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

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

8
додано
  1. База даних може перевіряти обмеження ефективно. Краще, ніж код.

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

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

6
додано

Коротка відповідь ... для збереження цілісності даних (тобто точності та дійсності).

An exception...
If the database is just storing a single-application's data for a single-user, such as in most Sqlite databases, it may not need constraints. In fact, they usually don't, so as to keep the access time so quick it's unmeasurable.

For everything else...
Databases always serve two masters which I'll call editors and users.

Editors mostly put data into the database and retrieve data one or a small number of records at a time. Their primary concerns are fast, accurate access to all the related pieces of data and fast, reliable storage of their changes.

Users mostly retrieve data and are most concerned with fast access to unquestionably accurate information. They often need various counts, aggregations and listings that used to be generated in those iconic foot-thick stacks of greenbar-paper printouts but usually wind up on web pages today.

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

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

Проте, як ми робимо вигляд, що ми можемо прогнозувати майбутнє, ми не можемо.

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

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

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

6
додано
Відмінна думка про розробку розробників додатків для редакторів, а не користувачів даних.
додано Автор David Mcsween, джерело
дуже хороше пояснення спасибі
додано Автор Tohir, джерело

На додаток до інших коментарів ...

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

4
додано

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

Також тригери, найімовірніше, не портативні, оскільки вони, як правило, написані на специфічних мовами постачальника, наприклад PL/SQL.

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

3
додано
Також тригери не гарантують цілісності, тому що виникають проблеми з консистенцією.
додано Автор lukejanicke, джерело

Вони завжди повинні бути застосовані в базі даних вперше , оскільки,

  1. База даних забезпечує цілісність різних клієнтів. Ви можете мати різні клієнти на різних платформах доступ до бази даних. Обмеження в базі даних не створюють ризику цілісності під час створення нового клієнта. Це заощаджує вас від того, що вам потрібно обмежити кількість запитів у разі перезапису або додаткової точки доступу.
  2. У базі даних є DSL для обмеження будівництва: SQL DDL!
  3. База даних забезпечує доступ до цих обмежень у системних каталогах, тому правильний ORM або "schema loader" можуть прочитати ці обмеження та внести їх у вашу програму. Наприклад, якщо ваша база даних вказує на те, що у вас є тип varchar (5) , ви можете знайти схему завантаження ORM для вашої конкретної мови, яка відображає тип мови до типу схеми і збирає це власне обмеження на розмір. DBIx для Perl є одним із таких схем завантажувача ; Ось ще один для Entity Framework . Можливості цих завантажувачів можуть відрізнятися, але все, що вони можуть забезпечити, є гарним початком забезпечення цілісності додатку без поїздки до бази даних.
0
додано
IT KPI - Databases
IT KPI - Databases
162 учасників