Klucz główny i obcy w SQL: czym się różnią i jak je utworzyć
Klucz główny i obcy to dwa pojęcia, bez których nie ma relacyjnej bazy danych. Klucz główny jednoznacznie identyfikuje wiersz w tabeli, a klucz obcy wskazuje wiersz w innej tabeli i w ten sposób łączy je ze sobą. Poniżej wyjaśniamy różnicę, pokazujemy, jak zapisać oba klucze w SQL, i odpowiadamy na pytanie, które często pojawia się na egzaminie: po co tworzy się klucz obcy w tabeli.
Co to jest klucz główny
Klucz główny (PRIMARY KEY) to kolumna lub zestaw kolumn, których wartość jest inna w każdym wierszu tabeli. Działa jak numer PESEL dla człowieka: po nim baza odnajduje konkretny wiersz. Ma trzy cechy:
- wartości nie mogą się powtarzać,
- nie może być pusty, czyli NULL,
- w tabeli jest najwyżej jeden klucz główny, choć może obejmować kilka kolumn.
Najczęściej używa się sztucznego numeru, a nie danych z życia. Imię czy adres e-mail mogą się zmienić albo powtórzyć, a numer nadany przez bazę nie. Dlatego stosuje się klucz główny nadawany automatycznie:
CREATE TABLE klienci (
id_klienta INT AUTO_INCREMENT PRIMARY KEY,
imie VARCHAR(50) NOT NULL,
email VARCHAR(100) UNIQUE
);Słowo AUTO_INCREMENT sprawia, że MySQL sam nadaje kolejne numery. Przy dodawaniu wiersza nie trzeba podawać wartości id_klienta.
Co to jest klucz obcy
Klucz obcy (FOREIGN KEY) to kolumna, której wartości muszą istnieć w kluczu głównym innej tabeli. Tworzy powiązanie między tabelami. Zamówienie nie ma powtarzać danych klienta, tylko zapisuje jego numer:
CREATE TABLE zamowienia (
id_zam INT AUTO_INCREMENT PRIMARY KEY,
data_zam DATE NOT NULL,
id_klienta INT NOT NULL,
FOREIGN KEY (id_klienta) REFERENCES klienci(id_klienta)
);Teraz baza nie pozwoli dodać zamówienia dla klienta o numerze, którego nie ma w tabeli klienci. To właśnie jest odpowiedź na egzaminowe pytanie: klucz obcy w tabeli jest tworzony po to, aby zdefiniować relację z inną tabelą i pilnować spójności danych. W przeciwieństwie do klucza głównego może się powtarzać, bo jeden klient składa wiele zamówień. Takie podejście to podstawa, którą opisujemy w tekście o normalizacji baz danych.
Klucz główny i obcy: różnice w tabeli
| Cecha | Klucz główny | Klucz obcy |
|---|---|---|
| Rola | identyfikuje wiersz w tej tabeli | wskazuje wiersz w innej tabeli |
| Powtórzenia | nie | tak |
| NULL | nie | może, jeśli kolumna na to pozwala |
| Ile w tabeli | najwyżej jeden | wiele |
| Słowo w SQL | PRIMARY KEY | FOREIGN KEY … REFERENCES |
Relacje, które tworzą klucze
Jeden do wielu. Najczęstszy przypadek. Jeden klient ma wiele zamówień, więc klucz obcy jest po stronie „wielu”, czyli w tabeli zamówień.
Wiele do wielu. Zamówienie może mieć wiele produktów, a produkt być w wielu zamówieniach. Rozwiązuje się to tabelą pośrednią z dwoma kluczami obcymi:
CREATE TABLE pozycje_zamowienia (
id_zam INT NOT NULL,
id_produktu INT NOT NULL,
ilosc INT NOT NULL,
PRIMARY KEY (id_zam, id_produktu),
FOREIGN KEY (id_zam) REFERENCES zamowienia(id_zam),
FOREIGN KEY (id_produktu) REFERENCES produkty(id_produktu)
);Tu klucz główny jest złożony z dwóch kolumn, bo dopiero ich para jest unikalna. Przy okazji widać, że ta sama kolumna może być jednocześnie częścią klucza głównego i kluczem obcym.
Jeden do jednego. Rzadszy przypadek, na przykład osobna tabela z danymi wrażliwymi. Klucz obcy dostaje wtedy ograniczenie UNIQUE.
Co się dzieje przy usuwaniu: ON DELETE
Klucz obcy pilnuje też usuwania. Domyślnie baza zablokuje usunięcie klienta, który ma zamówienia. Możesz określić inne zachowanie:
- ON DELETE RESTRICT: nie pozwala usunąć klienta, który ma zamówienia. To zwykle najbezpieczniejsze ustawienie.
- ON DELETE CASCADE: usuwa klienta razem z jego zamówieniami. Przydatne, ale ryzykowne, bo jeden błąd usuwa wiele wierszy.
- ON DELETE SET NULL: zostawia zamówienie, ale czyści w nim numer klienta. Kolumna musi pozwalać na NULL.
FOREIGN KEY (id_klienta) REFERENCES klienci(id_klienta)
ON DELETE RESTRICT ON UPDATE CASCADEW MySQL klucze obce działają w silniku InnoDB, domyślnym w nowszych wersjach. Starszy MyISAM je ignoruje, więc gdy klucz nie działa, sprawdź najpierw silnik tabeli.
Jak dodać klucz do istniejącej tabeli
Klucze nie muszą powstawać razem z tabelą. Jeśli tabela już istnieje, używa się ALTER TABLE:
-- dodanie klucza głównego
ALTER TABLE klienci ADD PRIMARY KEY (id_klienta);
-- dodanie klucza obcego z własną nazwą
ALTER TABLE zamowienia
ADD CONSTRAINT fk_zam_klient
FOREIGN KEY (id_klienta) REFERENCES klienci(id_klienta);
-- usunięcie klucza obcego
ALTER TABLE zamowienia DROP FOREIGN KEY fk_zam_klient;Własna nazwa, tutaj fk_zam_klient, przydaje się, gdy klucz trzeba później usunąć. Bez niej MySQL nada nazwę automatycznie i trzeba ją będzie najpierw odczytać poleceniem SHOW CREATE TABLE. Jeśli w tabeli są już dane, które nie pasują do powiązania, baza nie pozwoli dodać klucza, dopóki ich nie poprawisz.
Typowe błędy przy kluczu obcym
- Zła kolejność tworzenia tabel. Najpierw musi istnieć tabela klienci, a dopiero potem zamowienia. Przy usuwaniu tabel kolejność jest odwrotna.
- Różne typy kolumn. Obie kolumny muszą mieć zgodny typ. INT i BIGINT albo INT i INT UNSIGNED nie będą ze sobą współpracować.
- Błąd 1452, „Cannot add or update a child row”. Próbujesz dodać zamówienie z numerem klienta, którego nie ma w tabeli klienci.
- Błąd 1451, „Cannot delete or update a parent row”. Próbujesz usunąć klienta, który ma zamówienia. Najpierw usuń zamówienia albo zmień regułę ON DELETE.
Jak użyć kluczy w zapytaniu
Same klucze nie łączą danych w wynikach. Do tego służy JOIN, który wskazuje, po których kolumnach dopasować wiersze:
SELECT z.id_zam, z.data_zam, k.imie
FROM zamowienia z
INNER JOIN klienci k ON z.id_klienta = k.id_klienta;Więcej przykładów łączenia tabel i filtrowania wyników znajdziesz w tekście zapytania SQL: przykłady. Tło teoretyczne, czyli czym różnią się bazy relacyjne od innych, opisaliśmy w artykule o rodzajach baz danych.
Najczęściej zadawane pytania o klucze w bazie danych
Klucz obcy w tabeli jest tworzony po to, aby co?
Aby zdefiniować relację z inną tabelą i zapewnić spójność danych, czyli uniemożliwić wskazanie wiersza, którego tam nie ma.
Czy klucz obcy może się powtarzać?
Tak. Jeden klient ma wiele zamówień, więc jego numer pojawia się w wielu wierszach tabeli zamówień.
Czy tabela może nie mieć klucza głównego?
Technicznie tak, ale to zły pomysł, bo trudno wtedy wskazać konkretny wiersz. W dobrze zaprojektowanej bazie każda tabela go ma.
Jak nadać klucz główny automatycznie?
W MySQL używa się AUTO_INCREMENT przy kolumnie liczbowej. Baza nadaje wtedy kolejne wartości przy dodawaniu wierszy.
Czym jest klucz złożony?
To klucz główny z kilku kolumn, stosowany na przykład w tabeli pośredniej, gdzie unikalna jest dopiero para wartości.
Stan na listopad 2026 r.

Pingback: Zapytania SQL przykłady - SELECT, JOIN, GROUP BY