Használjunk-e a Foreign Key-t?


Persze, sőt egy jól megírt adatbázisban használni kell.

Nem lehet a kliens programokra bízni, hogy mindent ellenőrizzenek.

Egyrészt a programokban ezer helyen kellene ellenőrizni, ami nem biztos hogy teljeskörűen sikerül, másrészt más programokkal vagy esetleg IBConsole-val is lehet babrálni az adatbázist, amielyek nem végzik el a szükséges ellenőrzéseket, így az inkonzisztencia lehetőségét mindemképpen az adatbázisban illik korlátozni.


A másik oldalról a Foreign Key-eknek van egy kis hibájuk, ami nagy rendszereknél már komoly gondot okozhat.

Az IB-ben (és majdnem mindegyik másik adatbázisban) egy foreign hivatkozáshoz létrejön egy index.

Ez nem gond, ha pl. egy számla tételeinél adsz meg egy foreign hivatkozást a számlára. Ekkor azon túl, hogy véd az ellen, hogy kitöröld a számlatételek felől a számlájukat automatikusan biztosít egy számla azonosítóra vonatkozó indexet, ami mindíg kell a master-detail kapcsolat létrehozáshoz.

De mi van akkor, ha pl. a számlatételekhez használt adócsoport kódra egy foreign key-el vigyázunk. Létrejön a tételek táblához egy index az adócsoportra, hiszen ezzel ellenőrzi, hogy ha az adócsoport kód törlésre kerül, akkor van-e erre hivatkozás a számlatételek között. Az ellenőrzés gyors lesz, de szükségtelen, hiszen igen ritka (sőt gyakorlatilag soha nem történik) adócsoport kód törlés.

Az így létrejött adócsoportos index pedig teljesen felesleges, csak terheli az insert/update/delete időigényét, az adatbázis erőforrásait.

Ezek úgynevezett ritka indexek (pl. 1 millió tételben 3 lehetséges kódérték).

Az erőforrás pazarláson kívül sajnos más mellékhatást is eredményezhetnek az ilyen ritka indexek.

Egy select-ben az optimalizáló indexen keresztüli elérést határozhat el, miközben ennek idő és erőforrás igénye lényegesen nagyobb mint egy teljes végigolvasásnak (ez egy külön fejezetet érdemel), illetve lehet, hogy egy valóban hasznos (pl. számlaazonosítóra, vagy számlázási dátumra) szűrő indexet nem használ emiatt, ami sebesség problémákhoz vezethet.


Akkor ilyen esetben ne is próbájuk a szerver oldalon védeni az adatok konzisztenciáját?

De igen, ekkor is kell, de triggerekkel tegyük, vagyis a számlatétel insert/update-ban ellenőrizendő, hogy az adócsoport kód létezik-e és az adócsoport kód törlésénél kell ellenőriznie a triggernek, hogy használatban van-e valamely számlatételben. Kicsit körülményesebb, így csak nagyobb (pl. 1000 feletti tételszámú) tábláknál javasolt eljárás.


Javasolt linkek:


http://www.cvalde.net/document/declaRefIntegVsTrig.htm




(c) eMeL * utolsó módosítás: 2004.10.03