it-swarm-eu.dev

Warum werden für Joins keine Primärschlüssel- / Fremdschlüssel-Übereinstimmungen verwendet?

Soweit ich herausfinden konnte, verwenden viele DBMS (z. B. mysql, postgres, mssql) Fk- und pk-Kombinationen nur, um Änderungen an Daten einzuschränken. Sie werden jedoch selten nativ verwendet, um automatisch Spalten zum Verbinden auszuwählen (wie dies bei natürlichen Verknüpfungen mit Namen der Fall ist). Warum ist das so? Wenn Sie bereits eine Beziehung zwischen zwei Tabellen mit einem pk/fk definiert haben, warum kann die Datenbank dann nicht herausfinden, dass ich sie in den pk/fk-Spalten verbinden möchte, wenn ich diese Tabellen verbinde?

EDIT: um dies ein wenig zu verdeutlichen:

angenommen, ich habe eine Tabelle1 und eine Tabelle2. Tabelle 1 hat einen Fremdschlüssel in Spalte a, der auf den Primärschlüssel in Tabelle 2, Spalte b, verweist. Wenn ich mich jetzt diesen Tabellen anschließe, muss ich so etwas tun:

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

Ich habe jedoch bereits mit meinen Schlüsseln definiert, dass table1.a auf table2.b verweist. Daher scheint es mir nicht zu schwierig zu sein, ein DBMS-System dazu zu bringen, table1.a und table2.b automatisch als Join-Spalten zu verwenden. so dass man einfach verwenden kann:

SELECT * FROM table1
AUTO JOIN table2

Viele DBMS scheinen jedoch so etwas nicht zu implementieren.

49
Tiddo

In vielen Fällen gibt es mehrere Möglichkeiten, zwei Tabellen zu verbinden. In den anderen Antworten finden Sie viele Beispiele. Man könnte natürlich sagen, dass es in diesen Fällen ein Fehler wäre, den "automatischen Join" zu verwenden. Dann wären nur noch eine Handvoll einfacher Fälle übrig, in denen es verwendet werden kann.

Es gibt jedoch einen schwerwiegenden Nachteil! Abfragen, die heute korrekt sind, können morgen zu einem Fehler werden, wenn nur ein zweiter FK zur gleichen Tabelle hinzugefügt wird!

Lassen Sie mich das noch einmal sagen: Durch Hinzufügen von Spalten können Abfragen, die diese Spalten nicht verwenden, von "korrekt" in "Fehler" umgewandelt werden!

Das ist so ein Wartungs-Albtraum, dass jeder vernünftige Styleguide die Verwendung dieser Funktion verbieten würde. Die meisten verbieten bereits select * aus dem gleichen Grunde!

All dies wäre akzeptabel, wenn die Leistung verbessert würde. Dies ist jedoch nicht der Fall.

Zusammenfassend: Diese Funktion kann nur in einer begrenzten Anzahl einfacher Fälle verwendet werden, erhöht die Leistung nicht und die meisten Styleguides verbieten ihre Verwendung ohnehin.

Daher ist es nicht verwunderlich, dass die meisten Datenbankanbieter ihre Zeit für wichtigere Dinge verwenden.

32
Sjoerd

Ein Fremdschlüssel soll einschränken die Daten. dh die referenzielle Integrität erzwingen. Das ist es. Nichts anderes.

  1. Sie können mehrere Fremdschlüssel für dieselbe Tabelle haben. Beachten Sie Folgendes, wenn eine Sendung einen Startpunkt und einen Endpunkt hat.

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

    Möglicherweise möchten Sie basierend auf dem Abholstatus beitreten. Vielleicht möchten Sie sich dem Lieferstatus anschließen. Vielleicht möchten Sie 2 Joins für beide durchführen! Die SQL-Engine kann nicht wissen, was Sie wollen.

  2. Sie werden häufig skalare Verknüpfungswerte kreuzen. Obwohl Skalare normalerweise das Ergebnis von Zwischenberechnungen sind, haben Sie manchmal eine Spezialtabelle mit genau 1 Datensatz. Wenn die Engine versuchen würde, einen falschen Schlüssel für die Verknüpfung zu erkennen, wäre dies nicht sinnvoll, da Kreuzverknüpfungen niemals mit einer Spalte übereinstimmen.

  3. In einigen besonderen Fällen werden Sie Spalten beitreten, in denen keine eindeutig ist. Daher ist das Vorhandensein einer PK/FK auf diesen Spalten unmöglich.

  4. Möglicherweise denken Sie, dass die obigen Punkte 2 und 3 nicht relevant sind, da es bei Ihren Fragen darum geht, wann eine einzelne PK/FK-Beziehung zwischen Tabellen besteht. Das Vorhandensein einer einzelnen PK/FK zwischen den Tabellen bedeutet jedoch nicht, dass Sie neben der PK/FK keine weiteren Felder zum Verbinden haben können. Die SQL-Engine weiß nicht, an welchen Feldern Sie teilnehmen möchten.

  5. Nehmen wir an, Sie haben eine Tabelle "USA_States" und 5 weitere Tabellen mit einem FK für die Bundesstaaten. Die "fünf" Tabellen haben auch einige Fremdschlüssel zueinander. Sollte die SQL-Engine die "fünf" Tabellen automatisch mit "USA_States" verbinden? Oder sollte es die "fünf" miteinander verbinden? Beide? Sie können die Beziehungen so einrichten, dass die SQL-Engine in eine Endlosschleife eintritt und versucht, Dinge miteinander zu verbinden. In dieser Situation ist es unmöglich, dass die SQL-Engine errät, was Sie wollen.

