Посібник із проектування реляційних баз даних

Посібник із проектування реляційних баз даних

  • 17 травня, 2022
  • читати 15 хв

Зв'язок один-до-багатьох

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

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

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

Схематичне уявлення зв'язку один-до-багатьох. Запис у таблиці А має 0, 1 чи безліч асоційованих їй записів у таблиці B.

Як упізнати зв'язок один-до-багатьох?

Якщо у вас є дві сутності запитайте себе:

  1. Скільки об'єктів B можуть відноситися до об'єкта A?
  2. Скільки об'єктів з A можуть відноситися до об'єкта з B?

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

Деякі приклади зв'язку один-до-багатьох:

  • Машина та її частини. Кожна частина машини одноразово належить лише одній машині, але машина може мати безліч частин
  • Кінотеатри та екрани. В одному кінотеатрі може бути безліч екранів, але кожен екран належить лише одному кінотеатру
  • Діаграма сутність-зв'язок та її таблиці. Діаграма може мати більше однієї таблиці, але кожна з цих таблиць належить тільки одній діаграмі
  • Будинки та вулиці. На вулиці може бути кілька будинків, але кожен будинок належить лише одній вулиці

В даному випадку все настільки просто, що тільки тому може виявитися важким розуміння.

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

Зв'язок багато-до-багатьох

Зв'язок багато-до-багатьох — це зв'язок, при якому множинним записам з однієї таблиці (A) можуть відповідати множинні записи з іншої (B).

Прикладом такого зв'язку може бути школа, де вчителі навчають учнів. У більшості шкіл кожен учитель навчає багатьох учнів, а кожен учень може навчатися кількома учителями.

Зв'язок між постачальником пива і пивом, яке вони поставляють — це теж зв'язок багато-до-багатьох. Постачальник у багатьох випадках надає більше одного виду пива, а кожен вид пива може бути наданий безліччю постачальників.

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

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

Створення зв'язку багато-до-багатьох

Зв'язок багато-до-багатьох створюється за допомогою трьох таблиць.

Дві таблиці: джерела та одна сполучна таблиця. Первинний ключ сполучної таблиці A_B — складовий. Вона складається із двох полів, двох зовнішніх ключів, які посилаються на первинні ключі таблиць A та B.

Усі первинні ключі мають бути унікальними. Це має на увазі і те, що комбінація полів A і B має бути унікальною в таблиці A_B.

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

Таблиці «про пиво»

Таблиці вище пов'язують постачальників і пиво зв'язком багато-до-багатьох, використовуючи сполучну таблицю. Зверніть увагу, що пиво 'Gentse Tripel' (157) поставляють Horeca Import NL (157, AC001), Jansen Horeca (157, AB899) та Petersen Drankenhandel (157, AC009). І vice versa, Petersen Drankenhandel є постачальником 3 видів пива з таблиці, а саме: Gentse Tripel (157, AC009), Uilenspiegel (158, AC009) та Jupiler (163, AC009).

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

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

Інший приклад зв'язку багато-багатьом: замовлення номерів в готелії

Як останній приклад: як міг би бути змодельована таблиця замовлень номерів готелю відвідувачами.

Сполучна таблиця зв'язку багато-до-багатьох має додаткові поля.

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

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

Зв'язок один-до-одного

У зв'язку один-до-одного кожен блок сутності A може бути асоційований з 0, 1 блоком сутності B.

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

В одній таблиці

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

В окремих таблицях

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

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

Приклади зв'язку один до одного

Люди та їх паспорти. Кожна людина в країні має тільки один паспорт, що діє, і кожен паспорт належить тільки одній людині.

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

Який вид зв'язку вам потрібен?

Приклади зв'язків таблиць практично. Коли якісь дані є унікальними для конкретного об'єкта, наприклад, людина та номери її паспортів, такий зв'язок — зв'язок один-до-багатьох. Тобто, в одній таблиці ми маємо список деяких людей, а в іншій таблиці ми маємо перерахування номерів паспортів цієї людини (наприклад, паспорт країни проживання та закордонний паспорт). І ця комбінація даних є унікальною для кожної людини. Тобто, кожна людина може мати кілька номерів паспортів, але кожен паспорт може мати лише одного власника. Отже: потрібні дві таблиці.

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

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

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