-- Sposób 1: Jako ograniczenie tabeli (zalecany) CREATE TABLE produkty ( id_produktu INT AUTO_INCREMENT PRIMARY KEY, nazwa VARCHAR(200) NOT NULL, id_kategorii INT, -- Definicja FK na końcu tabeli CONSTRAINT fk_produkt_kat FOREIGN KEY (id_kategorii) REFERENCES kategorie(id_kategorii) ON DELETE SET NULL ON UPDATE CASCADE ); -- Sposób 2: Bez nazwy ograniczenia (MySQL nada automatycznie) FOREIGN KEY (id_kategorii) REFERENCES kategorie(id_kategorii);
| Warunek | Opis |
|---|---|
| Zgodność typów | Typ kolumny FK musi być zgodny z typem PK w tabeli nadrzędnej (np. INT i INT) |
| Tabela nadrzędna musi istnieć | Tabela z PK musi być utworzona przed tabelą z FK |
| Silnik InnoDB | Oba silniki tabel muszą być InnoDB (MyISAM ignoruje FK) |
| Indeks na kolumnie FK | MySQL automatycznie tworzy indeks na kolumnie FK (przyspiesza JOIN) |
| Akcja | ON DELETE — po usunięciu rodzica | ON UPDATE — po zmianie PK rodzica | Kiedy używać? |
|---|---|---|---|
CASCADE |
Usuwa powiązane rekordy dziecka | Aktualizuje FK w rekordach dziecka | Usuwanie kaskadowe (np. zamówienie i jego pozycje) |
SET NULL |
Ustawia FK na NULL (kolumna musi być nullable) | Ustawia FK na NULL | Produkt istnieje po usunięciu kategorii |
RESTRICT |
Blokuje usunięcie rodzica gdy ma dzieci | Blokuje zmianę PK gdy ma dzieci | Ochrona przed przypadkowym usunięciem (domyślne) |
NO ACTION |
Jak RESTRICT (sprawdza po transakcji) | Jak RESTRICT | Standard SQL, w MySQL = RESTRICT |
SET DEFAULT |
Ustawia wartość domyślną (rzadko używane) | Ustawia wartość domyślną | Nieobsługiwane przez InnoDB! |
ON DELETE CASCADE ON UPDATE CASCADE — dla pozycji zamówień (gdy usuniemy zamówienie, usuń pozycje)ON DELETE SET NULL ON UPDATE CASCADE — dla produktów (gdy usuniemy kategorię, produkt zostaje bez kategorii)ON DELETE RESTRICT ON UPDATE CASCADE — ochrona przed usunięciem
-- 1. Tabela nadrzędna — tworzymy PIERWSZA CREATE TABLE kategorie ( id_kategorii INT AUTO_INCREMENT PRIMARY KEY, nazwa VARCHAR(100) NOT NULL UNIQUE ) ENGINE=InnoDB; -- 2. Tabela podrzędna — tworzymy PO kategoriach CREATE TABLE produkty ( id_produktu INT AUTO_INCREMENT PRIMARY KEY, nazwa VARCHAR(200) NOT NULL, cena DECIMAL(10,2) NOT NULL DEFAULT 0.00, id_kategorii INT, CONSTRAINT fk_prod_kat FOREIGN KEY (id_kategorii) REFERENCES kategorie(id_kategorii) ON DELETE SET NULL ON UPDATE CASCADE ) ENGINE=InnoDB; -- 3. Tabela pośrednia zamówień — tworzymy OSTATNIA CREATE TABLE pozycje_zamowien ( id_pozycji INT AUTO_INCREMENT PRIMARY KEY, id_zamowienia INT NOT NULL, id_produktu INT NOT NULL, ilosc SMALLINT UNSIGNED NOT NULL DEFAULT 1, cena_jedn DECIMAL(10,2) NOT NULL, -- cena w momencie zamówienia! CONSTRAINT fk_poz_zam FOREIGN KEY (id_zamowienia) REFERENCES zamowienia(id_zamowienia) ON DELETE CASCADE, CONSTRAINT fk_poz_prod FOREIGN KEY (id_produktu) REFERENCES produkty(id_produktu) ON DELETE RESTRICT ) ENGINE=InnoDB;
cena_jedn w tabeli pośredniej (nie FK do aktualnej ceny produktu). To celowa redundancja — historyczna cena z momentu zamówienia musi być niezmieniona.
Poniżej tabela pracownicy. Uzupełnij brakujący fragment definiujący klucz obcy do tabeli dzialy:
CREATE TABLE pracownicy ( id_pracownika INT AUTO_INCREMENT PRIMARY KEY, imie VARCHAR(50) NOT NULL, id_dzialu INT NOT NULL, -- UZUPEŁNIJ FK TUTAJ );
Masz tabelę zamowienia i pozycje_zamowien z ON DELETE CASCADE na FK do zamówień. Co się stanie gdy usuniesz zamówienie o id=5?
Uzupełnij brakujące elementy w definicji klucza obcego:
CASCADE — usuwa/aktualizuje zależne rekordy automatycznieSET NULL — ustawia FK na NULL (kolumna musi dopuszczać NULL)RESTRICT — blokuje operację gdy istnieją rekordy zależne (domyślne)