Soweit ich weiß, werden Fremdschlüssel (FK) verwendet, um dem Programmierer zu helfen, Daten auf die richtige Weise zu bearbeiten. Angenommen, ein Programmierer tut dies tatsächlich bereits auf die richtige Weise. Brauchen wir dann wirklich das Konzept der Fremdschlüssel?
Gibt es andere Verwendungszwecke für Fremdschlüssel? Vermisse ich hier etwas?
database
oracle
foreign-keys
Niyaz
quelle
quelle
Antworten:
Fremdschlüssel helfen dabei, die referenzielle Integrität auf Datenebene durchzusetzen. Sie verbessern auch die Leistung, da sie normalerweise standardmäßig indiziert sind.
quelle
Fremdschlüssel können dem Programmierer auch helfen, weniger Code mit Dingen wie zu schreiben
ON DELETE CASCADE
. Dies bedeutet, dass wenn Sie eine Tabelle mit Benutzern und eine andere mit Bestellungen oder Ähnlichem haben, das Löschen eines Benutzers automatisch alle Bestellungen löschen kann, die auf diesen Benutzer verweisen.quelle
Ich kann mir nicht vorstellen, eine Datenbank ohne Fremdschlüssel zu entwerfen. Ohne sie müssen Sie möglicherweise einen Fehler machen und die Integrität Ihrer Daten beschädigen.
Sie sind streng genommen nicht erforderlich , aber die Vorteile sind enorm.
Ich bin ziemlich sicher, dass FogBugz keine Fremdschlüsseleinschränkungen in der Datenbank hat. Es würde mich interessieren, wie das Fog Creek Software- Team seinen Code strukturiert, um sicherzustellen, dass niemals Inkonsistenzen auftreten.
quelle
Ein Datenbankschema ohne FK-Einschränkungen ist wie das Fahren ohne Sicherheitsgurt.
Eines Tages wirst du es bereuen. Wenn Sie nicht so wenig zusätzliche Zeit für die Grundlagen des Designs und die Datenintegrität aufwenden, können Sie später sicher Kopfschmerzen bekommen.
Würden Sie Code in Ihrer Anwendung akzeptieren, der so schlampig war? Das hat direkt auf die Mitgliedsobjekte zugegriffen und die Datenstrukturen direkt geändert.
Warum ist dies Ihrer Meinung nach in modernen Sprachen schwierig und sogar inakzeptabel geworden ?
quelle
Ja.
ON DELETE CASCADE
quelle
Eine solche Annahme zu machen, scheint mir eine äußerst schlechte Idee zu sein; Im Allgemeinen ist Software phänomenal fehlerhaft.
Und genau darum geht es wirklich. Entwickler können die Dinge nicht richtig machen, daher ist es eine gute Sache, sicherzustellen, dass die Datenbank nicht mit schlechten Daten gefüllt werden kann.
Obwohl in einer idealen Welt natürliche Verknüpfungen Beziehungen (dh FK-Einschränkungen) verwenden würden, anstatt mit Spaltennamen übereinzustimmen. Dies würde FKs noch nützlicher machen.
quelle
Persönlich bin ich für Fremdschlüssel, weil dies die Beziehung zwischen den Tabellen formalisiert. Mir ist klar, dass Ihre Frage voraussetzt, dass der Programmierer keine Daten einführt, die die referenzielle Integrität verletzen würden, aber ich habe viel zu viele Fälle gesehen, in denen die referenzielle Datenintegrität trotz bester Absichten verletzt wird!
Vor-Fremdschlüssel-Einschränkungen (auch als deklarative referenzielle Integrität oder DRI bezeichnet) wurden viel Zeit für die Implementierung dieser Beziehungen mithilfe von Triggern aufgewendet. Die Tatsache, dass wir die Beziehung durch eine deklarative Einschränkung formalisieren können, ist sehr mächtig.
@John - Andere Datenbanken erstellen möglicherweise automatisch Indizes für Fremdschlüssel, SQL Server jedoch nicht. In SQL Server sind Fremdschlüsselbeziehungen nur Einschränkungen. Sie müssen Ihren Index für Fremdschlüssel separat definieren (was von Vorteil sein kann).
Bearbeiten: Ich möchte hinzufügen, IMO, die Verwendung von Fremdschlüsseln zur Unterstützung von ON DELETE oder ON UPDATE CASCADE ist nicht unbedingt eine gute Sache. In der Praxis habe ich festgestellt, dass die Kaskade beim Löschen basierend auf der Beziehung der Daten sorgfältig abgewogen werden sollte - z. B. haben Sie ein natürliches Eltern-Kind, bei dem dies in Ordnung sein kann, oder ist die zugehörige Tabelle eine Reihe von Suchwerten. Wenn Sie kaskadierte Updates verwenden, müssen Sie zulassen, dass der Primärschlüssel einer Tabelle geändert wird. In diesem Fall habe ich eine allgemeine philosophische Meinungsverschiedenheit dahingehend, dass sich der Primärschlüssel einer Tabelle nicht ändern sollte. Schlüssel sollten von Natur aus konstant sein.
quelle
Wie können Sie ohne Fremdschlüssel feststellen, dass zwei Datensätze in verschiedenen Tabellen verknüpft sind?
Ich denke, Sie beziehen sich auf die referenzielle Integrität, bei der der untergeordnete Datensatz nicht ohne einen vorhandenen übergeordneten Datensatz usw. erstellt werden darf. Diese werden häufig als Fremdschlüsseleinschränkungen bezeichnet - sind jedoch nicht mit dem Vorhandensein von Fremdschlüsseln in zu verwechseln den ersten Platz.
quelle
Gibt es einen Vorteil, wenn Sie keine Fremdschlüssel haben? Wenn Sie keine beschissene Datenbank verwenden, sind FKs nicht so schwer einzurichten. Warum sollten Sie sie vermeiden? Es ist eine Sache, eine Namenskonvention zu haben, die besagt, dass eine Spalte auf eine andere verweist, und eine andere, zu wissen, dass die Datenbank diese Beziehung tatsächlich für Sie überprüft.
quelle
Ich nehme an, Sie sprechen von Fremdschlüsseleinschränkungen, die von der Datenbank erzwungen werden . Sie verwenden wahrscheinlich bereits Fremdschlüssel, Sie haben der Datenbank nur nichts davon erzählt.
Theoretisch nein. Es gab jedoch noch nie eine Software ohne Fehler.
Fehler im Anwendungscode sind normalerweise nicht so gefährlich - Sie identifizieren den Fehler und beheben ihn. Danach läuft die Anwendung wieder reibungslos. Aber wenn ein Fehler zulässt, dass aktuelle Daten in die Datenbank gelangen, bleiben Sie dabei! Es ist sehr schwierig, beschädigte Daten in der Datenbank wiederherzustellen.
Überlegen Sie, ob ein subtiler Fehler in FogBugz das Schreiben eines beschädigten Fremdschlüssels in die Datenbank ermöglichte. Es kann einfach sein, den Fehler zu beheben und den Fix in einer Bugfix-Version schnell an Kunden weiterzuleiten. Wie sollten jedoch die beschädigten Daten in Dutzenden von Datenbanken behoben werden? Der richtige Code kann jetzt plötzlich kaputt gehen, da die Annahmen über die Integrität von Fremdschlüsseln nicht mehr gelten.
In Webanwendungen spricht normalerweise nur ein Programm mit der Datenbank, sodass es nur einen Ort gibt, an dem Fehler die Daten beschädigen können. In einer Unternehmensanwendung können mehrere unabhängige Anwendungen mit derselben Datenbank sprechen (ganz zu schweigen von Personen, die direkt mit der Datenbankshell arbeiten). Es gibt keine Möglichkeit, sicher zu sein, dass alle Anwendungen immer und für immer denselben Fehlern ohne Fehler folgen.
Wenn Einschränkungen in der Datenbank codiert sind, kann das Schlimmste, was bei Fehlern passieren kann, sein, dass dem Benutzer eine hässliche Fehlermeldung angezeigt wird, dass eine SQL- Einschränkung nicht erfüllt ist. Dies ist viel besser, als aktuelle Daten in Ihre Unternehmensdatenbank zu lassen, wo sie wiederum alle Ihre Anwendungen beschädigen oder einfach zu allen Arten von falschen oder irreführenden Ausgaben führen.
Oh, und Fremdschlüsseleinschränkungen verbessern auch die Leistung, da sie standardmäßig indiziert sind. Ich kann mir keinen Grund vorstellen , keine Fremdschlüsseleinschränkungen zu verwenden.
quelle
FKs sind sehr wichtig und sollten immer in Ihrem Schema vorhanden sein, es sei denn, Sie sind eBay .
quelle
unibrow
Ich denke, irgendwann muss eine einzige Sache für die Sicherstellung gültiger Beziehungen verantwortlich sein.
Beispielsweise verwendet Ruby on Rails keine Fremdschlüssel, überprüft jedoch alle Beziehungen selbst. Wenn Sie immer nur von dieser Ruby on Rails-Anwendung auf Ihre Datenbank zugreifen, ist dies in Ordnung.
Wenn Sie jedoch andere Clients haben, die in die Datenbank schreiben, müssen diese ohne Fremdschlüssel ihre eigene Validierung implementieren. Sie haben dann zwei Kopien des Validierungscodes, die höchstwahrscheinlich unterschiedlich sind und die jeder Programmierer als Hauptsünde erkennen sollte.
Zu diesem Zeitpunkt sind Fremdschlüssel wirklich erforderlich, da Sie damit die Verantwortung wieder auf einen einzelnen Punkt verlagern können.
quelle
Mit Fremdschlüsseln kann jemand, der Ihre Datenbank noch nicht gesehen hat, die Beziehung zwischen Tabellen bestimmen.
Jetzt mag alles in Ordnung sein, aber denken Sie daran, was passieren wird, wenn Ihr Programmierer geht und jemand anderes übernehmen muss.
Mit Fremdschlüsseln können sie die Datenbankstruktur verstehen, ohne Tausende von Codezeilen durchsuchen zu müssen.
quelle
Mit FKs kann der DBA die Datenintegrität vor dem Fummeln von Benutzern schützen, wenn der Programmierer dies nicht tut, und manchmal vor dem Fummeln von Programmierern schützen.
Programmierer sind sterblich und fehlbar. FKs sind deklarativ , was es schwieriger macht, sie zu vermasseln .
Obwohl dies nicht der Grund ist, warum sie erstellt wurden, bieten FKs starke zuverlässige Hinweise auf Diagrammwerkzeuge und Abfrage-Builder. Dies wird an Endbenutzer weitergegeben, die dringend zuverlässige Hinweise benötigen.
quelle
Sie sind nicht unbedingt erforderlich, da Sicherheitsgurte nicht unbedingt erforderlich sind. Aber sie können dich wirklich davor bewahren, etwas Dummes zu tun, das deine Datenbank durcheinander bringt.
Es ist so viel schöner, einen FK-Einschränkungsfehler zu debuggen, als einen Löschvorgang zu rekonstruieren, der Ihre Anwendung beschädigt hat.
quelle
Sie sind wichtig, da Ihre Anwendung nicht die einzige Möglichkeit ist, Daten in der Datenbank zu bearbeiten. Ihre Anwendung kann die referenzielle Integrität so ehrlich behandeln, wie sie möchte, aber es ist nur ein Bozo mit den richtigen Berechtigungen erforderlich, um einen Befehl zum Einfügen, Löschen oder Aktualisieren auf Datenbankebene auszugeben, und die Durchsetzung der referenziellen Integrität Ihrer Anwendung wird umgangen. Das Einfügen von FK-Einschränkungen auf Datenbankebene bedeutet, dass die FK-Einschränkung, sofern dieser Bozo die FK-Einschränkung nicht deaktiviert, bevor der Befehl ausgegeben wird, dazu führt, dass eine fehlerhafte Anweisung zum Einfügen / Aktualisieren / Löschen mit einer Verletzung der referenziellen Integrität fehlschlägt.
quelle
Ich denke darüber in Bezug auf Kosten / Nutzen nach ... In MySQL ist das Hinzufügen einer Einschränkung eine einzelne zusätzliche Zeile von DDL . Es sind nur eine Handvoll Schlüsselwörter und ein paar Sekunden Nachdenken. Das sind meiner Meinung nach die einzigen "Kosten" ...
Werkzeuge lieben Fremdschlüssel. Fremdschlüssel verhindern fehlerhafte Daten (dh verwaiste Zeilen), die die Geschäftslogik oder -funktionalität möglicherweise nicht beeinträchtigen und daher unbemerkt bleiben und sich aufbauen. Außerdem wird verhindert, dass Entwickler, die mit dem Schema nicht vertraut sind, ganze Arbeitsblöcke implementieren, ohne zu bemerken, dass ihnen eine Beziehung fehlt. Vielleicht ist im Rahmen Ihrer aktuellen Anwendung alles großartig, aber wenn Sie etwas verpasst haben und eines Tages etwas Unerwartetes hinzugefügt wird (denken Sie an ausgefallene Berichte), befinden Sie sich möglicherweise an einem Ort, an dem Sie fehlerhafte Daten, die sich seit dem Start angesammelt haben, manuell bereinigen müssen des Schemas ohne Datenbank erzwungene Prüfung.
Die geringe Zeit, die benötigt wird, um zu kodifizieren, was sich beim Zusammenstellen bereits in Ihrem Kopf befindet, könnte Ihnen oder jemand anderem ein paar Monate oder Jahre später Trauer ersparen.
Die Frage:
Es ist ein bisschen geladen. Fügen Sie anstelle von "Fremdschlüsseln" Kommentare, Einrückungen oder Variablennamen ein ... Wenn Sie die betreffende Sache bereits perfekt verstehen, ist dies für Sie "nutzlos".
quelle
Entropiereduktion. Reduzieren Sie das Potenzial für chaotische Szenarien in der Datenbank. Wir haben es schwer, da alle Möglichkeiten in Betracht gezogen werden. Meiner Meinung nach ist die Reduzierung der Entropie der Schlüssel zur Wartung eines Systems.
Wenn wir zum Beispiel eine Annahme machen: Jede Bestellung hat einen Kunden, dass die Annahme durch etwas erzwungen werden sollte . In Datenbanken ist "etwas" ein Fremdschlüssel.
Ich denke, das ist den Kompromiss bei der Entwicklungsgeschwindigkeit wert. Sicher, Sie können schneller mit ihnen codieren, und dies ist wahrscheinlich der Grund, warum manche Leute sie nicht verwenden. Persönlich habe ich einige Stunden mit NHibernate und einigen Fremdschlüsseleinschränkungen getötet, die wütend werden, wenn ich eine Operation durchführe. Ich weiß jedoch, was das Problem ist, also ist es weniger ein Problem. Ich benutze normale Tools und es gibt Ressourcen, die mir helfen, das zu umgehen, möglicherweise sogar Leute, die mir helfen!
Die Alternative besteht darin, zuzulassen, dass sich ein Fehler in das System einschleicht (und dies bei ausreichender Zeit), wenn kein Fremdschlüssel festgelegt ist und Ihre Daten inkonsistent werden. Dann erhalten Sie einen ungewöhnlichen Fehlerbericht, untersuchen und "OH". Die Datenbank ist verschraubt. Wie lange wird es dauern, bis das Problem behoben ist?
quelle
Sie können Fremdschlüssel als Einschränkung anzeigen, die,
quelle
Wir verwenden derzeit keine Fremdschlüssel. Und zum größten Teil bereuen wir es nicht.
Das heißt - wir werden sie wahrscheinlich in naher Zukunft aus mehreren Gründen viel häufiger einsetzen, beide aus ähnlichen Gründen:
Diagramme. Es ist so viel einfacher, ein Diagramm einer Datenbank zu erstellen, wenn Fremdschlüsselbeziehungen korrekt verwendet werden.
Werkzeugunterstützung. Es ist viel einfacher, Datenmodelle mit Visual Studio 2008 zu erstellen, die für LINQ to SQL verwendet werden können, wenn geeignete Fremdschlüsselbeziehungen bestehen.
Mein Punkt ist also, dass wir festgestellt haben, dass Fremdschlüssel nicht unbedingt erforderlich sind, wenn wir viel manuelle SQL-Arbeit (Konstruktionsabfrage, Abfrage ausführen, blahblahblah) ausführen. Sobald Sie jedoch mit der Verwendung von Tools beginnen, werden diese viel nützlicher.
quelle
Das Beste an Fremdschlüsseleinschränkungen (und Einschränkungen im Allgemeinen) ist, dass Sie sich beim Schreiben Ihrer Abfragen auf sie verlassen können. Viele Abfragen können viel komplizierter werden, wenn Sie sich nicht darauf verlassen können, dass das Datenmodell "true" enthält.
Im Code wird im Allgemeinen nur irgendwo eine Ausnahme ausgelöst - in SQL erhalten wir im Allgemeinen nur die "falschen" Antworten.
Theoretisch könnte SQL Server Einschränkungen als Teil eines Abfrageplans verwenden - aber abgesehen von Überprüfungsbeschränkungen für die Partitionierung kann ich nicht sagen, dass ich das jemals tatsächlich gesehen habe.
quelle
Fremdschlüssel waren in Projekten (Geschäftsanwendungen und Websites für soziale Netzwerke), an denen ich gearbeitet habe, nie explizit angegeben worden (Tabelle FOREIGN KEY REFERENCES (Spalte)).
Aber es gab immer eine Art Konvention, Spalten zu benennen, die Fremdschlüssel waren.
Es ist wie bei der Datenbanknormalisierung - Sie müssen wissen, was Sie tun und was die Folge davon ist (hauptsächlich Leistung).
Ich bin mir der Vorteile von Fremdschlüsseln bewusst (Datenintegrität, Index für Fremdschlüsselspalten, Tools, die das Datenbankschema kennen), aber ich habe auch Angst, Fremdschlüssel als allgemeine Regel zu verwenden.
Außerdem können verschiedene Datenbankmodule Fremdschlüssel auf unterschiedliche Weise bereitstellen, was zu subtilen Fehlern während der Migration führen kann.
Das Entfernen aller Bestellungen und Rechnungen eines gelöschten Kunden mit ON DELETE CASCADE ist das perfekte Beispiel für ein gut aussehendes, aber falsch gestaltetes Datenbankschema.
quelle
Ja. Das ON DELETE [RESTRICT | CASCADE] verhindert, dass Entwickler Daten stranden, und hält die Daten sauber. Ich bin kürzlich einem Team von Rails-Entwicklern beigetreten, die sich nicht auf Datenbankeinschränkungen wie Fremdschlüssel konzentriert haben.
Zum Glück habe ich diese gefunden: http://www.redhillonrails.org/foreign_key_associations.html - RedHill on Ruby on Rails-Plug-Ins generieren Fremdschlüssel mithilfe der Konvention über den Konfigurationsstil . Eine Migration mit product_id einen Fremdschlüssel für die erstellen - ID in der Produkte - Tabelle.
Schauen Sie sich die anderen großartigen Plug-Ins bei RedHill an , einschließlich Migrationen, die in Transaktionen eingeschlossen sind.
quelle
Wenn Sie vorhaben, Ihren Datenzugriffscode, dh Entity Framework oder ein anderes ORM, zu generieren, verlieren Sie die Möglichkeit, ein hierarchisches Modell ohne Fremdschlüssel zu generieren
quelle