Zusammenfassend : PK/FK hat nichts mit Tabellenverknüpfungen zu tun. Sie sind getrennte, nicht miteinander verbundene Dinge. Es ist nur ein Zufall der Natur, dass Sie sich häufig den PK/FK-Spalten anschließen.

Möchten Sie, dass die SQL-Engine errät, ob es sich um eine vollständige, linke, rechte oder innere Verknüpfung handelt? Das glaube ich nicht. Obwohl das wohl eine geringere Sünde wäre, als die Spalten zu erraten, an denen man teilnehmen soll.

27
Lord Tydus

das Konzept der "Verbindbarkeit". Die Beziehungen r1 Und r2 Können nur dann verknüpft werden, wenn Attribute mit demselben Namen vom gleichen Typ sind. Dieses Konzept gilt nicht nur für das Verknüpfen als solches, sondern auch für verschiedene andere Operationen [z Gewerkschaft].

SQL und relationale Theorie: Schreiben von genauem SQL-Code nach C. J. Datum

Standard SQL verfügt bereits über eine solche Funktion, die als NATURAL JOIN Bekannt ist, und wurde in mySQL implementiert.

Obwohl Ihr Vorschlag nicht ganz so wertvoll ist, scheint er vernünftig zu sein. Mit SQL Server (der ohne Unterstützung für NATURAL JOIN ) verwende ich SQL Prompt in Management Studio: Beim Schreiben eines INNER JOIN Schlägt InteliSense ON -Klauseln vor basierend auf allgemeinen Attributnamen und Fremdschlüsseln und ich finde es sehr nützlich. Ich habe jedoch keinen großen Wunsch, einen neuen (Standard-) SQL-Join-Typ dafür zu sehen.

11
onedaywhen

SQL stand an erster Stelle!

Fremdschlüssel- und Fremdschlüsseleinschränkungen wurden später eingeführt und sind im Wesentlichen eine Optimierung für Anwendungen im Transaktionsstil.

Relationale Datenbanken wurden ursprünglich als Methode konzipiert, um komplexe Abfragen auf Datensätze auf eine Weise anzuwenden, die mathematisch beweisbar unter Verwendung relationaler Algebra war. I.E. Für einen bestimmten Datensatz und eine bestimmte Abfrage gibt es immer eine einzige richtige Antwort.

Relationale Datenbanken haben seitdem einen langen Weg zurückgelegt, und ihre primäre Verwendung als Persistenzschicht für Transaktionssysteme war nicht das, was CODD et. alles ins Auge gefasst.

Das ANSI-Standardisierungsgremium für all seine widersprüchlichen Ziele und seine Lieferantenpolitik war jedoch stets bemüht, "mathematisch nachweisbare" Eigenschaften von SQL beizubehalten.

Wenn Sie der Datenbank erlauben würden, die Verknüpfungseigenschaften aus "versteckten" Fremdschlüsseldaten abzuleiten, würden Sie diese Eigenschaft verlieren (berücksichtigen Sie die Mehrdeutigkeit, wenn mehr als ein Satz von Fremdschlüsseln definiert wäre).

