Megosztás a következőn keresztül:


Elsődleges és idegenkulcs-korlátozások

Vonatkozik a következőkre: SQL Server 2016 (13.x) és későbbi verziók Azure SQL DatabaseAzure SQL Managed InstanceSQL database in Microsoft Fabric

Az elsődleges kulcsok és az idegen kulcsok kétféle kényszert jelentenek, amelyek az SQL Server-táblák adatintegritásának kikényszerítésére használhatók. Ezek fontos adatbázis-objektumok.

Elsődleges kulcskorlátozások

A táblák általában olyan oszlopokat vagy oszlopkombinációkat tartalmaznak, amelyek olyan értékeket tartalmaznak, amelyek egyedileg azonosítják a táblázat egyes sorait. Ezt az oszlopot vagy oszlopot a tábla elsődleges kulcsának (PK) nevezzük, és kikényszeríti a tábla entitásintegritását. Mivel az elsődleges kulcsok korlátozásai egyedi adatokat garantálnak, gyakran definiálva vannak egy identitásoszlopon.

Amikor egy tábla elsődleges kulcskorlátozását adja meg, az adatbázismotor az adatok egyediségét kényszeríti ki azáltal, hogy automatikusan létrehoz egy egyedi indexet az elsődleges kulcsoszlopokhoz. Ez az index gyors hozzáférést biztosít az adatokhoz, ha az elsődleges kulcsot a lekérdezésekben használják. Ha egy elsődleges kulcsra vonatkozó korlátozás több oszlopon van meghatározva, az értékek egy oszlopon belül duplikálhatók, de az elsődleges kulcs korlátozásának definíciójában szereplő összes oszlop értékeinek egyedinek kell lenniük.

Az alábbi ábrán látható módon a ProductID tábla VendorID és Purchasing.ProductVendor oszlopai összetett elsődlegeskulcs-kényszert alkotnak ehhez a táblához. Ez biztosítja, hogy a ProductVendor táblázat minden sora egyedi ProductID és VendorIDkombinációjával rendelkezik. Ez megakadályozza az ismétlődő sorok beszúrását.

Táblázat sorainak diagramja összetett ELSŐDLEGES KULCS kényszerhez.

  • A táblák csak egy elsődleges kulcskorlátot tartalmazhatnak.
  • Az elsődleges kulcsok száma nem haladhatja meg a 32 oszlopot, és a kulcs teljes hossza 900 bájt.
  • Az elsődleges kulcskorlátozás által létrehozott index nem okozhatja, hogy a táblában lévő indexek száma meghaladja a 999 nem fürtözött indexet és 1 klaszterezett indexet.
  • Ha nincs megadva fürtözött vagy nem konklúziós érték az elsődleges kulcsra vonatkozó korlátozáshoz, akkor a rendszer fürtözött indexet használ, ha nincs fürtözött index a táblában.
  • Az elsődleges kulcs kényszerében definiált összes oszlopot nem null értékként kell definiálni. Ha nincs kifejezetten megadva a nullképesség, akkor az elsődleges kulcs kényszerben részt vevő összes oszlop nullképessége nem engedélyezett.
  • Ha egy felhasználó által definiált CLR-típusoszlopon elsődleges kulcs van definiálva, a típus implementálásának támogatnia kell a bináris rendezést.

Idegenkulcs-korlátozások

Az idegen kulcs (FK) olyan oszlop vagy oszlopkombináció, amely két táblában lévő adatok közötti kapcsolat létrehozására és kényszerítésére szolgál az idegenkulcs-táblában tárolható adatok szabályozásához. Idegenkulcs-hivatkozásban két tábla között jön létre hivatkozás, ha az egyik tábla elsődleges kulcsértékét tartalmazó oszlopra vagy oszlopokra egy másik tábla oszlopa vagy oszlopai hivatkoznak. Ez az oszlop idegen kulcs lesz a második táblában.

A Sales.SalesOrderHeader tábla például egy idegenkulcs-hivatkozással rendelkezik a Sales.SalesPerson táblához, mert logikai kapcsolat áll fenn az értékesítési rendelések és az értékesítők között. A SalesPersonID tábla SalesOrderHeader oszlopa megegyezik a SalesPerson tábla elsődleges kulcsoszlopával. A SalesPersonID tábla SalesOrderHeader oszlopa a SalesPerson tábla idegen kulcsa. Ennek az idegenkulcs-kapcsolatnak a létrehozásával a SalesPersonID értéke nem szúrható be a SalesOrderHeader táblába, ha még nem létezik a SalesPerson táblában.

