sql >> Databáze >  >> RDS >> Database

OMEZENÍ ZAHRANIČNÍHO KLÍČE SQL:Konečný, snadný průvodce pro nováčky

Nováček? Potom pro vás může být cizí klíč SQL cizí.

Možná jste slyšeli různé názory na cizí klíče SQL. Pokud ne, brzy to uděláte. Nebo vaše zkušenost ovlivní váš pohled. Hlavní věc, kterou byste měli vědět, je, že cizí klíče jsou v relačních databázích nutností.

Přesto mohou někteří vývojáři cizí klíče odstranit nebo ignorovat, když čelí nějakým komplikacím. Tak co dělat? Používat cizí klíč nebo ho nepoužívat? Nastanou chvíle, kdy je nebudete potřebovat?

Tato příručka je pro vás, abyste viděli, jak důležitá je tato věc. Budete také znát některé chyby v kódu a naučíte se, jak je opravit. Kromě toho samozřejmě použijeme praktické příklady. Není nic, co byste nezvládli.

Co je cizí klíč SQL?

Pěkně popořádku. Co je cizí klíč v SQL? V několika slovech je to klíč, který spojuje 2 tabulky. Řekněme, že máte nadřazený stůl a podřízený stůl. Existuje určitá podobnost, která z nich dělá rodiče a dítě – klíč, který tyto 2 tabulky spojuje.

V SQL databázích se však cizí klíč netýká pouze tabulek. Posiluje vztah. Proto se tomu říká omezení cizího klíče.

Pokud se pokusíte přidat podřízený záznam s hodnotou cizího klíče, která neexistuje v primárních klíčích nadřazené tabulky, dojde k chybě. Později uvidíme ukázky kódu, které to ilustrují.

Které tabulky by měly mít omezení cizího klíče SQL?

Dětské stoly mohou mít cizí klíče. Jeden cizí klíč může odkazovat na jinou tabulku. V „dítě“ tabulce může být také několik cizích klíčů. V SQL Server může cizí klíč odkazovat na primární klíč nebo jedinečný klíč v jiné tabulce.

Co třeba sebereference?

To se vymyká obecné definici cizího klíče. sebe reference znamená, že můžete přiřadit cizí klíč, který odkazuje jiný sloupec ve stejné tabulce . SQL Server, MySQL a Oracle to podporují.

Vlastní reference je použitelná, když chcete vytvořit hierarchie, jako je vztah manažer-zaměstnanec. Je povoleno, ale většina implementací cizích klíčů je mezi 2 tabulkami.

Později budeme mít příklady.

4 výhody používání cizích klíčů SQL

Podívejme se podrobně na primární klíč a cizí klíč v SQL. Co dělá cizí klíče nutností pro SQL databázi? Prozkoumejme 4 body (zde na syntaxi omezení nezáleží).

1. Vyhněte se „chybějícím“ datům

„Chybí“ data jsou hodnoty cizích klíčů z podřízených tabulek bez přiřazených hodnot primárního klíče z nadřazené tabulky. Jsou také označovány jako osiřelé řádky. Když k tomu dojde, můžeme říci, že databáze má malou nebo žádnou referenční integritu.

S vynucenými omezeními cizího klíče se „chybějící“ data vůbec nestanou. Databázový stroj nepovolí odstranění hodnoty primárního klíče, na kterou odkazuje jiná tabulka. Podobně vložení cizího klíče do podřízené tabulky, který v primárních klíčích nadřazené tabulky neexistuje, způsobí chybu.

Jaká nejhorší věc se může stát, pokud nepoužíváte omezení cizího klíče? Zde je několik:

  • Zákazníci neobdrží produkty, za které zaplatili.
  • Léčba není podávána pacientům.
  • Chybějící kontrolní seznamy přeskakují bezpečnostní opatření.

S těmito věcmi můžete pracovat mimo databázi, ale musíte to kódovat. Více o tom bude následovat.

Řekněme, že vývojář ve vaší organizaci řešil stejné omezení mimo databázi. Bude zodpovědný a opraví problém ve výrobě, pokud kód selže? Myslím, že ne. A co když jste správce databáze? Pak budete muset uklidit jejich nepořádek. Není to tak povzbudivé, když se mě ptáte.

2. Vyhněte se nekonzistentním přehledům

Souvisí to s prvním bodem. Pokud některá data „chybějí“, v různých přehledech se objevují nekonzistentní součty. Podrobnosti neodpovídají souhrnům. Osamocené řádky se sečtou k součtu souhrnů. Mezitím podrobná zpráva nezachytila ​​osamocené řádky kvůli vnitřnímu spojení s nadřazenými tabulkami.

