Існує кілька причин, чому використання однієї великої «таблиці богів» є поганою. Спробую проілюструвати проблеми зі складеною прикладом бази даних. Припустимо, ви намагаєтеся моделювати спортивні змагання. Ми скажемо, що ви хочете моделювати ігри та команди, які грають у ці ігри. Дизайн з декількома таблицями може виглядати приблизно так (це за призначенням дуже спрощено, тому не зациклюйтеся на місцях, де можна застосувати більше нормування):
Teams
Id | Name | HomeCity
Games
Id | StartsAt | HomeTeamId | AwayTeamId | Location
і одна база даних таблиць виглядала б так
TeamsAndGames
Id | TeamName | TeamHomeCity | GameStartsAt | GameHomeTeamId | GameAwayTeamId | Location
Спочатку давайте подивимось на складання індексів на цих таблицях. Якщо мені потрібен був індекс про домашнє місто для команди, я міг би легко додати його до Teams
таблиці чи TeamsAndGames
таблиці. Пам’ятайте, що кожного разу, коли ви створюєте індекс, його потрібно десь зберігати на диску та оновлювати у вигляді рядків, доданих до таблиці. Що стосується Teams
таблиці, це досить просто. Я вкладаю нову команду, база даних оновлює індекс. Але про що TeamsAndGames
? Ну, те ж саме стосується іTeams
приклад. Я додаю команду, індекс оновлюється. Але це буває і тоді, коли я додаю гру! Незважаючи на те, що це поле буде недійсним для гри, індекс все одно повинен бути оновлений і збережений на диску для цієї гри. Для одного індексу це не дуже погано звучить. Але коли вам потрібно багато індексів для кількох сутностей, забитих у цій таблиці, ви витрачаєте багато місця для зберігання індексів і багато процесорного часу, оновлюючи їх для речей, де вони не застосовуються.
По-друге, узгодженість даних. У разі використання двох окремих таблиць я можу використовувати зовнішні ключі від Games
таблиці до Teams
таблиці, щоб визначити, які команди грають у гру. І якщо припустити, що я роблю колонки HomeTeamId
та AwayTeamId
стовпчики не нульовими, база даних гарантуватиме, що кожна гра, яку я ввожу, має 2 команди та що ці команди існують у моїй базі даних. А як щодо сценарію єдиної таблиці? Ну, оскільки в цій таблиці є кілька сутностей, ці стовпці повинні бути зведені нанівець (ви можете зробити так, щоб вони не були зведені нанівець і не переносили там дані про сміття, але це просто жахлива ідея). Якщо ці стовпці є нульовими, база даних вже не може гарантувати, що коли ви вставляєте гру, вона містить дві команди.
Але що робити, якщо ви все-таки вирішите просто піти на це? Ви встановите закордонні ключі таким чином, щоб ці поля вказували на іншу сутність у цій же таблиці. Але тепер база даних просто переконається, що ці сутності існують у таблиці, а не те, що вони є правильним типом. Ви можете дуже легко встановити GameHomeTeamId
ідентифікатор іншої гри, і база даних взагалі не скаржиться. Якщо ви спробували це в сценарії з декількома таблицями, база даних кинула би форму.
Ви можете спробувати пом'якшити ці проблеми, сказавши "ну, ми просто переконаємось, що ми ніколи цього не робимо в коді". Якщо ви впевнені у своїй здатності писати безкоштовний код уперше та у своїй здатності враховувати кожну дивну комбінацію речей, які може спробувати користувач, ідіть прямо вперед. Я особисто не впевнений у своїй здатності робити будь-яку з цих речей, тому дозволю базі даних отримати додаткову мережу безпеки.
(Це стає ще гірше, якщо ваш дизайн - це той, де ви копіюєте всі відповідні дані між рядків замість використання сторонніх ключів. Будь-які невідповідності правопису / інших даних буде важко вирішити. Як ви можете сказати, чи "Джон" є неправильним написанням "Джона "або якщо це було навмисно (бо це дві окремі люди)?)
По-третє, майже кожен стовпець повинен бути нульовим або повинен бути заповнений або скопійованими або сміттєвими даними. Гра не потребує TeamName
або TeamHomeCity
. Отже, будь-якій грі потрібен якийсь заповнювач там, або він повинен бути зведеним нанівець. І якщо вона зведена нанівець, база даних із задоволенням прийме гру без " TeamName
. Це також візьме команду без імені, навіть якщо ваша бізнес-логіка говорить, що цього ніколи не повинно відбуватися.
Є кілька інших причин, чому ви хочете окремі таблиці (включаючи збереження розумності розробника). Навіть є кілька причин, чому більша таблиця може бути кращою (денормалізація іноді покращує продуктивність). Таких сценаріїв мало і далеко (і, як правило, найкраще обробляти, коли у вас є показники ефективності, щоб показати, що це справді проблема, а не пропущений індекс чи щось інше).
Нарешті, розробіть щось, що легко буде підтримувати. Тільки тому, що це "працює", не означає, що це нормально. Намагатися підтримувати богові таблиці (як і заняття богом) - це кошмар. Ви просто налаштовуєте себе на біль пізніше.