Egy tábla legfeljebb 253 másik táblára és oszlopra hivatkozhat idegen kulcsként (kimenő hivatkozásokként). Az SQL Server 2016 (13.x) 253-ról 10 000-re növeli azon táblák és oszlopok számát, amelyek egyetlen tábla oszlopaira hivatkozhatnak (bejövő hivatkozások). (Legalább 130 kompatibilitási szintet igényel.) A növekedés a következő korlátozásokkal rendelkezik:

  • 253-nál több idegenkulcs-hivatkozás csak DELETE DML-műveletek esetén támogatott. UPDATE és MERGE műveletek nem támogatottak.

  • Az idegenkulcs-hivatkozással rendelkező táblák továbbra is 253 idegenkulcs-hivatkozásra korlátozódnak.

  • Jelenleg több mint 253 idegenkulcs-hivatkozás nem érhető el oszlopcentrikus indexekhez, memóriaoptimalizált táblákhoz, Stretch Database-hez vagy particionált idegenkulcs-táblákhoz.

    Important

    A Stretch Database elavult az SQL Server 2022 -ben (16.x) és az Azure SQL Database-ben. Ez a funkció az adatbázismotor egy későbbi verziójában lesz eltávolítva. Ne használja ezt a funkciót az új fejlesztési munkában, és tervezze meg a funkciót jelenleg használó alkalmazások módosítását.

Indexek idegenkulcs-korlátozásokhoz

Az elsődleges kulcskényszerekkel ellentétben az idegen kulcs kényszerének létrehozása nem hoz létre automatikusan megfelelő indexet. Az index manuális létrehozása egy idegen kulcson azonban gyakran az alábbi okokból hasznos:

  • Az illesztési feltételekben gyakran használják az idegenkulcs-oszlopokat, ha a kapcsolódó táblák adatait lekérdezésekben kombinálják úgy, hogy az egyik tábla idegenkulcs-korlátozásában szereplő oszlopot vagy oszlopokat egyezik meg a másik tábla elsődleges vagy egyedi kulcsoszlopával vagy oszlopaival. Az index lehetővé teszi, hogy az adatbázismotor gyorsan megtalálja a kapcsolódó adatokat a külső kulcstáblában. Az index létrehozása azonban nem szükséges. Két kapcsolódó táblából származó adatok akkor is kombinálhatók, ha nem határoznak meg elsődleges kulcsot vagy idegenkulcs-korlátozásokat a táblák között, de a két tábla közötti idegenkulcs-kapcsolat azt jelzi, hogy a két tábla össze lett optimalizálva egy olyan lekérdezésben, amely a kulcsokat használja feltételként.

  • Az elsődleges kulcskorlátozások módosításait a kapcsolódó táblák idegenkulcs-korlátozásokkal ellenőrzik.

Hivatkozási integritás

Bár az idegenkulcs-korlátozás fő célja az idegenkulcs-táblában tárolható adatok szabályozása, az elsődleges kulcstáblában lévő adatok módosítását is szabályozza. Ha például egy értékesítő sorát törli a Sales.SalesPerson táblából, és az értékesítő azonosítója a Sales.SalesOrderHeader táblában lévő értékesítési rendelésekhez használatos, a két tábla közötti relációs integritás megszakad; a törölt értékesítő értékesítési rendelései árvaként jelennek meg a SalesOrderHeader táblában, a SalesPerson tábla adataira mutató hivatkozás nélkül.

Egy idegenkulcs-korlátozás megakadályozza ezt a helyzetet. A kényszer kényszeríti a hivatkozási integritást, mert garantálja, hogy az elsődleges kulcstáblában lévő adatokon nem lehet módosításokat végrehajtani, ha ezek a módosítások érvényteleníti az idegenkulcs-táblában lévő adatokra mutató hivatkozást. Ha egy elsődleges kulcstáblában lévő sor törlésére vagy egy elsődleges kulcs értékének módosítására irányuló kísérlet történik, a művelet meghiúsul, ha a törölt vagy módosított elsődleges kulcs értéke egy másik tábla idegenkulcs-korlátozásában szereplő értéknek felel meg. Ha egy sor sikeres módosításához vagy törléséhez idegenkulcs-korlátozást szeretne használni, először törölnie kell az idegenkulcs-táblában lévő idegenkulcs-adatokat, vagy módosítania kell az idegenkulcs-táblában lévő idegenkulcs-adatokat, amelyek az idegen kulcsot különböző elsődleges kulcsadatokhoz kapcsolják.

Kaszkádolt hivatkozási integritás

