Чи викликає зло базу даних? [зачинено]


186

Чи спрацьовує база даних погана ідея?

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

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

Єдиний раз, коли ми використовуємо тригери, це дійсно прості речі, такі як встановлення ModifiedDate.


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

2
Питання закрито для додавання відповідей, але див. Також Чи безпечні тригери баз даних для обмежень цілісності крос-таблиці? . (Спойлер: ні, їх немає)
Mifeet

16
Цей сайт мене так злить. Це ВЕЛИКИЙ питання, як і багато інших, його закрито, оскільки людям не вистачає уяви, щоб прийняти запитання, які не вписуються в примітивний бінарний формат запитань і запитань, вони з чужої причини відчувають вимушеність слідувати.
Дивовижна

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

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

Відповіді:


147

Основні проблеми з тригерами

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

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


20
Це 2 переваги, в деяких випадках.
Джонно Нолан

18
"Скрадний" - це чудове слово, так - добре сказано. Саме тому я схиляюся від них ухилятися: занадто часто їх забувають або ігнорують. З мого особистого досвіду, перегляд тригерів часто супроводжується присмаком до мого власного чола.
Крістіан Нунсіато

5
Глобальні, тому вони хороші та необхідні для цілісності даних та таких речей, як аудит. Це не мінус, це плюс.
HLGEM

4
так що @ RobertŠevčík-Robajz, ви говорите, що всі розробники, яких ви знаєте, некомпетентні?
HLGEM

3
@HGLEM, погодьтесь, повинен бути фахівець, який розробить тригери. Справжній сценарій життя - немає. Реальний сценарій життя - дні, проведені в спробі виявити помилку, пов'язану із забутим тригером. Справжній сценарій життя - логіка тригера відчайдушно висувається в логіку програми, де її можна легко відновити і перевірити на одиниці. Це справжнє життя, з яким я маю справу, змушує мене сказати "триматися подалі від пускових механізмів" ... це не вина тригерів, оскільки це не вина каменів, що вікна розбиваються.
Rbjz

80

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

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

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

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


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

10
Не обов’язково, тригер буде, ймовірно, працювати лише тоді, коли рядок буде вставлено або оновлено. Індекс на основі функцій буде працювати для кожного вибору. Залежно від схеми використання одне, ймовірно, краще, ніж інше. Але НІ ВЖЕ не кращий за інших.
jmucchiello

@tuinstoel: Я повинен погодитися з вашим твердженням деякі з часу. Наприклад, Oracle створюватиме індекси на основі функцій лише тоді, коли він зможе довести, що функція є детермінованою. Іноді це просто неможливо довести (наприклад, якщо функція передбачає пошук таблиці, навіть якщо ви знаєте, що дані таблиці ніколи не змінюються).
Адам Пейнтер

50

Інструменти ніколи не є злими. Застосування цих інструментів може бути злим.


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

37
Пістолети @vbullinger не є злими, але їхні тригери є;)
Darragh Enright

2
: D Узагальнення небезпечні (рекурсивно). Чи завітали ви до "інструментів" тортур, які використовували інквізитори, щоб "викликати" визнання? +1 у будь-якому випадку.
Rbjz

22

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

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

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

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

Вони звучать суворо, і я здогадуюсь, що вони є. Але це основна істина, на мій погляд ...


3
>>> Проблеми з тригерами - люди. Так, якби тільки люди могли кодувати в зборах, працювати з хитрим графічним інтерфейсом, правильно здогадуватися, чи штовхати чи тягнути погано розроблені двері ... Будь-яка "особливість" людей неодноразово неправильно - це "зло".
Fakrudeen

1
@Fakrudeen, будь-який розробник, який неправильно спрацьовує, не має права доступу до бази даних.
HLGEM

20

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


Правила, орієнтовані на дані, належать до бази даних
абсин

мав менеsome programmers are too ethnocentric to consider that something other than their prized application may be affecting things
Kid101

13

Переважно так.

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

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

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


12
Це перевага тригера, а не розчарування! Збережені документи не можуть бути гарантовано викликані при кожній зміні даних. Існує багато способів зміни даних, окрім GUI.
HLGEM

2
HLGEM, це залежить від вашого контролю доступу. Ви можете заборонити будь-які зміни в таблицях безпосередньо, за винятком збереженої процедури.
Rbjz

1
Я думаю, що справа в тому, що якщо, наприклад, записи у двох таблицях ЗАВЖДИ створюватись та знищуватись разом, незалежно від того, як ви отримуєте доступ до бази даних, і незалежно від того, хто ви є чи які дозволи у вас є, то тригери - єдине законне рішення . Сам факт, що навіть можна призначити занадто багато або неправильних дозволів і сподіватися, що люди дізнаються, які зберігаються процедури слід використовувати, означає, що база даних загрожує втратою цілісності. Це точно так само, як і зовнішні ключові відносини. Це просто НАЙКРАЩЕ та НАЙБІЛЬШЕ НАДІЙНИЙ примусовий механізм роботи з базами даних.
Трайнко

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

9

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

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

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


7

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

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

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


3
Це правильно, це повинно бути в одному місці, БД. Логіка, яка впливає на цілісність даних, ОБОВ'ЯЗКОВА бути в базі даних і ніколи в додатку, де вона може або не може викликатись при впливі на дані в базі даних.
HLGEM

