Який кращий дизайн бази даних: більше таблиць або більше стовпців?


77

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

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

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

Відповіді:


60

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

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

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


Що таке "таблиця нижче"?
оливкова

1
Я маю на увазі "нижчий потік" у контексті "потоку даних". Що, по суті, означає, що у вас є процес, який використовує нормалізовані таблиці як джерело, якийсь спосіб перетворює дані, а потім депонує результат деінде.
Кріс Аммерман,

12

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

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


11

Це звучить не стільки як питання про таблиці / стовпці, скільки про нормалізацію. У деяких ситуаціях високий ступінь нормалізації (у цьому випадку "більше таблиць") є хорошим та чистим, але зазвичай для отримання відповідних результатів потрібна велика кількість СПІЛКУВАНЬ. А при досить великому наборі даних це може привести до зниження продуктивності.

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


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

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

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

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

Поганий дизайн, як правило, є найбільшим фактором поганої роботи, а не нормалізації.
Ед Гінес

5

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

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

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


Домовились. Я коли-небудь денормалізував лише зменшення складності запиту, як правило, для усунення невідповідності імпедансу ORM. Ніколи, тому що оптимізація була потрібна для продуктивності, навіть у великих масштабах.
Ben Simmons

5

Це залежить від смаку вашої бази даних. Наприклад, MS SQL Server надає перевагу більш вузьким таблицям. Це також більш "нормалізований" підхід. Інші двигуни можуть віддати перевагу навпаки. Мейнфрейми, як правило, потрапляють до цієї категорії.


4

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

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


3

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


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

3

Як і все інше: це залежить.

Не існує чіткого правила щодо кількості стовпців проти кількості таблиць.

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

Важкий, нормалізований дизайн столу є ефективним з точки зору простору і виглядає як "підручник", але може стати надзвичайно складним. Це виглядає приємно, поки вам не доведеться робити 12 приєднань, щоб отримати ім’я та адресу клієнта. Ці конструкції не є автоматично фантастичними з точки зору продуктивності, що має найбільше значення: запити.

Уникайте складності, якщо це можливо. Наприклад, якщо клієнт може мати лише дві адреси (не довільно багато), то може мати сенс просто зберегти їх усі в одній таблиці (CustomerID, Name, ShipToAddress, BillingAddress, ShipToCity, BillingCity тощо).

Ось допис Джефа на цю тему.


2

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

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


1

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

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


1
Мої 2 центи: я повинен не погодитися; проведення такої оптимізації під час проектування є класичним випадком передчасної оптимізації. Зачекайте, поки не побачите, що продуктивність є проблемою, перш ніж пожертвувати гарним дизайном.
JosephStyons

1

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

Я здогадуюсь, якою б я відповів, використовуйте найкраще судження.


1

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


1

Хм

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

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


1

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

Хороший дизайн бази даних повинен тривати протягом 20 років без змін.

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

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

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


0

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

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


0

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

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

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


0

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


0

Приємно бачити стільки надихаючих та обґрунтованих відповідей.

Моя відповідь була б (на жаль): це залежить.

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

Те саме стосується вибору між об'єктно-орієнтованим підходом та іншими варіантами.

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