Pokud je vaším úkolem udržovat databázi v dobrém stavu, vyčistíte i tento nepořádek.

3. Není potřeba žádný kód, abyste se vyhnuli osiřelým řádkům

Omezení cizího klíče působí jako samočistící prostředky. Místo toho, abyste vyčistili nepořádek, databáze to udělá tak, že nepovolí osamocené řádky. Omezení cizího klíče působí také jako policie. Zatknou chybnou logiku, která způsobuje osiřelé řádky, a považují ji za zločin spáchaný mimo databázi.

Chcete lesklou databázi bez osiřelých řádků? Samozřejmě, že ano. Pokud budete chtít data někdy analyzovat, budete rádi, že jste použili cizí klíče. Tato databáze bude dobrým zdrojem pro kopírování potřebných dat do vaší pracovní oblasti.

4. Rychle pochopte vztahy mezi tabulkami v diagramu

SQL Server Management Studio má vestavěný nástroj pro vytváření diagramů pro vaši databázi. Primární a cizí klíče činí diagram databáze informativní na první pohled. Bude však záležet na tom, kolik tabulek se vztahy jste do diagramu zahrnuli.

Diagramy pomáhají novým členům týmu porozumět struktuře dat. Pro starší spoluhráče to může být užitečné také jako dokumentace.

Když cizí klíč SQL může být „problémem“ (plus oprava)

Pro migraci starých dat do nové databáze budete vkládat záznamy hromadně. Pokud má zdrojová databáze nízkou referenční integritu, bude obtížné vkládat záznamy ze zdroje. Důvodem je to, že chyby cizího klíče se objevují sem a tam.

Existuje nějaká oprava? Máte 2 možnosti.

  1. Ujistěte se, že jste nejprve naplnili referenční tabulky nebo nadřazené tabulky. Poté naplňte podřízené tabulky. Jedna komplikace běží velmi pomalu. V ostatních případech se vyskytuje více chyb omezení cizího klíče. Pokud nastane druhý případ, musíte přehodnotit pořadí vkládání a zajistit, aby byly primární klíče vloženy jako první. Pokud se vyskytne problém s „pomalým chodem“, zvažte další možnost.
  2. Dočasně cizí klíče zakažte a povolte je po dokončení migrace (a vyčištění). Můžete to udělat v SQL Server Management Studio nebo použít T-SQL ALTER TABLE. Nicméně, to se snadněji řekne, než udělá. V tuto chvíli potřebujete kromě důvtipu a vůle i více trpělivosti. Později najdeme syntaxi pro deaktivaci a opětovné povolení cizích klíčů.

Další věcí, kterou je třeba zvážit, je použití databáze jako pracovní oblasti pro OLAP nebo analýzu dat. Předpokládejme, že zdrojová transakční databáze neobsahuje osamocené řádky. Nebo se můžete těmto řádkům vyhnout pomocí kódu. Poté se můžete rozhodnout nepoužívat cizí klíče. Cizí klíče zpomalí hromadné vkládání a aktualizace, zejména u obrovských datových sad.

3 snadné způsoby, jak přidat, upravit a odstranit omezení cizího klíče SQL

Co je potřeba k přidání, úpravě nebo odstranění cizích klíčů? S těmito 3 tipy je to snadné.

První dva kroky využívají grafické uživatelské rozhraní. Nástroje jako SQL Server Management Studio nebo dbForge Studio pro SQL Server jsou velmi dobrými kandidáty. Třetí bude používat T-SQL kód. Výběr kódu GUI nebo T-SQL závisí na situaci.

1. Použití nástroje Table Designer k přidání, úpravě a odstranění omezení cizího klíče SQL

V SQL je možné přidat omezení cizího klíče při vytváření nebo změně struktury tabulky pomocí Návrháře tabulek v SSMS. Obrázek 1 níže ukazuje, jak k němu přistupovat z hlavní nabídky, když je otevřená struktura tabulky.

Další možností je kliknout pravým tlačítkem kdekoli v návrháři tabulky a vybrat Vztahy z kontextové nabídky:

Jakmile vyberete Vztahy , zahraniční klíčové vztahy objeví se okno:

V zahraničních klíčových vztazích můžete přidat nový cizí klíč nebo upravit/smazat existující.

Pokud se rozhodnete přidat nebo upravit, kliknutím rozbalte Tabulky a sloupce Specifikace. Poté klikněte na elipsu pro definování nebo úpravu tabulky primárního a cizího klíče.