1
@HLGEM: Це залежить від того, чи може база даних мати доступ до інформації, яка дозволяє їй визначати, чи дані є валідними. Це не завжди так; коли валідатор перебуває в іншій організації (наприклад, щодо даних про кредитну карту або банківський рахунок), тоді БД не може знати, чи правильно це - припустимо, що це не БД банку! - і доведеться покладатися на заяву про примусове виконання. Те, що ви не хочете, - це база даних, яка встановлює випадкові підключення до сторонніх служб, як це погано, коли справа стосується розгортання сервера.
стипендіати доналу

@HLGEM: Хоча я не готовий повністю виключати можливість розміщення всієї логіки програми в базі даних, я вважаю, що вона прагне краще працювати, щоб розмістити її в іншому місці, як правило, багаторазовий OO-шар, який можна використовувати для всіх програм, що мають доступ база даних. Поки ваше додаток має доступ до бази даних лише через об'єктний рівень, ті самі гарантії логіки, яка завжди викликається, все ще застосовуватимуться.
Дейв Шерохман

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

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

6

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

Тепер вони можуть бути "злими", якщо ви опинитесь в "тригерному пеклі" одним пусковим механізмом, що стартує інші тригери. Я колись працював над продуктом COTS, де у них було те, що вони називали "flex trigger". Ці тригери зберігалися в таблиці, оскільки динамічні складові sql збиралися щоразу, коли вони виконувалися. Скомпільовані тригери зробили б перегляд і побачили, чи була в цій таблиці якісь флекс-тригери, а потім скомпілювати та запустити тригер "flex". Теоретично це звучало як дуже класна ідея, оскільки продукт легко був налаштований, але реальність базу даних сильно вибухнула завдяки всім компіляціям, які він мав робити ...

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


6

На високому рівні є два випадки використання для тригерів1

1) Зробити "автоматично" речі. У цьому випадку тригери викликають побічний ефект, вони змінюють дані способами, які не очікувались за умови (примітивної) операторної вставки, оновлення чи видалення, що було виконано, і призвело до запуску тригера.

Загальна думка тут полягає в тому, що тригери дійсно шкідливі. Оскільки вони змінюють добре відому семантику оператора INSERT, UPDATE або DELETE. Зміна семантики цих трьох примітивних SQL-операторів прикусить інших розробників, які в подальшому потребуватимуть роботи над таблицями вашої бази даних, які більше не ведуть себе очікуваним чином при роботі з ними примітивами SQL.

2) Для виконання правил цілісності даних, окрім тих, з якими ми маємо справу з декларативно (використовуючи ПЕРЕВІР, ПЕРВІЙНИЙ КЛЮЧ, УНІКАЛЬНИЙ КЛЮЧ та ІНТЕРНЕТ КЛЮЧ). У цьому випадку використання всі тригери - це дані QUERY (SELECT), щоб перевірити, чи дозволена чи ні зміна, внесена ВСТУП / ОНОВЛЕННЯ / УДАЛЕННЯ. Як і декларативні обмеження для нас. Тільки в цьому випадку ми (розробники) запрограмували правозастосування.

Використання тригерів для останнього випадку використання не є шкідливим.

Я веду щоденник на цьому веб-сайті: http://harmfultriggers.blogspot.com


Використовуючи тригери для референтної цілісності, складніше, ніж виглядає, вирішувати проблеми одночасності.
ВВ.

2
Домовились. Але чи легше при використанні якихось інших засобів?
Toon Koppelaars

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

Є багато некомпетентних розробників, хоча хаха.
хештейн

5

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

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


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

5

Не зла. Вони насправді спрощують такі речі

1. Включення / аудит змін до записів або навіть схем баз даних

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


2.Закріплення референтної сумісності (первинний / зовнішній ключові зв'язки тощо) у кількох базах даних


Ви можете відмовити заяви DDL?
Ендрю Лебедь

Взагалі ні. Єдиний спосіб зупинити це - видалити цей дозвіл з логінів користувачів.
jmucchiello

У деяких двигунах баз даних ви можете (наприклад, PostgreSQL).
Nicolás

@Andrew - У SQL Server ви можете. SQL Server 2005+ також має тригери DDL, які спрацьовують на такі події, як ALTER TABLE.
Мартін Сміт

4

Ні, вони не злі - вони просто неправильно зрозуміли :-D

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

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

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


4

Сказати, що вони злі - це перебільшення, але вони можуть стати причиною сітки. Коли стрілянина одного тригера спричиняє активацію інших тригерів, це стає дуже складним. Скажімо, вони клопітно: http://www.oracle.com/technology/oramag/oracle/08-sep/o58asktom.html

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


4

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

Вони також дуже корисні для аудиту.


4

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

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

Приклад, наведений у BOL під заголовком " Керування захистом тригера ", є користувачем, який створює тригер, що містить код, GRANT CONTROL SERVER TO JohnDoe ;з метою ескалації власних дозволів.


3

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


3

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

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

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

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


1

Дійсно, досить часто тригери зловживаються. Насправді в більшості випадків вони вам навіть не потрібні. Але це не робить їх обов'язково поганими.

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


1

Ідея спускових механізмів не є злом, обмеження гніздування тригерів - зло.

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