it-swarm-eu.dev

Proč se pro spojení nepoužívají primární / cizí klíčové zápasy?

Pokud jsem zjistil, mnoho databází DBMS (např. Mysql, postgres, mssql) používají kombinace fk a pk pouze k omezení změn dat, ale zřídka se nativně používají k automatickému výběru sloupců, které se mají spojit (jako přirozené spojení se jmény). Proč? Pokud jste již definovali vztah mezi dvěma tabulkami s pk/fk, proč nemůže databáze zjistit, že pokud se připojím k těmto tabulkám, chci se k nim připojit ve sloupcích pk/fk?

ÚPRAVA: trochu to objasnit:

předpokládejme, že mám tabulku1 a tabulku2. tabulka1 má cizí klíč ve sloupci a, který odkazuje na primární klíč v tabulce2, sloupec b. Nyní, když se připojím k těmto tabulkám, budu muset udělat něco takového:

SELECT * FROM table1
JOIN table2 ON table1.a = table2.b

Už jsem však definoval pomocí svých klíčů, že tabulka1.a odkazuje na tabulku2.b, takže se mi zdá, že by nemělo být obtížné, aby systém DBMS automaticky používal tabulku1.a a tabulku2.b jako sloupce spojení, tak, že člověk může jednoduše použít:

SELECT * FROM table1
AUTO JOIN table2

Zdá se však, že mnoho DBMS něco takového neimplementuje.

49
Tiddo

V mnoha případech existuje více než jeden způsob, jak spojit dvě tabulky; Podívejte se na další odpovědi pro mnoho příkladů. Samozřejmě by se dalo říci, že by v těchto případech bylo použití automatického spoje chybou. Pak by zůstala jen hrstka jednoduchých případů, kde by se dala použít.

Existuje však vážná nevýhoda! Dotazy, které jsou dnes správné, se mohou zítra stát jen chybou přidáním druhého FK do stejné tabulky!

Řeknu to znovu: přidáním sloupců se dotazy, které tyto sloupce nepoužívají, mohou změnit z „správné“ na „chybu“!

To je taková noční můra údržby, že by jakýkoli rozumný průvodce stylem tuto funkci zakázal. Většina již zakázala select * ze stejného důvodu!

To vše by bylo přijatelné, pokud by se zvýšil výkon. To však není pravda.

Shrnutí, tuto funkci lze použít pouze v omezeném počtu jednoduchých případů, nezvýší výkon a většina stylistických průvodců by její použití stejně zakázala.

Proto se nepřekvapuje, že většina prodejců databází se rozhodne trávit svůj čas důležitějšími věcmi.

32
Sjoerd

Cizí klíč je určen pro omezení data. tj. vynutit referenční integritu. A je to. Nic jiného.

  1. Ke stejné tabulce můžete mít více cizích klíčů. Pokud zásilka obsahuje počáteční a koncový bod, zvažte následující.

    table: USA_States
    StateID
    StateName
    
    table: Shipment
    ShipmentID
    PickupStateID Foreign key
    DeliveryStateID Foreign key
    

    Možná se budete chtít připojit na základě stavu vyzvednutí. Možná se chcete připojit ke stavu doručení. Možná budete chtít provést 2 spojení pro oba! Sql engine nemá možnost vědět, co chcete.

  2. Často budete křížit spojovat skalární hodnoty. Ačkoli skaláry jsou obvykle výsledkem mezilehlých výpočtů, někdy budete mít tabulku zvláštního určení s přesně 1 záznamem. Pokud by se motor pokusil detekovat klíč foriegn pro spojení ... to by nedávalo smysl, protože křížové spojení nikdy neodpovídá sloupci.

  3. V některých zvláštních případech se připojíte ke sloupcům, kde žádný není jedinečný. Proto je přítomnost PK/FK v těchto kolonách nemožná.

  4. Možná si myslíte, že výše uvedené body 2 a 3 nejsou relevantní, protože vaše otázky se týkají toho, kdy JE jediný vztah PK/FK mezi tabulkami. Přítomnost jednoho PK/FK mezi tabulkami však neznamená, že kromě PK/FK nemůžete mít další pole. Sql engine neví, na jakých polích se chcete připojit.

  5. Řekněme, že máte tabulku „USA_States“ a dalších 5 tabulek s FK do států. „Pět“ tabulek má také několik cizích klíčů. Měl by se sql engine automaticky spojit s „pěti“ tabulkami s „USA_States“? Nebo by se mělo spojit těch pět? Oba? Mohli byste nastavit vztahy tak, aby sql engine vstoupil do nekonečné smyčky a snažil se spojit věci dohromady. V této situaci je nemožné u motoru SQL odhadnout, co chcete.