Außerdem würde ein Programmierer, der SQL liest, nicht unbedingt wissen, welche Fremdschlüssel derzeit für die beiden Tabellen definiert sind, und müsste das Datenbankschema untersuchen, um herauszufinden, was die Abfrage tut.

9
James Anderson

Möglicherweise gehen Sie von einer falschen Annahme aus. Sie sagen "soweit Sie es herausfinden können", geben aber keinen empirischen oder nachweislichen Beweis. Wenn pk oder fk der beste Index für eine Abfrage sind, wird er verwendet. Ich weiß nicht, warum Sie das sehen, aber meine Vermutung sind schlecht geformte Fragen.


Bearbeiten Sie jetzt, da die Frage vollständig neu geschrieben wurde : Der Fall, den Sie beschreiben, ist nur für eine sehr kleine Anzahl von Abfragen. Was ist, wenn 12 Tabellen verbunden sind? Was ist, wenn es keine FKs gibt? Selbst wenn ein Standard-Join aktiviert wäre, würde ich den Join immer nur zur besseren Lesbarkeit angeben. (Ich möchte nicht auf die Daten schauen und dann versuchen herauszufinden, woran ich mich anschließe)

Einige Abfragetools führen tatsächlich eine automatische Verknüpfung für Sie durch und ermöglichen Ihnen dann, die Verknüpfung zu entfernen oder zu bearbeiten. Ich denke, dass der Abfrage-Generator von MS Access dies tut.

Schließlich besagt der ANSII-Standard, dass der Join angegeben werden muss. Grund genug, es nicht zuzulassen.

7
Morons

Während Sie eine Fremdschlüsselbeziehung definiert haben, bedeutet dies nicht, dass Sie die Tabellen in allen Abfragen so verknüpfen möchten. Es ist die wahrscheinlichste Methode zum Verknüpfen der Tabellen, aber es gibt Fälle, in denen dies nicht korrekt ist.

  • Möglicherweise möchten Sie ein kartesisches Produkt der beiden Tabellen oder einen Teil davon für einen bestimmten Zweck verwenden.
  • Möglicherweise gibt es andere Felder, denen Sie für einen anderen Zweck beitreten können.
  • Wenn Sie drei oder mehr Tabellen verbinden, kann eine der Tabellen mit zwei oder mehr Tabellen verknüpft sein. In diesem Fall ist normalerweise nur eine der möglichen FK-Beziehungen in der Abfrage geeignet.
7
BillThor

Es gibt viele Gründe, warum Datenbank dies nicht sicher tun kann, einschließlich der Tatsache, dass das Hinzufügen/Entfernen von Fremdschlüsseln die Bedeutung vorab geschriebener Abfragen ändert, einschließlich Abfragen im Quellcode der Anwendung. Die meisten Datenbanken verfügen auch nicht über einen guten Satz von Fremdschlüsseln, die alle möglichen Verknüpfungen abdecken, die Sie wahrscheinlich möchten. Fremdschlüssel werden häufig entfernt, um Systeme zu beschleunigen, und können nicht für Tabellen verwendet werden, die in der "falschen" Reihenfolge aus der Datei geladen werden.

Es gibt jedoch keinen Grund, warum ein Abfragedesign Tool oder der Texteditor einen Join mit Hilfe von Fremdschlüsseln nicht automatisch auf die gleiche Weise abschließen kann, wie sie Ihnen Intellisense geben auf Spaltenname. Sie können die Abfrage bearbeiten, wenn das Tool einen Fehler gemacht hat, und eine vollständig definierte Abfrage speichern. Ein solches Tool könnte auch die Konvention nutzen, Fremdschlüsselspalten nach dem Namen der übergeordneten Tabelle und Spalten mit demselben Namen in der übergeordneten/untergeordneten Tabelle usw. zu benennen.

(Meine Frau kann den Unterschied zwischen Management Studio und SQL Server immer noch nicht verstehen und spricht über das Starten von SQL Server, wenn sie Management Studio startet!)

3
Ian Ringrose

