Czym jest encja i jej atrybuty, jak wybrać klucz główny, po co jest klucz obcy i jak dobrać typ danych do każdej kolumny, gdy projektujesz tabelę od zera. Lekcja 7.2 kursu INF.03.
Encja (entity) to typ obiektu, o którym baza przechowuje dane: klient, produkt, zamówienie. W bazie relacyjnej encji odpowiada tabela, pojedynczemu wystąpieniu encji rekord, a atrybutowi encji kolumna. Na egzaminie pisemnym wracają z tego trzy pytania: przez co jest reprezentowana encja, co jednoznacznie identyfikuje rekord i jaki typ danych pasuje do opisanej kolumny. W zadaniu praktycznym ta sama wiedza jest potrzebna dwa razy: przy czytaniu schematu relacji z arkusza i przy poleceniu ALTER TABLE ... ADD, w którym typ nowej kolumny podano słowami.
Encja i atrybut
Encja to rzeczownik z opisu zadania, o którym trzymamy WIELE wystąpień o tym samym zestawie cech. Atrybut to jedna taka cecha. Projekt bazy zaczyna się od zdań zamawiającego:
1
2
Biuro turystyczne prowadzi listę wycieczek: nazwa, kraj, cena,
liczba dni, termin wyjazdu.
Encją jest tutaj wycieczka, bo wycieczek jest wiele i każda ma nazwę, kraj, cenę, liczbę dni i termin. Te pięć rzeczy to atrybuty: opisują wycieczkę, ale nie są obiektami, o których zbieramy osobne dane. Kraj bywa granicznym przypadkiem: jeżeli zamawiający chce trzymać przy kraju walutę i wymagane dokumenty, kraj staje się osobną encją. Definicję encji z atrybutami zapisuje się w projekcie skrótowo, z kluczem głównym na pierwszym miejscu:
1
wycieczka(id, nazwa, kraj, cena, dni, termin)
Dziedzina (domain) atrybutu to zbiór wartości, które wolno w nim zapisać. Dziedziną atrybutu dni są liczby całkowite dodatnie, dziedziną atrybutu cena liczby nieujemne z dwoma miejscami po przecinku. Dziedzina jest tym, co potem przekłada się na typ danych i na ograniczenia kolumny.
Atrybut prosty ma jedną, niepodzielną wartość: cena, termin. Atrybut złożony rozpada się na części, jak adres na ulicę, kod pocztowy i miasto. W tabeli zapisuje się go jako osobne kolumny ulica, kod, miasto, bo wyszukiwanie po samym mieście z jednej wspólnej kolumny jest niewykonalne. Atrybut jednowartościowy trzyma jedną wartość na wystąpienie, a atrybut wielowartościowy wiele: klient z dwoma numerami telefonu. Kolumna telefon z wpisem 600100200, 601200300 to sygnał, że brakuje osobnej tabeli. Dlaczego tak jest, tłumaczy lekcja o normalizacji.
Klucz główny
Klucz główny (PRIMARY KEY, w pytaniach nazywany też kluczem podstawowym) to kolumna albo zestaw kolumn, które jednoznacznie identyfikują rekord w tabeli. Po jego wartości baza trafia w dokładnie jeden wiersz i po niej wskazują go inne tabele.
›
Wartość jest unikalna: dwa rekordy nie mogą mieć tej samej.
›
Wartość nigdy nie jest pusta, więc kolumnę zabezpiecza się atrybutem NOT NULL.
›
Tabela ma dokładnie jeden klucz główny.
›
Dobry klucz jest krótki i niezmienny, bo powtarza się w kluczach obcych innych tabel.
Klucz kandydujący (candidate key) to każda kolumna albo zestaw kolumn, które mogłyby pełnić tę rolę. W tabeli klient kandydatami są numer PESEL i adres e-mail, a imię nie, bo Anna może być druga. Z kandydatów wybiera się jeden i on zostaje kluczem głównym.
Klucz naturalny pochodzi z danych, które i tak opisują obiekt: PESEL, numer indeksu, ISBN książki. Klucz sztuczny (surrogate key) to numer dodany tylko po to, żeby identyfikować rekord, w MySQL najczęściej id INT AUTO_INCREMENT. W praktyce prawie zawsze wybiera się sztuczny: naturalny bywa długi, bywa nieznany w chwili dodawania rekordu, potrafi się zmienić (nazwisko po ślubie, adres e-mail), a PESEL to dodatkowo dana osobowa, której nie chce się kopiować do połowy tabel. Dlatego w bazie sklepu klient, produkt i zamowienie mają zwykłe id.
Klucz złożony (composite key) to klucz główny zbudowany z dwóch albo więcej kolumn, które dopiero razem są unikalne. Typowo w tabeli łączącej: w tabeli uczen_przedmiot kolumny uczen_id i przedmiot_id osobno powtarzają się wiele razy, ale para uczeń plus przedmiot występuje raz.
Pułapka: klucz główny nie musi być liczbą i nie musi nazywać się id, ale musi być unikalny i różny od NULL. Właśnie to nazywa się integralnością encji.
Klucz obcy
Klucz obcy (FOREIGN KEY) to kolumna, która przechowuje wartość klucza głównego innej tabeli. Tworzy się go po to, żeby zdefiniować relację jeden do wielu: klucz obcy stoi zawsze po stronie „wiele". Jeden klient ma wiele zamówień, więc to zamowienie dostaje kolumnę klient_id, a nie odwrotnie. W bazie sklepu wygląda to tak: klient(id, imie, miasto) z kluczem głównym id oraz zamowienie(id, klient_id, produkt_id, ilosc, kwota), w którym klient_id wskazuje na klient.id.
W tabeli klient kluczem głównym jest kolumna id, a w tabeli zamowienie kolumna klient_id jest kluczem obcym wskazującym na tę wartość, przy czym zamówienie 13 ma w niej NULL
Klucz obcy pilnuje integralności referencyjnej: każdej wartości klucza obcego musi odpowiadać istniejąca wartość klucza głównego w tabeli powiązanej. Baza nie pozwoli dodać zamówienia klienta o numerze 99, skoro takiego klienta nie ma, ani skasować klienta, do którego zamówienia się odwołują. Sam klucz obcy może być pusty, jeżeli kolumna nie ma NOT NULL: zamówienie 13 z rysunku ma NULL w klient_id, bo powstało bez konta. NULL nie łamie integralności, bo nie wskazuje na nic.
Typ kolumny z kluczem obcym musi być identyczny z typem klucza głównego, na który wskazuje. Jeżeli klient.id jest INT UNSIGNED, to zamowienie.klient_id też, inaczej baza odrzuci definicję relacji.
1
2
3
4
5
6
7
CREATETABLEzamowienie(
idINTAUTO_INCREMENTPRIMARYKEY,
klient_idINT,
produkt_idINTNOTNULL,
iloscINTNOTNULL,
FOREIGNKEY(klient_id)REFERENCESklient(id)
);
Gdy klucz główny wskazywanej tabeli jest złożony, klucz obcy też obejmuje kilka kolumn i zapisuje się go z nazwą ograniczenia. Tak wygląda odwołanie tabeli ocena do złożonego klucza tabeli uczen_przedmiot:
Opis z arkusza brzmi tak: biuro turystyczne oferuje wycieczki, każda ma nazwę, kraj, cenę i liczbę dni; klient ma imię, nazwisko i adres e-mail; klient zapisuje się na wycieczki. Zaprojektuj encje, wskaż klucze i dobierz typy.
Rozwiązanie zaczyna się od wypisania encji. Rzeczowniki z wieloma wystąpieniami to wycieczka i klient. Zdanie „klient zapisuje się na wycieczki" opisuje powiązanie: jeden klient jeździ na wiele wycieczek, a na jedną wycieczkę zapisuje się wielu klientów, więc powstaje trzecia encja, tabela łącząca zapis.
1
2
3
wycieczka(id, nazwa, kraj, cena, dni)
klient(id, imie, nazwisko, email)
zapis(wycieczka_id, klient_id, data_zapisu)
Tabela
Klucz główny
Klucze obce
wycieczka
id, sztuczny
brak
klient
id, sztuczny; email był kandydatem, ale bywa zmieniany
brak
zapis
złożony: wycieczka_id plus klient_id
wycieczka_id, klient_id
Atrybut
Typ
wycieczka.nazwa
VARCHAR(100) NOT NULL
wycieczka.kraj
VARCHAR(50)
wycieczka.cena
DECIMAL(8,2) NOT NULL
wycieczka.dni
TINYINT UNSIGNED
klient.imie
VARCHAR(40)
klient.email
VARCHAR(120)
zapis.data_zapisu
DATE
Na egzaminie
Pytania pisemne z tej lekcji są krótkie i powtarzalne. „Encja jest reprezentowana przez" z odpowiedzią tabela. „Jednoznacznemu identyfikatorowi rekordu odpowiada" z odpowiedzią klucz główny. „Klucz obcy tworzy się po to, aby zdefiniować relację 1..n wiążącą go z kluczem głównym innej tabeli", i to zdanie warto znać w tej właśnie postaci, bo dystraktory mówią o sortowaniu albo o przyspieszaniu zapytań, czym zajmuje się indeks, a nie klucz obcy. „Klucz główny zabezpiecza się przed pustą wartością atrybutem" z odpowiedzią NOT NULL. „Typ dla kodów pocztowych o stałej długości" z odpowiedzią CHAR. Osobne pytanie pokazuje zapis CONSTRAINT nazwa FOREIGN KEY (a, b) REFERENCES tabela (a, b) i pyta, co on robi: definiuje klucz obcy złożony z dwóch kolumn.
W zadaniu praktycznym arkusz daje gotowy plik .sql i rysunek schematu. Kolumny z końcówką _id to prawie zawsze klucze obce i to one wyznaczają, po czym łączyć tabele w kwerendzie „wykorzystującej relację". Drugie miejsce to ALTER TABLE ... ADD z kolumną opisaną słowami: „pole na ocenę od 1 do 6" to TINYINT UNSIGNED, „pole na cenę" to DECIMAL(8,2), „pole na kod pocztowy" to CHAR(6). Najczęstszy błąd na tym poleceniu to INT wszędzie tam, gdzie w treści pojawia się cyfra.
Ściąga
Pojęcie
Zapamiętaj
encja
typ obiektu, w bazie relacyjnej tabela
wystąpienie encji
jeden rekord, czyli wiersz tabeli
atrybut
cecha encji, czyli kolumna
dziedzina
zbiór wartości dopuszczalnych w atrybucie
klucz główny
unikalny, NOT NULL, jeden na tabelę
klucz kandydujący
każdy kandydat na klucz główny; wybiera się jeden
klucz sztuczny
id INT AUTO_INCREMENT, domyślny wybór
klucz naturalny
PESEL, ISBN; bywa zmienny i długi
klucz złożony
dwie kolumny razem, typowy w tabeli łączącej
klucz obcy
wskazuje na klucz główny innej tabeli, stoi po stronie „wiele"
integralność referencyjna
każdej wartości klucza obcego odpowiada istniejący klucz główny