Odtud můžete označit sloupce primárního a cizího klíče.

Po definování primárního a cizího klíče klikněte na OK . Poté přejděte zpět do návrháře tabulky a uložte změny.

2. Použití databázového diagramu k přidání, úpravě a odstranění omezení cizího klíče SQL

Diagram databáze můžete použít k vytvoření omezení cizího klíče SQL. Obrázek 5 ukazuje, jak vytvořit vztah mezi dvěma tabulkami kliknutím na tabulku cizího klíče a přetažením do tabulky primárního klíče.

Po uvolnění myši se zobrazí Tabulky a sloupce Zobrazí se okno jako na obrázku 4. Poté můžete označit sloupce primárního a cizího klíče. Poté klikněte na OK.

Chcete-li upravit existující vztah, klikněte pravým tlačítkem na vztah v diagramu. Poté vyberte Vlastnosti :

Poté v části Vlastnosti v okně rozbalte Tabulky a sloupce a klikněte na elipsu tlačítko:

Po kliknutí na elipsu tlačítko Tabulky a sloupce objeví se okno. Sloupce primárního a cizího klíče můžete změnit (opět se podívejte na obrázek 4 výše).

Mezitím smazání vztahu vyžaduje klepnutí pravým tlačítkem na existující vztah. Vyberte Odstranit vztahy z databáze a klikněte na Ano až budete vyzváni.

3. Použití T-SQL k přidání, úpravě a odstranění omezení cizího klíče SQL

Třetí způsob, jak přidat cizí klíč, je prostřednictvím kódu T-SQL. Můžete použít SQL CREATE TABLE a přidat omezení cizího klíče. Nebo můžete také použít ALTER TABLE k přidání tohoto omezení po vytvoření tabulky.

Zde je syntaxe pro použití CREATE TABLE:

-- Single-column foreign key
CREATE TABLE Table2
(ID INT IDENTITY(1,1) NOT NULL PRIMARY KEY CLUSTERED,
 col1 INT NULL REFERENCES Table1(col1)
)
GO

Po definování názvu a typu sloupce můžete přidat REFERENCE do tabulky a sloupce. Výše uvedená syntaxe zobrazuje Tabulku1 tabulce na col1 sloupec. Všimněte si, že názvy sloupců v obou tabulkách musí být stejné, aby byly platné pro cizí klíče.

Výše uvedená syntaxe je pro cizí klíče s jedním sloupcem. Pokud potřebujete více sloupců jako cizí klíče, použijte klauzuli FOREIGN KEY, jak je uvedeno níže:

-- Multiple-column foreign key
CREATE TABLE Table2
(ID INT IDENTITY(1,1) NOT NULL PRIMARY KEY CLUSTERED,
 col1 INT NOT NULL,
 col2 INT NOT NULL,
 col3 VARCHAR(10) NULL
 CONSTRAINT FK_Table1_Table2 FOREIGN KEY(col1, col2)
	REFERENCES Table1(col1,col2)
)
GO

Po vytvoření tabulky můžete přidat cizí klíče pomocí ALTER TABLE. Zde je syntaxe:

ALTER TABLE Table2 WITH CHECK ADD CONSTRAINT FK_Table1_Table2_2 FOREIGN KEY(col3)
	REFERENCES Table3(col1)
GO

Chcete-li odstranit omezení cizího klíče, můžete použít ALTER TABLE s DROP CONSTRAINT:

ALTER TABLE Table2 
DROP CONSTRAINT FK_Table1_Table2_2
GO

Nyní můžeme shrnout 3 způsoby, jak přidat, upravit a odstranit cizí klíče:

Příklady omezení cizího klíče SQL (MySQL)

Podřízený stůl s 1 odkazem na nadřazený stůl

-- Single Reference
CREATE TABLE [dbo].[Countries](
	[CountryID] [int] IDENTITY(1,1) NOT NULL,
	[Country] [nvarchar](50) NOT NULL,
	[ContinentID] [int] NULL,
	[Modified] [datetime] NOT NULL,
 CONSTRAINT [PK_Country] PRIMARY KEY CLUSTERED 
(
	[CountryID] ASC
))
GO

ALTER TABLE [dbo].[Countries]  WITH CHECK ADD CONSTRAINT [FK_Countries_Continent] FOREIGN KEY([ContinentID])
REFERENCES [dbo].[Continent] ([ContinentID])

GO