Natürliche Verknüpfung "automatisch" verbindet sich mit der Gleichheit gemeinsamer Spalten, aber Sie sollten dies nur schreiben, wenn Sie dies möchten , basierend auf Tabellenbedeutungen und Ihrem gewünschten Ergebnis. Es gibt kein "automatisch" Wissen, wie zwei Tabellen "verbunden" werden sollen oder auf andere Weise eine Tabelle "sollte" in einer Abfrage erscheinen. Wir müssen keine Einschränkungen für die Abfrage kennen. Ihre Anwesenheit bedeutet nur, dass die Eingaben begrenzt sein können und folglich auch die Ausgabe. Sie können eine Art join_on_fk_to_pk-Operator definieren, der gemäß den deklarierten Einschränkungen "automatisch" beitritt. Wenn Sie jedoch möchten, dass die Bedeutung der Abfrage gleich bleibt, wenn sich nur Einschränkungen, aber keine Tabellenbedeutungen ändern, müssen Sie diese Abfrage in not ändern. Verwenden Sie die neu deklarierten Konstanten. Wenn Sie nur die gewünschte Abfrage mit join & Bedingungen eingeben, bleibt die Bedeutung trotz aller Änderungen an den Einschränkungen gleich.

Welche Einschränkungen gelten (einschließlich PKs, FKs, UNIQUE & CHECK), hat keinen Einfluss darauf, was Tabellen bedeuten. Wenn sich die Tabellenbedeutungen ändern, können sich natürlich die Einschränkungen ändern. Wenn sich die Einschränkungen ändern, bedeutet dies nicht, dass sich die Abfragen ändern sollten.

Zum Abfragen müssen keine Einschränkungen bekannt sein. Wenn wir über Einschränkungen Bescheid wissen, können wir weitere Ausdrücke verwenden, die ohne das Halten von Einschränkungen nicht dieselbe Antwort zurückgeben würden. Erwarten Sie beispielsweise über UNIQUE, dass eine Tabelle eine Zeile enthält, damit wir sie als Skalar verwenden können. Diese Abfragen können unterbrochen werden, wenn die Einschränkung angenommen, aber nicht deklariert wurde. Das Deklarieren einer Einschränkung, von der die Abfrage nicht ausgegangen ist, kann sie jedoch nicht aufheben.

Gibt es eine Faustregel zum Erstellen einer SQL-Abfrage aus einer für Menschen lesbaren Beschreibung?

3
philipxy

Der Grund ist, dass es die SPRACHE gibt, und dann gibt es die zugrunde liegenden Prinzipien. Die Sprache ist spärlich und es fehlen viele Funktionen, die Sie in einer Allzwecksprache erwarten würden. Dies ist einfach eine nette Funktion, die der Sprache nicht hinzugefügt wurde und wahrscheinlich auch nicht hinzugefügt wird. Es ist keine tote Sprache, also gibt es Hoffnung, aber ich wäre nicht optimistisch.

Wie andere bereits erwähnt haben, verwenden einige Implementierungen eine Erweiterung, bei der join (column) zwei Tabellen basierend auf einem gemeinsamen Spaltennamen verbindet, der etwas ähnlich ist. Aber es ist nicht weit verbreitet. Beachten Sie, dass sich diese Erweiterung von der SELECT * FROM employee NATURAL JOIN department; Syntax, die keine Möglichkeit enthält, anzugeben, welche Spalten verwendet werden sollen. Weder verlassen sich auf eine Beziehung zwischen den Tabellen, die sie unzuverlässig macht (die natürliche Join-Syntax mehr als die Erweiterung).

Es gibt kein grundlegendes Hindernis für "innere Verknüpfungstabelle in PKFK", wobei PKFK ein Schlüsselwort ist, das "die zwischen den beiden Tabellen definierte Fremdschlüsselbeziehung" bedeutet. Es kann Probleme mit mehreren fk in derselben Tabelle geben, die jedoch einfach einen Fehler verursachen können. Die Frage ist, ob die Leute, die die Sprache entwerfen, der Meinung sind, dass a) eine gute Idee ist und b) besser zu bearbeiten ist als irgendein anderer Sprachwechsel ...

2
jmoreno

Wenn angenommen wird, dass das Weglassen der ON-Klausel den Feldern folgt, die auf der referenziellen Integrität basieren, wie würden Sie ein kartesisches Produkt ausführen?

Bearbeiten: mit AUTO Die Vorteile sind etwas weniger Eingabe und Sie müssen nicht wissen, wie sie verbunden sind, oder sich an eine komplizierte Verbindung erinnern. Wenn sich die Beziehung ändert, wird sie automatisch behandelt, aber das passiert nur selten, außer in der frühen Entwicklung.

Was Sie jetzt tun müssen, ist zu entscheiden, ob alle Ihre AUTO-Joins während einer Änderung der Beziehung halten, um der Absicht Ihrer select-Anweisung zu entsprechen.

1
JeffO