Повернутися до всіх запитань

Що таке foreign key в SQL?

DatabasesJuniorMiddle
Зустрічали на інтервʼю:1 користувач

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

Простий приклад

В нас є таблиця users i orders. Користувач може створювати замовлення, і відповідно запис в таблиці orders має бути привʼязаний до конкретного запису в users. Для того, щоб звʼязати їх, ми будемо використовувати поле orders.user_id і таким чином будемо розуміти, хто створив замовлення.

users
+----+-------+
| id | name |
+----+-------+
| 1 | Ivan |
| 2 | Maria |
+----+-------+

orders
+----+---------+---------+
| id | user_id | product |
+----+---------+---------+
| 1 | 1 | Laptop |
| 2 | 1 | Mouse |
| 3 | 2 | Phone |
+----+---------+---------+

З практичної точки зору, ми можемо реалізувати цю привʼязку і без Foreign Key, просто записуючи ID як число в поле user_id. Але цей підхід має декілька значних мінусів:

  1. База даних не контролює звʼязки між таблицями. Наприклад, в даному випадку в нас звʼязок one-to-many (один користувач має багато замовлень). Але якщо ми спробуємо зробити вибірку по конкретному користувачу, база даних буде сканувати всю таблицю, так як вона не знає, які замовлення відносяться до користувача, бо user_id це просто число, а не посилання на іншу таблицю.
  2. Немає захисту від неіснуючих даних. Якщо ми захочемо записати в user_id число 100, ми не отримаємо ніякої помилки про те, що такого користувача не існує.
  3. Немає контролю при видаленні чи оновленні користувача. Якщо при видаленні користувача нам потрібно буде видаляти всі його замовлення, то без Foreign Key ми будемо змушені робити це в бізнес-логіці. Тоді як зовнішній ключ реалізовує механізм referential actions, який дозволяє контролювати процес. Детально про цей механізм тут.

Всі ці проблеми вирішує Foreign Key, який забезпечує тісний звʼязок між таблицями і дозволяє нам реалізувати звʼязки між ними.

Зустрічав на інтервʼю?

Повʼязані питання

JuniorMiddleDatabases

Як працює LEFT JOIN?

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

Розберемо приклад

Ми маємо дві таблиці users i orders. Наша задача полягає в тому щоб отримати всіх користувачів разом з замовленнями. Якщо в користувача немає замовлення, ми все одно маємо включити його в список тому ми будемо використовувати LEFT JOIN.

-- users
id | name
------------
1 | Alice
2 | Bob
3 | Charlie

-- orders
id | user_id | product
------------------------
1 | 1 | Laptop
2 | 1 | Mouse
3 | 2 | Keyboard

Запит буде мати наступний вигляд. Давайте розберемо його детальніше:

-- Вибираємо стовпці, які хочемо бачити в результаті:
-- name - з таблиці users
-- product - з таблиці orders
SELECT
users.name,
orders.product
FROM
users
-- Робимо LEFT JOIN — тобто беремо ВСІ рядки з таблиці users (ліва таблиця)
-- і додаємо дані з таблиці orders (права таблиця), якщо знайдеться збіг.
LEFT JOIN
orders
-- Визначаємо умову, за якою пов’язуються рядки з обох таблиць:
-- якщо значення users.id збігається з orders.user_id, то ці рядки об’єднуються.
ON
users.id = orders.user_id;

В результаті виконання запиту, ми отримаємо такий результат:

name | product
-------------------
Alice | Laptop
Alice | Mouse
Bob | Keyboard
Charlie | NULL -- Хоч і Charlie не має співпадінь в правій таблиці, LEFT JOIN все одно додає його до вибірки, але в значенні правої таблиці буде NULL
DatabasesJuniorMiddle

Як працює RIGHT JOIN?

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

Розберемо приклад

У нас є дві таблиці: users і orders. Наша задача - отримати всі замовлення разом з інформацією про користувача, навіть якщо користувача немає (наприклад, замовлення створено, але користувач був видалений чи не існує).

-- users
id | name
------------
1 | Alice
2 | Bob
3 | Charlie

-- orders
id | user_id | product
------------------------
1 | 1 | Laptop
2 | 1 | Mouse
3 | 2 | Keyboard
4 | 4 | Monitor

Запит буде мати наступний вигляд. Розберемо його детальніше:

SELECT
users.name,
orders.product
FROM
users -- Ліва таблиця
RIGHT JOIN
orders -- Права таблиця: повертаємо всі її рядки
ON
users.id = orders.user_id; -- Умова зв’язку таблиць

В останньому рядку, ім’я буде NULL, але замовлення Monitor буде в результаті, тому що RIGHT JOIN гарантує, що всі рядки з таблиці orders (правої таблиці) будуть включені.

name | product
-----------------------
Alice | Laptop
Alice | Mouse
Bob | Keyboard
NULL | Monitor
JuniorMiddleDatabases

Як працює CROSS JOIN?

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

Розберемо приклад

Ми маємо дві таблиці: users і plans. Наша задача полягає в тому, щоб отримати всі можливі пари користувачів і тарифів. Для цього ми будемо використовувати CROSS JOIN.

-- users
id | name
------------
1 | Alice
2 | Bob


-- plansœ
id | plan_name
-------------------
1 | Basic
2 | Premium
3 | Enterprise

Запит буде мати наступний вигляд. Давайте розберемо його детальніше:

-- Вибираємо стовпці, які хочемо бачити в результаті:
-- name - з таблиці users
-- plan_name - з таблиці plans
SELECT
users.name,
plans.plan_name
FROM
users
-- Робимо CROSS JOIN - тобто беремо кожен рядок з таблиці users
-- і поєднуємо його з КОЖНИМ рядком з таблиці plans
CROSS JOIN
plans;

В результаті виконання запиту, ми отримаємо такий результат: Alice поєдналася з усіма тарифами і так само Bob поєднався з усіма можливими тарифами.

name | plan_name
-------------------------
Alice | Basic
Alice | Premium
Alice | Enterprise
Bob | Basic
Bob | Premium
Bob | Enterprise

Важливо пам’ятати

CROSS JOIN може дуже швидко створити велику кількість рядків. Наприклад, якщо в першій таблиці 100 рядків, а в другій 200, то результат буде містити вже 20 000 рядків. Тому його потрібно використовувати обережно.

Коментарі (0)

Увійдіть, щоб залишити коментар

Поки що немає коментарів. Будьте першим!