V souhrnu: PK/FK nemá nic společného s připojením tabulky. Jsou to oddělené nesouvisející věci. Ve sloupcích PK/FK se často připojujete k nehodě přírody.

Chcete, aby motor sql hádal, zda se jedná o úplné, levé, pravé nebo vnitřní spojení? Nemyslím si to. Ačkoliv by to pravděpodobně byl menší hřích, než odhadnout sloupce, aby se připojily.

27
Lord Tydus

koncept „spojitelnosti“. Vztahy r1 a r2 jsou spojitelné pouze tehdy, jsou-li atributy se stejným názvem stejného typu ... tento koncept se vztahuje nejen na spojení jako takové, ale také na různé jiné operace [jako je unie].

SQL a relační teorie: Jak napsat přesný kód SQL od C. J. Date

Standardní SQL již má takovou funkci známou jako NATURAL JOIN a byl implementován do mySQL.

Přestože váš návrh není tak hodný, zdá se to rozumný. S SQL Serverem (který postrádá podporu pro NATURAL JOIN ), používám SQL Prompt v Management Studio: při psaní INNER JOIN jeho InteliSense navrhuje ON klauzule na základě běžných názvů atributů a cizích klíčů a považuji to za velmi užitečné. Nemám však velkou touhu vidět za tím nový (standardní) typ připojení SQL.

11
onedaywhen

SQL přišel jako první!

Omezení cizího klíče a cizího klíče přišly později a jsou v podstatě optimalizací pro aplikace ve stylu transakcí.

Relační databáze byly původně koncipovány jako metoda aplikace složitých dotazů na sady dat způsobem, který byl matematicky prokazatelný pomocí relační algebry. TJ. pro danou sadu dat a daný dotaz je vždy jediná správná odpověď.

Relační databáze od té doby prošly dlouhou cestu a primární použití jako vrstva perzistence pro transakční systémy nebylo to, co CODD et. všechny předpokládané.

Orgán standardů ANSI pro všechny své protichůdné cíle a politiku prodejců se však vždy snažil zachovat „matematicky prokazatelné“ vlastnosti SQL.

Pokud jste databázi povolili odvodit vlastnosti spojení ze "skrytých" dat cizího klíče, ztratili byste tuto vlastnost (zvažte dvojznačnost, pokud byla definována více než jedna sada cizích klíčů).

Také programátor, který čte SQL, nemusí nutně vědět, jaké cizí klíče jsou aktuálně definovány pro dvě tabulky, a musel by prozkoumat schéma databáze, aby zjistil, co dotaz dělá.

9
James Anderson

Možná pracujete na základě falešného předpokladu. Říkáte „pokud to zjistíte“, ale neposkytujete žádný empirický nebo důkazní důkaz. Pokud jsou pk nebo fk nejlepším indexem pro dotaz, bude použit. Nevím, proč to vidíte, ale můj odhad je špatně utvářený.


pravit nyní, když byla otázka úplně přepsána: Případ, který popisujete, by se týkal pouze velmi malé sady dotazů. Co když je připojeno 12 tabulek? Co když neexistují FKs .... I kdyby existovalo výchozí připojení, stále bych specifikoval spojení jen kvůli čitelnosti. (Nechci se na data dívat a potom se pokusím přijít na to, k čemu se připojuje)

Některé nástroje dotazu ve skutečnosti provedou automatické připojení a poté vám umožní odebrat nebo upravit připojení. Myslím, že MS Access's Query Builder to dělá.

Nakonec standard ANSII uvádí, že spojení musí být specifikováno. To je dostatečný důvod, aby to nebylo možné.

7
Morons

I když jste definovali vztah cizího klíče, neznamená to, že se chcete připojit ke všem tabulkám ve všech dotazech. Je to nejpravděpodobnější metoda pro připojení tabulek, ale existují případy, kdy to není správné.

  • Možná budete chtít použít kartézský produkt z obou tabulek nebo jejich částí pro nějaký účel.
  • Mohou existovat další pole, ke kterým se můžete připojit za jiným účelem.
  • Pokud spojujete tři nebo více tabulek, může jedna z tabulek souviset s dvěma nebo více tabulkami. V tomto případě obvykle může být v dotazu vhodný pouze jeden z možných vztahů FK.
7
BillThor

Existuje mnoho důvodů, jak to databáze nemůže bezpečně udělat, včetně skutečnosti, že přidání/odebrání cizích klíčů změní význam předem napsaných dotazů včetně dotazů ve zdrojovém kódu aplikace. Většina databází také nemá dobrou sadu cizích klíčů, která by pokrývala všechna možná spojení, která budete pravděpodobně chtít dělat. Také za lepší nebo za cenu se cizí klíče často odstraňují, aby se urychlily systémy a nelze je použít na tabulkách, které jsou načteny ze souboru v chybném pořadí.

