Нормалізація бази даних: Проста історія кафе “Café Delight”

pic

Уявіть, що ви відкриваєте нову кав'ярню під назвою Café Delight. Ви хочете використовувати базу даних для відстеження замовлень, клієнтів та меню. Коли ви вперше проектуєте базу даних, вона виглядає трохи хаотично. Давайте подивимося, як нормалізація може допомогти впорядкувати все.

1НФ (Перша нормальна форма): "Ніякого безладу в таблицях"

Проблема: Спочатку у вас є таблиця, яка виглядає так:

| OrderID | CustomerName | MenuItems | Quantities |  
|---------|--------------|------------------------|------------|  
| 1 | Alice | Coffee, Croissant | 1, 2 |  
| 2 | Bob | Sandwich, Orange Juice | 1, 1 |
  • Стовпці MenuItems та Quantities містять кілька значень (наприклад, "Coffee, Croissant" і "1, 2").
  • Такий формат заплутаний і важкий для запитів.

Правило: У 1НФ кожен стовпець повинен містити атомарні (неділові) значення.

Рішення: Розділімо таблицю так, щоб кожен елемент даних був у окремому рядку:

| OrderID | CustomerName | MenuItem | Quantity |  
|---------|--------------|---------------|----------|  
| 1 | Alice | Coffee | 1 |  
| 1 | Alice | Croissant | 2 |  
| 2 | Bob | Sandwich | 1 |  
| 2 | Bob | Orange Juice | 1 |

Тепер кожен стовпець містить лише одне значення, і таблиця відповідає вимогам 1НФ.

2НФ (Друга нормальна форма): "Без часткових залежностей"

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

| OrderID | CustomerName | MenuItem | Quantity | Price |  
|---------|--------------|---------------|----------|--------|  
| 1 | Alice | Coffee | 1 | $3.00 |  
| 1 | Alice | Croissant | 2 | $2.50 |  
| 2 | Bob | Sandwich | 1 | $5.00 |  
| 2 | Bob | Orange Juice | 1 | $4.00 |

Ось у чому проблема:

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

Правило: У 2НФ всі атрибути, що не є ключовими, повинні залежати від всього первинного ключа. (Без часткових залежностей!)

Рішення: Розділімо таблицю на дві:

1. Таблиця `Orders`, яка відстежує замовлення та кількості:  

| OrderID | CustomerName | MenuItem | Quantity |  
|---------|--------------|---------------|----------|  
| 1 | Alice | Coffee | 1 |  
| 1 | Alice | Croissant | 2 |  
| 2 | Bob | Sandwich | 1 |  
| 2 | Bob | Orange Juice | 1 |  

2. Таблиця `Menu`, яка відстежує страви меню та їх ціни:  

| MenuItem | Price |  
|---------------|--------|  
| Coffee | $3.00 |  
| Croissant | $2.50 |  
| Sandwich | $5.00 |  
| Orange Juice | $4.00 |

Тепер ціна залежить лише від MenuItem, і таблиця відповідає вимогам 2НФ.

3НФ (Третя нормальна форма): "Без транзитивних залежностей"

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

| OrderID | CustomerName | MenuItem | Quantity | PhoneNumber |  
|---------|--------------|---------------|----------|--------------|  
| 1 | Alice | Coffee | 1 | 123-456-7890 |  
| 1 | Alice | Croissant | 2 | 123-456-7890 |  
| 2 | Bob | Sandwich | 1 | 987-654-3210 |  
| 2 | Bob | Orange Juice | 1 | 987-654-3210 |

Ось у чому проблема:

  • PhoneNumber залежить від CustomerName, а не безпосередньо від OrderID.
  • Якщо Аліса змінить свій номер телефону, вам доведеться оновити його в кількох рядках.

Правило: У 3НФ не повинно бути транзитивних залежностей. (Нехай неназивний стовпець не залежить від іншого неназивного стовпця.)

Рішення: Розділімо таблицю на три:

1. Таблиця `Orders`:  

| OrderID | CustomerName | MenuItem | Quantity |  
|---------|--------------|---------------|----------|  
| 1 | Alice | Coffee | 1 |  
| 1 | Alice | Croissant | 2 |  
| 2 | Bob | Sandwich | 1 |  
| 2 | Bob | Orange Juice | 1 |  

2.
Таблиця `Menu` (без змін):  

| MenuItem | Price |  
|---------------|--------|  
| Coffee | $3.00 |  
| Croissant | $2.50 |  
| Sandwich | $5.00 |  
| Orange Juice | $4.00 |  


3. Таблиця `Customers`:  

| CustomerName | PhoneNumber |  
|--------------|--------------|  
| Alice | 123-456-7890 |  
| Bob | 987-654-3210 |

Тепер PhoneNumber залежить лише від CustomerName, і таблиця відповідає вимогам 3НФ.

Висновок

Через Нормалізацію:

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

З правильно нормалізованою базою даних, Café Delight тепер може ефективно обробляти оновлення, запити та обслуговування без зайвих даних.

Перекладено з: Database Normalization: A Simple Story of Café Delight

Leave a Reply

Your email address will not be published. Required fields are marked *