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


10

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

Платформа, що розглядається, - MySQL 5.x, і не встановлено зовнішній ключ, навіть відсутні деякі обмеження PRIMARY KEY у відповідних таблицях, що, принаймні для мене, не є розумним. Можливо, вони праві, і я помиляюся, але мені не вистачає аргументів, щоб обговорити цю ситуацію.

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

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

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

Зазвичай обробка операцій “CRUD” реалізується на рівні коду прикладної програми; наприклад, для того , щоб видалити деякі дані з, скажімо, TableA:

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

Питання

Чи можете ви допомогти мені розробити добру, точну та ґрунтовну відповідь, щоб збагатити дискусію?


Примітка . Можливо, щось подібне вже запитували (і відповіли), але я нічого не міг знайти за допомогою Google.


Коментарі не для розширеного обговорення; ця розмова була переміщена до чату .
Пол Білий 9

Відповіді:


12

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

  • Ні, не слід випускати з уваги обмеження цілісності даних .

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

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

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

ЗАБЕЗПЕЧЕННЯ КЛЮЧОВІ обмеження, зв'язки даних та цілісність референції

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

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

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

Однак, як відомо, це не оптимальна методика захисту референтної цілісності , тому що реляційна наука прописала для цього дуже потужний інструмент, тобто обмеження ЗОВНІШНЯ КЛЮЧ (FK). Ці обмеження дуже легко створити (за допомогою вищого декларативного підходу), оскільки вони є одиничними реченнями, які уникають використання непотрібних спеціальних процедур та схильності до помилок. Дуже корисно зазначити, що швидкість виконання обмежень FK була оптимізована спеціалізованими програмістами (а основні виробники платформ над цим працювали вже десятиліття).

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

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

ОСНОВНІ КЛЮЧОВІ обмеження та наслідки повторюваних рядків

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

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

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

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

Таким чином:

  • Яку "версію" можна вважати правильною, надійною?
  • Який із них точно відображає реальний світ?

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

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

Ось чому ідентифікація ПЕРШОГО КЛЮЧА (ПК) та декларація відповідного обмеження завжди повинні виконуватись дизайнером бази даних. Але також слід зазначити, що таблиця може мати більше одного стовпця або комбінації стовпців, що містять значення, що однозначно ідентифікують кожен рядок; як наслідок, окрім встановлення обмеження PK (в ідеалі встановленого як ПЕРШИЧНИЙ з прагматичних причин), дизайнер повинен також оголосити один або кілька КЛЮЧІВ АЛЬТЕРНАТИ (як правило, визначені одним або декількома УНІКАЛЬНИМИ, а не обмеженнями NULL), коли застосовується (що є досить поширений).

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

(Поточні) ПЕРЕВІРИТИ обмеження та однорядну перевірку

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

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

У зв'язку з цим вам доведеться подбати про цей фактор іншими способами, наприклад, КРИСТОЮ КИСЛОТИ , ТРІГЕРЖЕРАМИ або іншими методами в межах самої СУБД (див. Цю відповідь від @ ypercubeᵀᴹ для інформації з цього приводу), щоб дані продовжували бути послідовним.

Обмеження АСЕРГІЇ: декларативно налаштовувати подальші бізнес-правила для кількох рядків та кількох таблиць

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

Зі свого боку, стандарт SQL включає ВКАЗАННЯ вже багато років. Я не знаю, які правила вашого бізнес-середовища отримали б користь від цього підходу до перевірки логічного рівня, але, як розробник бази даних, я вважаю, що було б дуже зручно обмежувати дані одним або кількома ЗАБЕЗПЕЧЕННЯми, хоча я мушу згадати це з З точки зору розробників СУБД, цей першочерговий вид інструменту було важко реалізувати на фізичному рівні абстракції.

Виявляється, що постачальник Oracle та / або розробники оцінюють підтримку ASSERTION з 2016 року, і це зробить цю СУБД більш реляційною, а отже, більш надійною та конкурентоспроможною. Я здогадуюсь, що якщо (i) їхні споживачі продовжують наполягати і (ii) Oracle досягає успіху у впровадженні, то (iii) інші постачальники / спільноти СУБД повинні також їх дозволити, і їх використання почне поширюватися. Безумовно, це був би величезний прогрес у галузі управління базами даних, і будучи одним із найрізноманітніших інструментів, передбачених доктором Коддом, я особисто сподіваюся, що ми побачимо це, що відбудеться незабаром.

Узгодженість даних та процес прийняття рішень

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

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

Загальновідомо, що люди використовують інформацію як основний інструмент в організаційному (і в звичайному) процесі прийняття рішень. Тоді, якщо інформація, представлена ​​БД, не є цілісною та точною, рішення, засновані на такій інформації, не будуть надійними (якщо не сказати). Ось чому RDB повинен бути ретельно розроблений та впроваджений: він повинен бути побудований, щоб стати надійним ресурсом, який може допомогти своїм користувачам приймати обґрунтовані рішення.

"Денормалізація"

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

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

Отже, якщо припустити, що згадана таблиця фактично була нормалізована правильно, «денормалізуючи» її (що, на відміну від формального значення цього слова, передбачає додавання до неї стовпців, що належать до, а також є частиною інших таблиць у рекламі hoc fashion) може допомогти, наприклад, прискорити (на фізичному рівні) обробку лише одного або кількох конкретних операторів SELECT, в той час як такий спосіб дії може одночасно підірвати виконання багатьох інших пов'язаних даних операції з маніпуляції (наприклад, кілька операторів INSERT, UPDATE, DELETE та SELECT, або їх комбінації, укладені в межах однієї або декількох АСИДНИХ ПЕРЕХОДІВ).

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