Neexistuje však žádný důvod, proč by návrh dotazu nástroj nebo textový editor nemohl automaticky dokončit spojení pomocí cizích klíčů stejným způsobem, jakým vám dávají inteligentní na název sloupce. Pokud nástroj zjistil chybu, můžete jej upravit a uložit kompletně definovaný dotaz. Takový nástroj by také mohl užitečně využít konvenci pojmenování sloupců cizích klíčů podle názvu „nadřazené“ tabulky a sloupců se stejným názvem v nadřazené/podřízené tabulce atd.

(Moje žena stále nedokáže pochopit rozdíl mezi Management Studio a Sql Server a mluví o spuštění serveru SQL, když spustí manažerské studio!)

3
Ian Ringrose

Přirozené spojení se „automaticky“ připojí k rovnosti běžných sloupců, ale měli byste psát jen tehdy, pokud to je to, co want na základě významů tabulek a vašeho očekávaného výsledku. Neexistuje žádné „automatické“ vědět, jak by se dvě tabulky „měly“ spojit nebo jakkoli jiným způsobem, aby se v dotazu objevila jakákoli tabulka „. Nepotřebujeme znát omezení dotazu. Jejich přítomnost pouze znamená, že vstupy mohou být omezené a v důsledku toho může být výstup také. Mohli byste definovat nějaký operátor join_on_fk_to_pk, který se „automaticky“ připojí za deklarovaná omezení; ale pokud chcete, aby význam dotazu zůstal stejný, i když se změní pouze omezení, ale nikoli tabulkové významy, budete muset tento dotaz změnit na ne , použijte nové deklarované konstanty. Stačí zadat dotaz, který chcete použít, a připojit se k podmínkám již ponechává stejný význam i přes jakékoli změny omezení .

Jaká omezení platí (včetně PK, FK, UNIQUE & CHECK) nemají vliv na to, co znamenají tabulky. Samozřejmě, pokud se změní významy tabulek, pak se kontraindikace mohou změnit. Pokud se však omezení změní, neznamená to, že by se dotazy měly změnit.

Člověk nemusí znát omezení dotazu. Znalost omezení znamená, že můžeme použít další výrazy, které by bez omezení nevrátily stejnou odpověď. Např. Pomocí UNIQUE očekáváme, že tabulka má jeden řádek, takže ji můžeme použít jako skalár. Tyto dotazy se mohou porušit, pokud bylo omezení přijato, ale nebylo deklarováno. Prohlášení omezení, které dotaz nepředpokládal, však nemůže porušit.

Existuje pravidlo pro sestavení dotazu SQL z popisu čitelného člověkem?

3
philipxy

Důvod je ten, že existuje LANGUAGE, a pak jsou zde základní principy. Tento jazyk je řídký a chybí v mnoha funkcích, které byste očekávali ve všeobecném jazyce. Jednoduše se jedná o pěknou funkci, která nebyla přidána do jazyka a pravděpodobně nebude. Není to mrtvý jazyk, takže existuje určitá naděje, ale nebyl bych optimistický.

Jak jiní zdůraznili, některé implementace používají rozšíření, kde join (sloupec) spojuje dvě tabulky na základě společného názvu sloupce, což je poněkud podobné. Ale není to široce rozšířené. Toto rozšíření se liší od SELECT * FROM employee NATURAL JOIN department; syntaxe, která nezahrnuje způsob určení sloupců, které se mají použít. Nespoléhejte se ani na vztah mezi tabulkami, což je činí nespolehlivými (přirozená syntaxe spojení více než rozšíření).

Neexistuje žádná zásadní překážka „vnitřní tabulky spojení v PKFK“, kde PKFK je klíčové slovo, které znamená „vztah cizího klíče definovaný mezi dvěma tabulkami“, mohou existovat problémy s více fk ke stejné tabulce, ale to by mohlo jednoduše způsobit chybu. Otázkou je, zda lidé, kteří jazyk navrhují, považují a) za dobrý nápad ab) za lepší práci, než s jakoukoli jinou jazykovou změnou ...

2
jmoreno

Pokud se předpokládá, že vynechání klauzule ON bude následovat pole založená na referenční integritě, jak byste udělali kartézský produkt?

Úpravy: pomocí AUTO Výhodou tohoto je trochu méně psaní a nemusíte vědět, jak jsou spojeni, nebo si pamatovat složité spojení. Pokud se vztah změní, bude se s ním zacházet automaticky, ale to se zřídka stane, s výjimkou raného vývoje.

Nyní musíte rozhodnout, zda se všechny vaše připojení AUTO během změny relace podrží, aby odpovídaly záměru vašeho vybraného příkazu.

1
JeffO