Kaszkádolt hivatkozási integritási korlátozások használatával meghatározhatja, hogy az adatbázismotor milyen műveleteket hajt végre, amikor egy felhasználó törölni vagy frissíteni próbál egy olyan kulcsot, amelyre a meglévő idegen kulcsok pontot mutatnak. Az alábbi kaszkádolt műveletek definiálhatók.

  • NO ACTION

    Az adatbázismotor hibát jelez, és a szülőtábla sorának törlési vagy frissítési művelete vissza lesz állítva.

  • CASCADE

    A megfelelő sorok frissülnek vagy törölve lesznek a hivatkozó táblában, amikor az adott sor frissül vagy törölve van a szülőtáblában. CASCADE nem adható meg abban az esetben, ha egy időbélyeg oszlop az idegen kulcs vagy a hivatkozott kulcs része. ON DELETE CASCADE nem adható meg INSTEAD OF DELETE eseményindítóval rendelkező táblához. ON UPDATE CASCADE nem adható meg olyan táblákhoz, amelyek INSTEAD OF UPDATE eseményindítókkal rendelkeznek.

  • SET NULL

    Az idegen kulcsot alkotó összes értéket NULL-ra állítják, amikor a szülőtábla megfelelő sorát frissítik vagy törlik. A kényszer végrehajtásához az idegen kulcs oszlopainak null értékűnek kell lenniük. Nem adható meg olyan táblákhoz, amelyek INSTEAD OF UPDATE eseményindítókkal rendelkeznek.

  • SET DEFAULT

    Az idegen kulcsot alkotó összes érték az alapértelmezett értékre van állítva, ha a szülőtábla megfelelő sorát frissíti vagy törli. A kényszer végrehajtásához az összes idegenkulcs-oszlopnak alapértelmezett definíciókkal kell rendelkeznie. Ha egy oszlop null értékű, és nincs megadva explicit alapértelmezett érték, NULL lesz az oszlop implicit alapértelmezett értéke. Nem adható meg olyan táblákhoz, amelyek INSTEAD OF UPDATE eseményindítókkal rendelkeznek.

CASCADE, SET NULL, SET DEFAULTés NO ACTION olyan táblákon kombinálhatók, amelyek hivatkozási kapcsolatban vannak egymással. Ha az adatbázismotor találkozik NO ACTION, akkor leállítja és visszavonja a kapcsolódó CASCADE, SET NULLés SET DEFAULT műveleteket. Ha egy DELETE utasítás CASCADE, SET NULL, SET DEFAULTvagy NO ACTION művelet kombinációját eredményezi , az adatbázismotor minden CASCADEellenőrzése előtt alkalmazza az összes SET NULL, SET DEFAULTés NO ACTION műveletet .

Eseményindítók és kaszkádolt hivatkozási műveletek

A kaszkádolt hivatkozási műveletek a következő módon aktiválják a AFTER UPDATE vagy AFTER DELETE eseményindítókat:

  • Először az eredeti DELETE vagy UPDATE által közvetlenül okozott kaszkádolt hivatkozási műveleteket hajtja végre.

  • Ha az érintett táblákban AFTER eseményindítók vannak definiálva, ezek az eseményindítók az összes kaszkádolt művelet végrehajtása után aktiválódnak. Ezek a triggerek ellentétes sorrendben lépnek működésbe, mint a kaszkád művelete. Ha egy táblán több eseményindító is található, véletlenszerű sorrendben aktiválódnak, hacsak nincs dedikált első vagy utolsó eseményindító a táblához. Ez a sorrend a sp_settriggerorderhasználatával van megadva.

  • Ha több kaszkádolt lánc származik abból a táblából, amely egy UPDATE vagy DELETE művelet közvetlen célpontja volt, az a sorrend, amelyben ezek a láncok aktiválják a megfelelő eseményindítókat, meghatározatlan. Azonban az egyik lánc mindig aktiválja az összes eseményindítóját, mielőtt egy másik lánc tüzelésbe kezd.

  • A AFTER vagy UPDATE művelet közvetlen céljaként szolgáló táblán lévő DELETE eseményindító attól függetlenül aktiválódik, hogy a sorok érintettek-e. Ebben az esetben a kaszkádolás nem érint más táblákat.

  • Ha az előző eseményindítók bármelyike más táblákon hajt végre UPDATE vagy DELETE műveleteket, ezek a műveletek másodlagos kaszkádolt láncokat indíthatnak el. Ezeket a másodlagos láncokat minden egyes UPDATE vagy DELETE művelethez külön dolgozzuk fel, miután az összes elsődleges lánc aktiválódott. Ez a folyamat rekurzívan megismételhető a későbbi UPDATE vagy DELETE műveletekhez.

  • Ha CREATE, ALTER, DELETEvagy más adatdefiníciós nyelvi (DDL) műveleteket hajt végre az eseményindítókon belül, a DDL-eseményindítók aktiválhatók. Ez később olyan DELETE vagy UPDATE műveleteket is végrehajthat, amelyek további kaszkádolt láncokat és eseményindítókat indítanak el.

  • Ha egy adott kaszkádolt hivatkozási műveletláncban hiba keletkezik, hiba lép fel, a rendszer nem indít el AFTER eseményindítókat az adott láncban, és a láncot létrehozó DELETE vagy UPDATE művelet vissza lesz állítva.

  • Az INSTEAD OF eseményindítóval rendelkező táblákban nem lehet REFERENCES záradék, amely kaszkádolt műveletet határoz meg. A kaszkádolt művelet által megcélzott táblák AFTER eseményindítója azonban végrehajthat egy INSERT, UPDATEvagy DELETE utasítást egy másik táblán vagy nézeten, amely az objektumon definiált INSTEAD OF eseményindítót aktiválja.