Ліси фізичного рівня, що підтримують нормалізовані та «денормалізовані» таблиці

Логічний (абстрактний) макет (SQL-DDL-дизайн), який повинен бути використаний у реальному світі, чітко містить фізичні (конкретні) наслідки, які необхідно враховувати.

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

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

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

Функціонування розглянутої бази даних

Наступні пункти вашого питання стосуються швидкості операцій із пошуку даних:

[A] s продукт "працює", виникає вагання щодо розширення бази даних; тим не менше, перше, що я помітив, - це одна сторінка, на яку завантажується 1 хвилина (так, 60 секунд!).

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

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

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

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

  • Налаштування INDEX можуть потребувати вдосконалення.
  • Визначення типу та розміру стовпців PK та FK потрібно переглянути (і я повністю погоджуюся з @ Rick James щодо його міркувань щодо ПК , оскільки складові ключі, як правило, набагато ефективніші, ніж додані сурогати у відповідних випадках).
  • Подальша (формальна, заснована на науці) нормалізація може допомогти полегшити ці проблеми, враховуючи той факт, що при правильних обставинах (тобто, здійснених у добре спроектованій RDB), JOIN виконується дуже швидко .

Більше того, так, як згадує @TommCatt у своїй відповіді , іноді (логічне) перезапис запиту змінює його (фізичний) план виконання, прискорюючи читання / запис даних, що є фактором, який слід рішуче враховувати.


1
Чудова відповідь. Я завжди нагадую себе, коли розглядаю ефективність виконання, що команда розробників набагато розумніша, ніж я над цими проблемами працюю дуже давно. Реляційні бази даних лежать в основі наймасштабніших систем у світі (Facebook та Twitter, щоб назвати кілька очевидних).
Нік Бедфорд

9

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

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

Ні в якому разі не видаляйте FK з бази даних OLTP.

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

Це дуже рідко, коли проста настройка не може отримати набагато більше підвищення швидкості, ніж денормалізація. Тут хороший DBA може (нарешті) заробити свою зарплату. Ви також можете налаштувати свої запити. Одного разу я взяв запит, який відповів не менше ніж за 30 хвилин, і він працював менше 8 секунд. Жодних змін у базі даних немає, просто переписав запит. Зрозуміло, це моя найкраща репутація, тому ваш пробіг може відрізнятися, але денормалізація повинна бути останньою справою.

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

select <something> from <SomeView> where <whatever>;

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

Мені дуже притаманне, коли хтось каже, "оскільки продукт" працює ", є вагання щодо покращення бази даних". Якщо це "вагання" більше схоже на "не на мій годинник, товариш!" то, можливо, ви навіть захочете оновити своє резюме. Нічого хорошого ніколи не виходить із такого середовища, і ви будете винні у кожному майбутньому невдачі, хоча ви, можливо, годинами лобіювали внести зміни, які завадили б невдачі. Ви почуєте: "Зараз не час вносити зміни" знову і знову. Правильно. Удачі.


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

2

Зміна назви змінює питання. FOREIGN KEYsнеобов’язкові. Вони роблять:

  • ФК неявно створюють INDEXв одній із таблиць. Такий індекс можна додати вручну. (Тому ФК для цього не потрібно .)
  • FK перевіряє цілісність. Це головна претензія ФК на славу. ФК не потрібно, оскільки ваша програма може робити подібні перевірки або вирішити, що перевірка не потрібна. Тому...
  • Перевірка цілісності коштує чогось у виконанні; тому він уповільнює обробку. (Зазвичай це не велика справа.)
  • ФК не роблять все, що хоче кожен; Цей форум завалений питаннями "чому ФК не може робити X". Зокрема, не застосовується CHECKваріант.
  • FK можуть CASCADEречі. (Особисто я вважаю за краще залишатися під контролем, а не вважати, що ФК «зробить правильно».)

Підсумок для ФК: Деякі люди наполягають на ФК; деякі продукти прекрасно живуть без них. Тобі вирішувати.

Позбутися PRIMARY KEYInnoDB - велика помилка. З іншого боку, позбавлення від сурогату AUTO_INCREMENTта використання "природного" ПК, складеного з одного (або більше) стовпців, часто є правильним . Простий, поширений випадок - безліч: багато таблиць з відображенням, про які йдеться тут .

Виходячи з особистого досвіду, я пропоную, що капелюшки 2/3 таблиць краще використовувати "натуральні" замість auto_inc PK.


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

Видалення занадто багато може трапитися в додатку або з FK. Видалення занадто мало зазвичай стає очевидним. ОТО, я бачив випадки, коли видалення занадто мало коштує витрат - подумайте про "нормалізацію", коли речі рідко видаляються. Додаткові, невикористані, ряди практично нешкідливі.
Рік Джеймс

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

1
Зауважте загальну тему в моїх міркуваннях: Єдиної відповіді немає; ні один розмір не підходить для всіх.
Рік Джеймс

Якщо у вас таблиці - це тисяча рядків; продуктивність не є проблемою. Якщо ваші таблиці мають мільярд рядків, всі "правила" щодо нормалізації, ПК, індексів, FK, UUID тощо повинні бути перевірені. Інакше db розтане.
Рік Джеймс
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.