V SQL vytvoříte vztah vytvořením omezení cizího klíče.
Přesněji řečeno, máte nadřazenou tabulku a podřízenou tabulku. Nadřazená tabulka obsahuje primární klíč a podřízená tabulka obsahuje cizí klíč, který odkazuje na primární klíč nadřazené tabulky.
Když k vytvoření vztahu použijete SQL, můžete vztah vytvořit při vytváření tabulky nebo jej můžete vytvořit později (změnou tabulky). Tento článek popisuje oba scénáře.
Vytvořte vztah při vytváření tabulky
Zde je příklad vytvoření vztahu v rámci CREATE TABLE
v okamžiku vytvoření tabulky.
CREATE TABLE Parent (
ParentId int IDENTITY(1,1) NOT NULL PRIMARY KEY,
ParentName nvarchar(255) NOT NULL
)
CREATE TABLE Child (
ChildId int IDENTITY(1,1) NOT NULL PRIMARY KEY,
ChildName nvarchar(255) NOT NULL,
ParentId int NOT NULL
CONSTRAINT FK_Child_Parent FOREIGN KEY (ParentId)
REFERENCES Parent (ParentId)
);
Zde jsem vytvořil dvě tabulky; jeden s názvem Parent
a druhý s názvem Child
.
Vytvořil jsem vztah v definici tabulky pro dítě. Vztah je vytvořen pomocí CONSTRAINT
argument. Všimněte si, že toto je stále uvnitř CREATE TABLE
prohlášení.
Vztah potřebuje jméno. V tomto případě jsem to nazval FK_Child_Parent
. FOREIGN KEY
část je následována názvem sloupce (v podřízené tabulce), který bude cizím klíčem.
REFERENCES
část určuje sloupec, na který bude cizí klíč odkazovat. V tomto případě odkazuje na ParentId
sloupec Parent
stůl. To se provádí pomocí REFERENCES Parent (ParentId)
.
To je vše, co je potřeba k vytvoření vztahu.
Všimněte si, že příklady na této stránce byly provedeny pomocí SQL Server. V závislosti na vašem DBMS možná budete muset změnit některé podrobnosti definic sloupců.
Například IDENTITY
je SQL Server verze toho, co se někdy nazývá AUTO_INCREMENT
v jiných DBMS (jako je MySQL). Pokud používáte SQLite, zde je návod, jak vytvořit sloupec s automatickým přírůstkem v SQLite.
Přidat vztah ke stávající tabulce
Můžete také přidat vztah k existující tabulce jednoduše pomocí ALTER TABLE
prohlášení.
Předstírejme, že jsme vztah nevytvořili při vytváření dvou tabulek z předchozího příkladu. Takže předstírejme, že jsme místo toho udělali toto:
CREATE TABLE Parent (
ParentId int IDENTITY(1,1) NOT NULL PRIMARY KEY,
ParentName nvarchar(255) NOT NULL
)
CREATE TABLE Child (
ChildId int IDENTITY(1,1) NOT NULL PRIMARY KEY,
ChildName nvarchar(255) NOT NULL,
ParentId int NOT NULL
);
Takže v tomto scénáři jsme udělali jen dvě tabulky. Nebyl mezi nimi vytvořen žádný vztah.
Nyní, po vytvoření tabulek, si najednou vzpomeneme:"Ach sakra, zapomněl jsem vytvořit vztah!"
Žádný problém, teď to můžeme udělat:
ALTER TABLE Child
ADD CONSTRAINT FK_Child_Parent FOREIGN KEY (ParentId)
REFERENCES Parent (ParentId);
Hotovo. Právě jsme přidali vztah pomocí stejných podrobností jako v předchozím příkladu.
Pamatujte, že SQLite nepodporuje přidávání cizích klíčů pomocí ALTER TABLE
prohlášení. Podívejte se, jak přidat cizí klíč do existující tabulky v SQLite, kde najdete další informace.
Při aktualizaci/smazání
Ve výchozím nastavení jsou vztahy serveru SQL vytvořeny pomocí ON DELETE NO ACTION
a ON UPDATE NO ACTION
. Proto byly předchozí příklady vytvořeny pomocí tohoto nastavení.
Různé DBMS však mohou používat jiná výchozí nastavení.
V každém případě to můžete ve svém kódu výslovně zadat. Takže můžeme upravit předchozí příklad, aby vypadal takto:
ALTER TABLE Child
ADD CONSTRAINT FK_Child_Parent FOREIGN KEY (ParentId)
REFERENCES Parent (ParentId)
ON DELETE NO ACTION
ON UPDATE NO ACTION;
To ve skutečnosti znamená, že pokud by se někdo pokusil odstranit nebo aktualizovat záznam v primárním klíči, došlo by k chybě a změna by byla vrácena zpět. Toto je způsob, jak SQL Server zabránit jakýmkoli změnám, které by mohly narušit referenční integritu vašeho systému.
V zásadě je důvodem, proč vytváříte vztah, především vynucení referenční integrity.
Máte však několik možností, jak chcete, aby SQL Server tyto situace řešil.
Konkrétně můžete použít kteroukoli z následujících hodnot:
NO ACTION
:Vyvolá se chyba a akce odstranění/aktualizace na řádku v nadřazené tabulce bude vrácena zpět.CASCADE
:Odpovídající řádky jsou odstraněny z/aktualizovány v referenční tabulce, pokud je tento řádek odstraněn/aktualizován v nadřazené tabulce.SET NULL
:Všechny hodnoty, které tvoří cizí klíč, jsou nastaveny naNULL
pokud je odpovídající řádek v nadřazené tabulce odstraněn nebo aktualizován. To vyžaduje, aby sloupce cizího klíče měly hodnotu null.SET DEFAULT
:Všechny hodnoty, které tvoří cizí klíč, jsou nastaveny na výchozí hodnoty, pokud je odpovídající řádek v nadřazené tabulce odstraněn nebo aktualizován. Aby se toto omezení provedlo, musí mít všechny sloupce cizího klíče výchozí definice. Pokud má sloupec hodnotu null a není nastavena žádná explicitní výchozí hodnota,NULL
se stane implicitní výchozí hodnotou sloupce.