ALTER TABLE [dbo].[Countries] CHECK CONSTRAINT [FK_Countries_Continent]
GO

Chcete-li si tento vztah představit, podívejte se na obrázek 9 níže:

ContinentID je klíč, který spojuje obě tabulky dohromady.

Dětská tabulka s více odkazy

Sportovní vůz tabulka má více odkazů na tři různé tabulky:

-- Multiple References
CREATE TABLE [dbo].[SportsCars](
	[SportsCarID] [int] IDENTITY(1,1) NOT NULL,
	[ManufacturerID] [int] NULL,
	[StyleID] [int] NULL,
	[CountryID] [int] NULL,
	[Model] [nvarchar](50) NOT NULL,
	[Years] [varchar](50) NOT NULL,
	[Notes] [varchar](255) NOT NULL,
	[Modified] [datetime] NOT NULL,
 CONSTRAINT [PK_SportsCars] PRIMARY KEY CLUSTERED 
(
	[SportsCarID] ASC
))
GO

ALTER TABLE [dbo].[SportsCars] WITH CHECK ADD CONSTRAINT [FK_SportsCars_Country] FOREIGN KEY([CountryID])
REFERENCES [dbo].[Countries] ([CountryID])
GO

ALTER TABLE [dbo].[SportsCars] CHECK CONSTRAINT [FK_SportsCars_Country]
GO

ALTER TABLE [dbo].[SportsCars] WITH CHECK ADD CONSTRAINT [FK_SportsCars_Manufacturer] FOREIGN KEY([ManufacturerID])
REFERENCES [dbo].[Manufacturers] ([ManufacturerID])
GO

ALTER TABLE [dbo].[SportsCars] CHECK CONSTRAINT [FK_SportsCars_Manufacturer]
GO

ALTER TABLE [dbo].[SportsCars] WITH CHECK ADD CONSTRAINT [FK_SportsCars_Styles] FOREIGN KEY([StyleID])
REFERENCES [dbo].[Styles] ([StyleID])
GO

ALTER TABLE [dbo].[SportsCars] CHECK CONSTRAINT [FK_SportsCars_Styles]
GO

V databázovém diagramu se zobrazí takto:

Vlastní reference

Hierarchie pozic ukazují vlastní odkaz v následující tabulce:

CREATE TABLE [dbo].[Ranks](
	[RankId] [int] IDENTITY(1,1) NOT NULL,
	[Rank] [varchar](50) NOT NULL,
	[RankLevel] [smallint] NOT NULL,
	[RankParentId] [int] NULL,
 CONSTRAINT [PK_Ranks] PRIMARY KEY CLUSTERED 
(
	[RankId] ASC
)) ON [PRIMARY]
GO

ALTER TABLE [dbo].[Ranks] WITH CHECK ADD CONSTRAINT [FK_Ranks_Ranks] FOREIGN KEY([RankParentId])
REFERENCES [dbo].[Ranks] ([RankId])
GO

ALTER TABLE [dbo].[Ranks] CHECK CONSTRAINT [FK_Ranks_Ranks]
GO

Schéma této sebereference je jednoduché. Čára ukazuje na stejnou tabulku v samostatném odkazu.

S ON UPDATE a ON DELETE

S ON UPDATE CASCADE aktualizujete hodnotu sloupce primárního klíče také s hodnotami cizího klíče v souvisejících tabulkách. Mezitím, když použijete ON DELETE CASCADE, smazáním primárního klíče se odstraní i cizí klíče. Výchozí nastavení pro ON UPDATE a ON DELETE je NO ACTION.

Zde je příklad UPDATE and DELETE CASCADE:

ALTER TABLE [dbo].[Countries] WITH CHECK ADD CONSTRAINT [FK_Countries_Continent] FOREIGN KEY([ContinentID])
REFERENCES [dbo].[Continent] ([ContinentID]) 
ON UPDATE CASCADE 
ON DELETE CASCADE
GO

Zakázání omezení cizího klíče SQL

Následující deaktivuje existující omezení cizího klíče. Všimněte si, že vztah stále existuje.

ALTER TABLE [dbo].[SportsCars] NOCHECK CONSTRAINT [FK_SportsCars_Country]
GO

Toto není výchozí nastavení a nedoporučuje se. Chcete-li však urychlit hromadné vkládání a aktualizace, můžete dočasně zakázat cizí klíč, jako je ten výše. Až budete hotovi, musíte jej přepnout zpět pomocí CHECK CONSTRAINT.

ALTER TABLE [dbo].[SportsCars] CHECK CONSTRAINT [FK_SportsCars_Country]
GO

