Moduł 2 – Typy relacji w bazach danych
Czym jest relacja?
Relacja to logiczne powiązanie między dwiema tabelami. Realizowana jest poprzez klucze:
- Klucz główny (PRIMARY KEY) – jednoznacznie identyfikuje rekord w tabeli
- Klucz obcy (FOREIGN KEY) – odwołuje się do klucza głównego innej tabeli
Relacja 1 do 1 (jeden do jednego)
Jednemu rekordowi w tabeli A odpowiada dokładnie jeden rekord w tabeli B.
Kiedy stosować?
- Gdy chcemy rozdzielić dane rzadko używane od często używanych
- Dane wrażliwe (np. numer PESEL, dane logowania) w osobnej tabeli
Przykład
PRACOWNICY KONTA_BANKOWE
────────── ─────────────
NR_PRACOWNIKA ──1:1── NR_PRACOWNIKA
IMIE NR_KONTA
NAZWISKO BANK
CREATE TABLE KONTA_BANKOWE (
NR_PRACOWNIKA CHAR(4) NOT NULL,
NR_KONTA CHAR(26) NOT NULL,
BANK VARCHAR(40),
PRIMARY KEY (NR_PRACOWNIKA),
FOREIGN KEY (NR_PRACOWNIKA) REFERENCES PRACOWNICY(NR_PRACOWNIKA)
);
Relacja 1 do wielu (jeden do wielu) – 1:M
Jednemu rekordowi w tabeli A może odpowiadać wiele rekordów w tabeli B.
To najczęstszy typ relacji w bazach danych.
Przykład z bazy wypożyczalni
KLIENCI WYPOZYCZENIA
─────── ────────────
NR_KLIENTA ──1:M──> NR_KLIENTA
IMIE NR_WYPOZYCZENIA
NAZWISKO NR_SAMOCHODU
Jeden klient może mieć wiele wypożyczeń, ale każde wypożyczenie należy do jednego klienta.
SAMOCHODY WYPOZYCZENIA
───────── ────────────
NR_SAMOCHODU ─1:M──> NR_SAMOCHODU
MARKA NR_WYPOZYCZENIA
TYP DATA_WYP
Jeden samochód może być wielokrotnie wypożyczany (w różnych terminach).
-- Klucz obcy w tabeli WYPOZYCZENIA
CREATE TABLE WYPOZYCZENIA (
NR_WYPOZYCZENIA CHAR(8) NOT NULL,
NR_KLIENTA CHAR(8) NOT NULL,
NR_SAMOCHODU CHAR(6) NOT NULL,
-- ...
PRIMARY KEY (NR_WYPOZYCZENIA),
FOREIGN KEY (NR_KLIENTA) REFERENCES KLIENCI(NR_KLIENTA),
FOREIGN KEY (NR_SAMOCHODU) REFERENCES SAMOCHODY(NR_SAMOCHODU)
);
Relacja wiele do wielu – N:M
Wielu rekordom w tabeli A może odpowiadać wiele rekordów w tabeli B.
Realizacja
Relacja N:M nie może być bezpośrednio zaimplementowana w SQL. Wymaga tabeli pośredniej (asocjacyjnej).
STUDENCI KURSY
──────── N:M ─────
ID_STUDENTA ────> ID_KURSU
IMIE NAZWA
NAZWISKO OPIS
↓ rozkład na 1:M + 1:M
STUDENCI ZAPISY KURSY
──────── ────── ─────
ID_STUDENTA ─1:M> ID_STUDENTA ID_KURSU
ID_KURSU <M:1─ ID_KURSU
Przykład z bazy wypożyczalni
W bazie wypożyczalni relacja N:M mogłaby wystąpić między KLIENCI a SAMOCHODY:
- jeden klient może wypożyczyć wiele samochodów
- jeden samochód może być wypożyczony przez wielu klientów
Tabela WYPOZYCZENIA pełni rolę tabeli pośredniej:
KLIENCI ─── WYPOZYCZENIA ─── SAMOCHODY
1 N:M 1
Diagram bazy wypożyczalni
MIEJSCA (1) ────────< PRACOWNICY (N)
│
│ (miejsca wypożyczenia i oddania)
↓
WYPOZYCZENIA (N) >──── KLIENCI (1)
│
│
└──────────────── SAMOCHODY (1)
Pełna struktura relacji:
| Tabela A | Relacja | Tabela B | Klucz łączący |
|---|---|---|---|
| KLIENCI | 1:M | WYPOZYCZENIA | NR_KLIENTA |
| SAMOCHODY | 1:M | WYPOZYCZENIA | NR_SAMOCHODU |
| MIEJSCA | 1:M | WYPOZYCZENIA | NR_MIEJSCA_WYP / NR_MIEJSCA_ODD |
| PRACOWNICY | 1:M | WYPOZYCZENIA | NR_PRACOW_WYP / NR_PRACOW_ODD |
| MIEJSCA | 1:M | PRACOWNICY | NR_MIEJSCA |
Integralność referencyjna
Relacje wymuszają integralność referencyjną – nie można:
- dodać wypożyczenia dla nieistniejącego klienta
- usunąć klienta, który ma powiązane wypożyczenia (bez kaskady)
-- Próba usunięcia klienta z wypożyczeniami spowoduje błąd:
DELETE FROM KLIENCI WHERE NR_KLIENTA = '00000001';
-- ERROR: Cannot delete parent row: a foreign key constraint fails
Poprzedni moduł: Języki SQL Następny moduł: Podstawy SELECT