Soweit ich herausfinden konnte, verwenden viele DBMS (z. B. mysql, postgres, mssql) fk- und pk-Kombinationen nur, um Änderungen an Daten einzuschränken, aber sie werden selten nativ verwendet, um automatisch zu verbindende Spalten auszuwählen (wie natürliche Verknüpfungen mit Namen). Warum ist das so? Wenn Sie bereits eine Beziehung zwischen zwei Tabellen mit einem pk / fk definiert haben, kann die Datenbank dann nicht herausfinden, ob ich diese Tabellen in den pk / fk-Spalten verknüpfen möchte, wenn ich sie verknüpfe.
EDIT: um dies etwas zu klären:
Angenommen, ich habe einen Tisch1 und einen Tisch2. In Tabelle 1 befindet sich ein Fremdschlüssel in Spalte a, der auf den Primärschlüssel in Tabelle 2, Spalte b, verweist. Wenn ich mich nun diesen Tabellen anschließe, muss ich Folgendes 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 sollte es für mich nicht zu schwierig sein, ein DBMS-System so zu konfigurieren, dass es automatisch table1.a und table2.b als Verknüpfungsspalten verwendet. so dass man einfach benutzen kann:
SELECT * FROM table1
AUTO JOIN table2
Viele DBMS scheinen jedoch so etwas nicht zu implementieren.
quelle
NATURAL JOIN
(weshalb ich sie normalerweise vermeide), aber ich denke nicht, dass dies bedeuten sollte, dass ein DBMS keine automatische Methode zum Verknüpfen von Tabellen basierend auf Fremdschlüsseln implementieren kann.AUTO JOIN mytable THROUGH myrelation
, es wäre sehr schön.InnerJoin(SRC_TABLE.rDEST_TABLE.REL_NAME_F01)
Ein Fremdschlüssel soll die Daten einschränken . dh referenzielle Integrität erzwingen. Das ist es. Nichts anderes.
Sie können mehrere Fremdschlüssel für dieselbe Tabelle haben. Beachten Sie Folgendes, wenn eine Sendung einen Start- und einen Endpunkt hat.
Möglicherweise möchten Sie basierend auf dem Abholstatus beitreten. Vielleicht möchten Sie sich am Auslieferungszustand beteiligen. Vielleicht möchten Sie zwei Joins für beide ausführen! Die SQL-Engine hat keine Möglichkeit zu wissen, was Sie wollen.
Sie werden häufig skalare Cross-Join-Werte verwenden. Obwohl Skalare normalerweise das Ergebnis von Zwischenberechnungen sind, haben Sie manchmal eine Spezialtabelle mit genau 1 Datensatz. Wenn die Engine versucht hätte, einen falschen Schlüssel für den Join zu ermitteln, wäre dies nicht sinnvoll, da Cross-Joins niemals mit einer Spalte übereinstimmen.
In einigen besonderen Fällen werden Sie an Spalten teilnehmen, bei denen keine eindeutig ist. Daher ist das Vorhandensein eines PK / FK auf diesen Spalten unmöglich.
Sie können denken , Punkte 2 und 3 nicht relevant sind , da Ihre Fragen zu ist , wenn es IS eine einzelne PK / FK Beziehung zwischen Tabellen. Das Vorhandensein einer einzelnen PK / FK zwischen den Tabellen bedeutet jedoch nicht, dass Sie nicht zusätzlich zur PK / FK weitere Felder zum Verknüpfen haben können. Die SQL-Engine würde nicht wissen, auf welchen Feldern Sie beitreten möchten.
Nehmen wir an, Sie haben eine Tabelle "USA_States" und 5 weitere Tabellen mit einem FK zu den Staaten. Die "fünf" Tabellen haben auch ein paar Fremdschlüssel zueinander. Sollte die SQL-Engine automatisch die "fünf" Tabellen mit "USA_States" verbinden? Oder soll es die "Fünf" miteinander verbinden? Beide? Sie können die Beziehungen so einrichten, dass die SQL-Engine in eine Endlosschleife eintritt und versucht, die Elemente 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 Dinge, die nichts miteinander zu tun haben. Es ist nur ein Zufall der Natur, dass Sie sich oft an den PK / FK-Säulen beteiligen.
Möchten Sie, dass die SQL-Engine errät, ob es sich um eine vollständige, eine linke, eine rechte oder eine innere Verknüpfung handelt? Ich glaube nicht. Obwohl das wohl eine geringere Sünde wäre, als die Säulen zum Beitritt zu raten.
quelle
SQL und relationale Theorie: Wie man genauen SQL-Code nach CJ-Datum schreibt
Standard-SQL verfügt bereits über eine solche Funktion, die als "
NATURAL JOIN
mySQL" bezeichnet und in mySQL implementiert wurde.Obwohl Ihr Vorschlag nicht ganz so wertvoll ist, scheint er vernünftig zu sein. Mit SQL Server (für den es an Unterstützung mangelt
NATURAL JOIN
) verwende ich SQL Prompt in Management Studio: Beim Schreiben einesINNER JOIN
InteliSense-Befehls werdenON
Klauseln vorgeschlagen, die sowohl auf allgemeinen Attributnamen als auch auf Fremdschlüsseln basieren, und ich finde es sehr nützlich. Ich habe jedoch keinen großen Wunsch, einen neuen (Standard-) SQL-Join-Typ dafür zu sehen.quelle
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 so anzuwenden, dass sie mithilfe der relationalen Algebra mathematisch nachweisbar sind . IE 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 al. alles vorgesehen.
Das ANSI-Standardgremium war jedoch stets bestrebt, die "mathematisch nachweisbaren" Eigenschaften von SQL trotz aller widersprüchlichen Ziele und Herstellerpolitik beizubehalten.
Wenn Sie der Datenbank erlauben würden, die Verknüpfungseigenschaften aus "verborgenen" Fremdschlüsseldaten abzuleiten, würden Sie diese Eigenschaft verlieren (berücksichtigen Sie die Mehrdeutigkeit, wenn mehr als ein Satz von Fremdschlüsseln definiert ist).
Auch ein Programmierer, der die SQL liest, würde nicht unbedingt wissen, welche Fremdschlüssel aktuell für die beiden Tabellen definiert sind, und müsste das Datenbankschema untersuchen, um herauszufinden, was die Abfrage tut.
quelle
Während Sie eine Fremdschlüsselbeziehung definiert haben, heißt das nicht, dass Sie die Tabellen in allen Abfragen 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.
quelle
Möglicherweise gehen Sie von einer falschen Annahme aus. Sie sagen "so weit Sie es herausfinden können", geben aber keine empirischen oder nachweislichen Beweise. 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 ist schlecht formulierte Abfragen.
Bearbeiten Sie jetzt, da die Frage vollständig umgeschrieben wurde: Der Fall, den Sie beschreiben, ist nur für eine sehr kleine Anzahl von Abfragen bestimmt. Was ist, wenn 12 Tische verbunden sind? Was ist, wenn es keine FKs gibt? Auch wenn es einen Standard-Join gibt, würde ich den Join immer nur aus Gründen der Lesbarkeit angeben. (Ich möchte nicht auf die Daten schauen und dann versuchen, herauszufinden, woran sich etwas anschließt.)
Einige Abfragetools führen tatsächlich eine automatische Verknüpfung durch, mit der Sie die Verknüpfung entfernen oder bearbeiten können. Ich denke, dass der Abfrage-Generator von MS Access dies tut.
Schließlich besagt der ANSII-Standard, dass der Join angegeben werden muss. Das ist Grund genug, es nicht zuzulassen.
quelle
Es gibt viele Gründe, warum die Datenbank dies nicht sicher tun kann, einschließlich der Tatsache, dass das Hinzufügen / Entfernen von Fremdschlüsseln die Bedeutung vorab geschriebener Abfragen einschließlich Abfragen im Quellcode der Anwendung ändert. 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 das System zu beschleunigen, und können nicht für Tabellen verwendet werden, die in der "falschen" Reihenfolge aus der Datei geladen werden.
Allerdings gibt es keinen Grund , warum ein Abfrage - Entwurfswerkzeug oder den Texteditor kann nicht automatisch vollständig ein Join mit Hilfe von Fremdschlüsseln in der gleichen Art und Weise , wie sie Ihnen geben intellisense auf Spaltennamen. Sie können die Abfrage bearbeiten, wenn das Tool einen Fehler festgestellt hat, und eine vollständig definierte Abfrage speichern. Ein solches Tool könnte auch die Konvention der Benennung von Fremdschlüsselspalten nach dem übergeordneten Tabellennamen und gleichnamigen Spalten in der übergeordneten / untergeordneten Tabelle usw. nutzen.
(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!)
quelle
Natural Join „automatisch“ tritt auf Gleichheit der gemeinsamen Spalten, aber Sie sollten nur das schreiben , wenn das, was Sie wollen , basierend auf dem Tisch Bedeutungen und Ihr desied Ergebnis. Es gibt kein "automatisches" Wissen darüber, wie zwei Tabellen in einer Abfrage "verknüpft" oder auf andere Weise "angezeigt" werden sollen. Für die Abfrage müssen keine Einschränkungen bekannt sein. Ihre Anwesenheit bedeutet nur, dass die Eingaben begrenzt sein können und folglich auch die Ausgabe. Sie könnten eine Art join_on_fk_to_pk-Operator definieren, der "automatisch" pro deklarierter Einschränkung beitritt. Wenn Sie jedoch möchten, dass die Bedeutung der Abfrage gleich bleibt, wenn sich nur Einschränkungen ändern, aber keine Tabellenbedeutungen, müssen Sie diese Abfrage ändern, um die neuen deklarierten Konstanten nicht zu verwenden.belässt die Bedeutung trotz Änderungen der Bedingungen bereits gleich .
Welche Einschränkungen gelten (einschließlich PKs, FKs, UNIQUE & CHECK), hat keinen Einfluss auf die Bedeutung der Tabellen. Wenn sich die Tabellenbedeutungen ändern, können sich natürlich auch die Einschränkungen ändern. Wenn sich die Einschränkungen ändern, bedeutet dies jedoch nicht, dass sich die Abfragen ändern sollten.
Man muss keine Einschränkungen kennen, um abzufragen. Wenn wir die Bedingungen kennen, können wir weitere Ausdrücke verwenden, die ohne das Halten der Bedingungen nicht dieselbe Antwort liefern würden. B. über UNIQUE erwarten, 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, um eine SQL-Abfrage aus einer für Menschen lesbaren Beschreibung zu erstellen?
quelle
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, es gibt also Hoffnung, aber ich wäre nicht optimistisch.
Wie bereits erwähnt, verwenden einige Implementierungen eine Erweiterung, bei der join (column) zwei Tabellen auf der Grundlage eines gemeinsamen Spaltennamens verknüpft, 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 unterscheidet, in der nicht angegeben werden kann, welche Spalten verwendet werden sollen. Weder verlassen Sie sich auf eine Beziehung zwischen den Tabellen, die sie unzuverlässig macht (die natürliche Verknüpfungssyntax mehr als die Erweiterung).Es gibt kein grundsätzliches Hindernis für "innere Join-Tabelle 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 und b) besser zu bearbeiten ist als irgendein anderer Sprachwechsel ...
quelle
Wenn davon ausgegangen wird, dass die ON-Klausel den Feldern folgt, die auf der referenziellen Integrität basieren, wie würden Sie ein kartesisches Produkt ausführen?
Bearbeiten: Verwenden von AUTO Der Vorteil ist, dass Sie weniger tippen und nicht wissen müssen, wie sie verbunden sind oder sich an einen komplizierten Join erinnern. Wenn sich die Beziehung ändert, wird sie automatisch behandelt, aber das kommt nur in frühen Entwicklungsphasen vor.
Sie müssen jetzt entscheiden, ob alle Ihre AUTO-Joins während eines Beziehungswechsels blockieren, um der Absicht Ihrer select-Anweisung zu entsprechen.
quelle
Teile des Grundes sind:
1 - Theoretisch können Sie Tabellen in beliebigen Spalten aus den beiden Tabellen verbinden. Dies ist zwar keine gängige Praxis, aber gültig. Denken Sie daran, dass SQL wie eine Programmiersprache ist und nicht versteht, welche Informationen sich in den Spalten befinden, und dass Namen für SQL diesbezüglich nicht viel bedeuten.
2 - Es gibt verschiedene Arten von Verknüpfungen (links, rechts, innen) - Inner Joins ist nur eine davon.
3 - Der SQL-Standard kann sich an dem Prinzip orientieren, dass es sich um eine Sprache auf niedrigerer Ebene handelt, die es Dialekten auf höherer Ebene ermöglicht, damit Intelligenz zu bilden. Der Vergleich ist etwas klarer, wenn Sie an eine Sprache der 4. Generation im Vergleich zu einer Sprache der 3. Generation denken. In der Tat erlaubte Ihnen ein Tool, das ich verwendet habe, IEF, so etwas zu schreiben:
Zusammenfassend ist Ihr Vorschlag interessant und könnte entweder als Teil des Standards oder als gespeicherte Prozedur implementiert werden (standardmäßig wäre dies ein Inner Join).
quelle
Tiddo, ich glaube, Sie haben vollkommen recht, SQL zu diesem Thema ist ziemlich dumm , und ich erinnere mich, dass ich das Gleiche über Fremdschlüssel gedacht habe, als Sie vor zehn Jahren SQL gelernt haben.
Ok, angesichts dessen musste ich schließlich diese Prüfung bestehen; und um es zu bestehen, musste ich loslassen . SQL ist eher ein Zugunglück als irgendjemand zugeben dürfte, sein Standardisierungspfad ist eine völlige Katastrophe, und einige Implementierungen sind bedrohlich abgeschlossen . Trotzdem ist es im Allgemeinen recht praktisch. (Ich bin kein K / V-Luddit)
Fremdschlüssel also ... gar nicht so praktisch. Sie sind ein wichtiges Konzept im relationalen Modell , aber die gleichnamige SQL-Funktion lässt sich nicht gut vergleichen.
Sagen Sie gerade: nicht , dass die SQL - Funktion namens verwenden
Foreign Key
überhaupt , bis Sie einen großen System mit Performance - Problemen betroffen. Explizit den Motor zu sagen , das Feld ein Fremdschlüssel ist und welches nicht wird nur für die Indizierung verwendet, und es ist unsichtbar für den Benutzer db.Ist es irreführend?
Ja.
Werden sie es jetzt, nach 30 Jahren irregeführter Menschen, noch mächtiger machen?
Keine Chance.
Völlig ignoriert Fremdschlüssel bis notwendig ... feste SQL für mich?
Ja!
Und warum zum Teufel ist das alles überhaupt passiert?
Nun, die Funktion , die wir als Fremdschlüssel bezeichnen, wurde später zu SQL hinzugefügt. SQL ist ein Standard, der sich im Laufe der Zeit von unten nach oben entwickelt hat. Die Hersteller haben lächerliche Funktionen implementiert, während die Standardkörper mit Handflächen versehen sind.
Wie bereits erwähnt, waren Fremdschlüssel nur für die Indizierung gedacht und es war kein JOIN-Konstrukt verfügbar. (Verknüpfungen wurden mit
SELECT
Abfragen erstellt.JOIN
Abfragen sind relativ neu und nur für die Alias-SELECT
Funktionalität gedacht. ) Wahrscheinlich war das Aufrufen dieses IndizierungsflagsFOREIGN KEY
ein cleverer Namens-Hack gegenüber Konzepten der relationalen Datenbank-Theorie.quelle