Mám problémy a opravy

Tato část vám ukáže, co se stane, když INSERT, UPDATE nebo DELETE záznamy s cizími klíči. To také předpokládá, že cizí klíče nejsou zakázány s NOCHECK CONSTRAINT. To vám pomůže, když narazíte na tyto běžné problémy.

Na INSERT

-- This will cause an error because countryID = 47 does not exist in the Countries table
INSERT INTO SportsCars 
(ManufacturerID, StyleID, CountryID, Model, Years, Notes) 
VALUES (108, 10, 47, 'F2', '2021', 'Limited Edition')
GO

Zde je chybová zpráva:

Msg 547, Level 16, State 0, Line 56
The INSERT statement conflicted with the FOREIGN KEY constraint "FK_SportsCars_Country". The conflict occurred in database "Vehicles", table "dbo.Countries", column 'CountryID'.
The statement has been terminated.

Oprava :Přidejte ID země =47 do zemí nejprve stůl. Potom znovu spusťte výše uvedený příkaz INSERT. Sekvence začíná vložením záznamů do nadřazené tabulky a poté do podřízené tabulky.

V AKTUALIZACI

-- Update CountryID to 47 will trigger an error.
UPDATE SportsCars
SET CountryID = 47
WHERE ManufacturerID = 108
GO

Zde je chyba UPDATE:

Msg 547, Level 16, State 0, Line 60
The UPDATE statement conflicted with the FOREIGN KEY constraint "FK_SportsCars_Country". The conflict occurred in database "Vehicles", table "dbo.Countries", column 'CountryID'.
The statement has been terminated.

Oprava :Přidejte ID země =47 do zemí stůl. Potom znovu spusťte příkaz UPDATE.

Na DELETE

-- This will trigger an error because ManufacturerID = 108 is referenced in the SportsCars table
DELETE FROM Manufacturers
WHERE ManufacturerID = 108

Tento kód spustí chybu jako níže:

Msg 547, Level 16, State 0, Line 64
The DELETE statement conflicted with the REFERENCE constraint "FK_SportsCars_Manufacturer". The conflict occurred in database "Vehicles", table "dbo.SportsCars", column 'ManufacturerID'.
The statement has been terminated.

Oprava :Odstraňte odpovídající záznamy ze SportsCars tabulka s ID výrobce =108. Potom znovu spusťte výše uvedený příkaz DELETE. Dalším způsobem je povolit ON DELETE CASCADE, pokud je to možné. Sekvence začíná odstraněním záznamů z podřízených tabulek a poté – z nadřazené tabulky.

Takové věci

Takže, jsou vám cizí klíče stále cizí?

Pojďme si shrnout, co jsme se zatím naučili.

  • Cizí klíče propojují dvě tabulky (nebo jednu tabulku při použití vlastního odkazu). Potřebujete je k zajištění referenční integrity.
  • K přidání, úpravě nebo odstranění omezení cizího klíče můžete použít nástroj GUI nebo T-SQL.
  • Pro nástroje GUI můžete použít SQL Server Management Studio nebo dbForge Studio pro SQL Server. Oba nabízejí databázové diagramy a návrháře tabulek pro vytváření tabulek s primárními a cizími klíči.
  • CREATE TABLE a ALTER TABLE jsou vhodné pro přidávání a odstraňování omezení cizího klíče.
  • Cizí klíče můžete dočasně zakázat pomocí NOCHECK CONSTRAINT v ALTER TABLE. To urychlí hromadné vkládání a aktualizace. Nezapomeňte ji však znovu povolit pomocí CHECK CONSTRAINT.
  • Chcete-li se vyhnout problémům s cizími klíči, dodržujte správné pořadí. Pro INSERT a UPDATE vložte nejprve do nadřazené tabulky, poté do podřízených tabulek. Chcete-li DELETE, odstraňte nejprve podřízené záznamy a poté nadřazené záznamy.

Chtěli byste přidat něco, co pomůže nováčkům zvládnout cizí klíče? Komentáře sekce je otevřena pro vaše chytré nápady. Pokud se vám tento příspěvek líbí, sdílejte jej na svých oblíbených platformách sociálních médií.


  1. SQL:Získejte záznamy vytvořené v časovém rozsahu pro konkrétní data

  2. Jak nainstalovat InfluxDB na Ubuntu 20.10

  3. Jak vytvořit tabulku pomocí databáze sqlite v Androidu?

  4. Instalace SQL Server Failover Cluster -2