Slovník pojmů

Cizí klíč

Sloupec pojmenovaný customer_id ještě není cizí klíč. Teprve databázový constraint zajistí, že odkaz ukazuje na existující řádek a má definované chování při změně.

Stručná definice

Platný odkaz mezi rodičovským a závislým záznamem.

Cizí klíč kontroluje, zda hodnota ve sloupci nebo kombinaci sloupců existuje jako vhodná identita v jiné tabulce. Položka objednávky tak nemůže odkazovat na objednávku, která neexistuje. Pravidlo funguje i mimo hlavní HTTP formulář, například při importu nebo souběžném zápisu.

Cizí klíč není ORM asociace ani autorizace. Doctrine může vztah namapovat do objektů, ale referenční integritu chrání databáze. Aplikace zase musí na serveru ověřit, zda konkrétní uživatel smí pracovat s danou objednávkou.

Jaký problém řeší

Vazby, které nesmějí mířit do prázdna

Cizí klíč vyjadřuje referenční vazbu a případně závislost interních dat v relačním modelu.

  • objednávka odkazuje na zákazníka
  • položka objednávky odkazuje na objednávku a produkt
  • spojovací tabulka propojuje produkt a kategorii
  • hierarchická tabulka odkazuje sama na sebe přes parent_id
  • mazání a změny respektují vědomě zvolenou referenční politiku

SQL ukázka

PostgreSQL: referenční integrita objednávky

Index product_id je zde explicitní kvůli dotazům a kontrole mazání produktu; jeho potřebu je nutné ověřit podle reálného provozu.

CREATE TABLE orders (
    id uuid PRIMARY KEY,
    customer_id uuid NOT NULL REFERENCES customers(id) ON DELETE RESTRICT
);

CREATE TABLE order_items (
    order_id uuid NOT NULL REFERENCES orders(id) ON DELETE CASCADE,
    product_id uuid NOT NULL REFERENCES products(id) ON DELETE RESTRICT,
    quantity integer NOT NULL,
    PRIMARY KEY (order_id, product_id)
);

CREATE INDEX order_items_product_id_idx ON order_items(product_id);

Jak funguje

Od rodiče k platné položce objednávky

Textová alternativa: položka je platná, pouze pokud její order_id ukazuje na existující objednávku podle zvolené politiky.

  1. Identita rodiče Tabulka orders má primární nebo jiný vhodný unikátní klíč.
  2. Odkazující sloupec order_items.order_id nese hodnotu, která má na řádek orders odkazovat.
  3. Kontrola databáze Při vložení a změně databáze ověří, že rodičovský řádek existuje.
  4. ON DELETE a ON UPDATE Při změně rodiče platí zvolená politika: RESTRICT, CASCADE, SET NULL nebo jiná podporovaná varianta.
  5. Commit platného stavu Transakce potvrdí vazbu jen v podobě, která splňuje pravidlo integrity.

Důležité pojmy

Odkaz, index a asociace nejsou synonyma.

Konkrétní akce při mazání je doménové rozhodnutí, nikoli výchozí technická volba.

Rodičovský a závislý řádek

Referencovaný neboli rodičovský řádek je cíl. Odkazující neboli závislý řádek nese hodnotu cizího klíče.

Povinný a volitelný vztah

NULL ve FK může vyjadřovat nepovinný vztah. Pokud rodič musí existovat, doplní se NOT NULL. NULL není odkaz na neexistující řádek.

ON DELETE a ON UPDATE

RESTRICT či NO ACTION změnu odmítne. CASCADE odstraní závislé záznamy, SET NULL vztah uvolní. Vhodnost záleží na významu dat.

Více ku více

Vztah produktů a kategorií drží spojovací tabulka se dvěma cizími klíči; stejné pravidlo platí pro jiné many-to-many vztahy.

Cizí klíč a index

PostgreSQL automaticky nevytváří index na odkazující straně FK. Potřebný index se navrhuje podle JOINů a mazání rodičů; jiné databáze se mohou lišit.

Vztah k podobným pojmům

Integrita v databázi, model v aplikaci.

Každá vrstva řeší jinou část vztahu mezi daty.

Primární klíč
Běžný cíl cizího klíče; určuje hlavní identitu referencovaného řádku.
Databázový index
Může podpořit čtení a kontrolu vazeb, ale sám nevynucuje platný vztah.
Doctrine ORM
Asociace je objektové mapování; databázový FK je nezávislá kontrola integrity.
Databázový constraint
FOREIGN KEY je jeden z constraintů, které databáze vyhodnocuje při zápisu.

Výhody a omezení

Referenční integrita zmenšuje prostor pro nekonzistentní data.

Přínosy

  • ochrana platných odkazů i při souběžných zápisech
  • jasná dokumentace vztahu mezi tabulkami
  • vědomé chování při mazání rodičovského záznamu
  • spolehlivější data pro JOINy, reporty a importy

Časté chyby

  • považování customer_id bez constraintu za chráněný vztah
  • předpoklad, že FK vždy automaticky vytvoří vhodný index
  • mechanické použití ON DELETE CASCADE
  • záměna FK za ORM asociaci nebo autorizaci
  • snaha vynutit stejný vztah přes hranici externího systému

Praktický příklad

Objednávka, položka a produkt

orders.customer_id odkazuje na customers.id. order_items.order_id odkazuje na orders.id a product_id na products.id. Pokud je položka skutečnou součástí objednávky, může pro její testovací smazání dávat CASCADE smysl; historický produkt se naopak často nemaže, aby nezanikl vztah k dokončeným objednávkám.

Cizí klíč nepovoluje libovolně mazat ani číst data v jiné organizaci. Tenantní kontext a oprávnění jsou samostatná business a bezpečnostní pravidla.

Na co myslet

Před mazáním si ověřte business význam závislosti.

Constraint chrání data, ale rozhodnutí o procesu mazání zůstává na návrhu aplikace.

  • použít NOT NULL, pokud vztah není volitelný
  • volit CASCADE jen pro skutečně závislá data
  • ověřit indexy na odkazující straně podle dotazů a objemu
  • nepřenášet referenční integritu externí služby jen do názvu sloupce
  • přeložit porušení constraintu na srozumitelnou aplikační chybu

Časté otázky

Cizí klíč v praxi

Vytvoří cizí klíč vždy index?

Ne. PostgreSQL indexuje cíl primárního či unikátního klíče, ale na odkazujících sloupcích FK vhodný index automaticky nevytváří. Jiné systémy mají jiné detaily.

Má každý customer_id být cizí klíč?

U interních tabulek s vlastněnými daty často ano. U externího ID může být zdroj pravdy v jiné službě, kde databáze lokální FK vynutit nemůže.

Kdy použít CASCADE?

Když závislý záznam bez rodiče nedává smysl a hromadné mazání je vědomě správné. Není to bezpečná výchozí volba pro historická data.

Nahrazuje FK validaci v aplikaci?

Ne. Aplikace může chybu vysvětlit a kontroluje business proces; databáze současně chrání invariant při souběhu a jiných cestách zápisu.

Jak tento princip používám v praxi

Vztahy mezi daty chráním i mimo aplikační formulář.

V e-commerce modelech řeším vazby objednávek, položek, produktů a integrací spolu s dopady na mazání, importy a výkon.

Zavolejte mi

Zavolám vám následující pracovní den mezi 9:00 a 17:00.

Můžete mi také zavolat rovnou.

+420 605 181 728

Nechte mi telefonní číslo a pošlete žádost o zpětné zavolání.

Odesláním souhlasíte se zpracováním údajů pro vyřízení žádosti.