Soll ich die Beziehungen zwischen Tabellen in der Datenbank oder nur im Code definieren?


60

Nach meiner Erfahrung enthielten viele der Projekte, die ich in der Vergangenheit gelesen habe, keine Beziehungsdefinitionen in der Datenbank, sondern sie definierten sie nur im Quellcode. Ich frage mich also, welche Vor- und Nachteile es hat, Beziehungen zwischen Tabellen in der Datenbank und im Quellcode zu definieren. Und die umfassendere Frage betrifft andere erweiterte Funktionen in modernen Datenbanken wie Kaskaden, Trigger, Prozeduren ... In meinen Gedanken gibt es einige Punkte:

In der Datenbank:

  • Korrigieren Sie Daten aus dem Design. Verhindern Sie Anwendungsfehler, die ungültige Daten verursachen können.

  • Reduzieren Sie den Netzwerk-Roundtrip zur Anwendung beim Einfügen / Aktualisieren von Daten, da die Anwendung mehr Abfragen durchführen muss, um die Datenintegrität zu überprüfen.

Im Quellcode:

  • Flexibler.

  • Besser bei der Skalierung auf mehrere Datenbanken, da die Beziehung manchmal datenbankübergreifend sein kann.

  • Mehr Kontrolle über die Datenintegrität. Die Datenbank muss nicht jedes Mal überprüft werden, wenn die Anwendung Daten ändert (Komplexität kann O (n) oder O (n log n) (?) Sein). Stattdessen wird es an die Anwendung delegiert. Und ich denke, der Umgang mit der Datenintegrität in der Anwendung führt zu ausführlicheren Fehlermeldungen als die Verwendung der Datenbank. Beispiel: Wenn Sie einen API-Server erstellen, die Beziehungen in der Datenbank definieren und ein Fehler auftritt (z. B. dass die Entität, auf die verwiesen wird, nicht vorhanden ist), wird eine SQL-Ausnahme mit einer Meldung angezeigt. Die einfache Möglichkeit besteht darin, 500 an den Client zurückzugeben, wenn ein "Interner Serverfehler" vorliegt und der Client keine Ahnung hat, was falsch läuft. Oder der Server kann die Nachricht analysieren, um herauszufinden, was falsch ist, was meiner Meinung nach eine hässliche, fehleranfällige Methode ist. Wenn Sie dies der Anwendung überlassen,

Gibt es noch etwas?

Bearbeiten: Wie Kilian betont, ist mein Standpunkt zu Leistung und Datenintegrität sehr falsch. Also habe ich bearbeitet, um meinen Punkt dort zu korrigieren. Ich verstehe vollkommen, dass es effizienter und robuster sein wird, wenn die Datenbank damit umgeht. Bitte überprüfen Sie die aktualisierte Frage und denken Sie darüber nach.

Edit: danke euch allen. Die Antworten, die ich erhalten habe, weisen alle darauf hin, dass die Einschränkungen / Beziehungen in der Datenbank definiert werden sollten. :). Ich habe noch eine Frage, da diese Frage nicht in den Geltungsbereich dieser Frage fällt. Ich habe sie gerade als separate Frage veröffentlicht: Behandle Datenbankfehler für API-Server . Bitte hinterlassen Sie einige Einblicke.


4
"Da die Anwendung mehr Abfragen durchführen muss, um die Datenintegrität zu überprüfen." Nicht unbedingt. Wenn die Datenbank vollständig von Ihrer Anwendung kontrolliert wird, kann eine zusätzliche Überprüfung der Datenintegrität zu einer übermäßig defensiven Programmierung führen. Sie brauchen sie nicht unbedingt; Testen Sie einfach Ihre Anwendung entsprechend, um sicherzustellen, dass sie nur gültige Änderungen an der Datenbank vornimmt.

9
Eines sollten Sie niemals vergessen: Wenn nicht alle Beteiligten perfekte Software schreiben und die Überprüfungen in der Software sind, schlägt eine dieser Überprüfungen fehl und führt dazu, dass Einschränkungen nicht durchgesetzt werden. Es geht nicht darum, ob, sondern wann. Dies führt dazu, dass sich Fehler nur schwer reproduzieren lassen und die Daten stundenlang massiert werden, um sie wieder an die durch die Software erzwungenen Einschränkungen anzupassen.
Dabu

10
Erwähnenswertes: Sobald Sie Integritätsprobleme in Ihre Datenbank aufgenommen haben, kann die Büchse der Pandora geöffnet werden. Es ist ein Albtraum, die Integrität einer von Anomalien geprägten Datenbank wiederherzustellen. Strenge Kontrollen in Ihrer Datenbank sind zwar mühsam, ersparen Ihnen aber auf lange Sicht eine Menge Schmerzen.
DanK

3
Im Quellcode: Schließlich schreiben Sie den größten Teil einer Datenbank.
Blrfl

7
Ich habe einmal einem sehr talentierten Programmierer eine ähnliche Frage gestellt, die er mir sagte: "Es ist wie Bremsen an einem Auto. Es geht nicht darum, das Auto langsamer zu machen, sondern es schneller und sicherer fahren zu lassen." Sicher ist es möglich, ohne Einschränkungen zu laufen, aber wenn schlechte Daten irgendwie reinkommen, kann es zu einem schweren Absturz kommen
mercurial

Antworten:


70

TL; DR: Beziehungseinschränkungen sollten in die Datenbank aufgenommen werden.


Ihre Bewerbung ist nicht groß genug.

Sie haben in der Tat Recht, dass für die Erzwingung von Beziehungen zwischen Datenbanken diese möglicherweise in der Anwendung erzwungen werden müssen.

Ich möchte Sie jedoch darauf hinweisen, dass Sie zuerst die Dokumentation der von Ihnen verwendeten Datenbanksoftware und die vorhandenen Produktangebote überprüfen sollten. Beispielsweise gibt es Clustering-Angebote zusätzlich zu Postgres und MySQL.

Und selbst wenn Sie am Ende brauchen haben einige Validierung in der Anwendung, wirft das Kind mit dem Badewasser nicht aus . Denn je weniger Sie tun müssen, desto besser geht es Ihnen.

Wenn Sie sich Sorgen über zukünftige Skalierbarkeitsprobleme machen, befürchte ich, dass Ihre Anwendung erhebliche Änderungen erfahren muss, bevor sie trotzdem skaliert werden kann. Als Faustregel gilt, dass Sie jedes Mal, wenn Sie 10-fach wachsen, neu designen müssen. Lassen Sie uns also nicht zu viel Geld darauf verwenden, Skalierbarkeitsprobleme nicht zu antizipieren, und verwenden Sie stattdessen Geld, um tatsächlich den Punkt zu erreichen, an dem Sie diese Probleme haben.

Ihre Bewerbung ist nicht korrekt genug.

Wie groß ist die Wahrscheinlichkeit, dass die von Ihnen verwendete Datenbank die Prüfung fehlerhaft implementiert hat, im Vergleich zu der Wahrscheinlichkeit, dass Ihre Anwendung die Prüfung fehlerhaft implementiert hat?

Und welches ändern Sie am häufigsten?

Ich würde wetten, dass die Datenbank jederzeit korrekt ist .

Ihre Entwickler denken nicht genug verteilt.

Reduzieren Sie das Netzwerk-Roundtrip zur Anwendung, wenn Sie Daten einfügen / aktualisieren, da die Anwendung mehr Abfragen durchführen muss, um die Datenintegrität zu überprüfen.

Rote Fahne ! 1

Wenn Sie denken:

  • Überprüfen Sie, ob der Datensatz vorhanden ist
  • Wenn nicht, Datensatz einfügen

dann du versagt die grundlegendsten Concurrency Problem: ein anderer Prozess / Thread kann den Datensatz werden , indem , wie Sie gehen.

Wenn Sie denken:

  • Überprüfen Sie, ob der Datensatz vorhanden ist
  • Wenn nicht, Datensatz einfügen
  • Überprüfen Sie, ob der Datensatz als Duplikat eingefügt wurde

Dann haben Sie MVCC nicht berücksichtigt: Die Ansicht der Datenbank, die Sie haben, ist eine Momentaufnahme, als Ihre Transaktion gestartet wurde. Es werden nicht alle Updates angezeigt, die ausgeführt werden, und möglicherweise werden sie nicht einmal festgeschrieben.

Das Aufrechterhalten von Einschränkungen über mehrere Sitzungen hinweg ist ein wirklich schweres Problem. Seien Sie froh, dass es in Ihrer Datenbank gelöst ist.

1 Sofern Ihre Datenbank die Serializable-Eigenschaft nicht ordnungsgemäß implementiert. aber nur wenige tun es tatsächlich.


Zuletzt:

Und ich denke, mit Datenintegrität in der Anwendung wird es zu einer ausführlicheren Fehlermeldung kommen als mit Datenbank. Beispiel: Wenn Sie einen API-Server erstellen. Wenn Sie Beziehungen in der Datenbank definieren und ein Fehler auftritt (z. B. dass die referenzierte Entität nicht vorhanden ist), wird eine SQL-Ausnahme mit der Meldung angezeigt.

Analysieren Sie keine Fehlermeldungen . Wenn Sie eine Datenbank mit Produktionsqualität verwenden, sollte diese strukturierte Fehler zurückgeben. Sie werden zumindest einen Fehlercode haben, um anzuzeigen, was möglicherweise falsch ist, und basierend auf diesem Code können Sie eine geeignete Fehlermeldung erstellen.

Beachten Sie, dass der Code in den meisten Fällen ausreicht: Wenn Sie einen Fehlercode haben, der besagt, dass ein referenzierter Fremdschlüssel nicht vorhanden ist, ist es wahrscheinlich, dass diese Tabelle nur einen Fremdschlüssel enthält, sodass Sie im Code wissen, um welches Problem es sich handelt .

Und, um ehrlich zu sein, meistens werden Sie Fehler sowieso nicht so anmutig handhaben. Nur weil es so viele davon gibt und du nicht für alle verantwortlich bist ...

... was nur mit dem obigen Korrektheitspunkt zusammenhängt . Jedes Mal, wenn ein "500: Internal Server Error" angezeigt wird, weil eine Datenbankeinschränkung ausgelöst wurde und nicht verarbeitet wurde, bedeutet dies, dass die Datenbank Sie gespeichert hat, da Sie nur vergessen haben, sie im Code zu verarbeiten.


3
Haha, Sie haben das geschrieben, als ich meinen Kommentar schrieb, ironischerweise unterstrichen Sie den Punkt, den wir beide ansprechen. Ich stimme vollkommen zu: Sie können nicht einmal Integrität oder Einschränkungen in Nicht-DB-Code ausführen. Transaktionen können die Ergebnisse anderer erst sehen, wenn sie festgeschrieben sind (und selbst dann vielleicht nicht). Möglicherweise wird die Illusion von Integrität erzeugt, doch aufgrund von Sperren kann es zu zeitlichen oder schwerwiegenden Problemen mit der Skalierbarkeit kommen. Nur die Datenbank kann dies korrekt ausführen.
LoztInSpace

8
Alles gute Punkte. Zum anderen sind Beziehungen in einer Datenbank selbstdokumentierend. Wenn Sie jemals eine Datenbank rekonstruieren mussten, deren Beziehungen nur im Code definiert wurden, der sie abfragt, hassen Sie jeden, der dies tut.
Kat

1
@ Kat11: Das stimmt. Selbstbeschreibend hat auch den Vorteil, dass Tools die Daten leicht verstehen und darauf reagieren können, was manchmal nützlich sein kann.
Matthieu M.

1
Ihr Argument zu MVCC ist in DBs, die die SERIALIZABLE-Isolation korrekt implementieren, nicht korrekt (moderne Versionen von PostgreSQL beispielsweise - obwohl viele wichtige RDBMS dies nicht tun). In einer solchen Datenbank würde sogar der erste, naive Ansatz korrekt funktionieren. Wenn Schreibkonflikte auftreten, werden diese als Serialisierungsfehler zurückgesetzt.
James_pic

1
Wenn Sie in DBs, die SERIALIZABLE korrekt implementieren, alle erfolgreich festgeschriebenen Transaktionen annehmen, gibt es eine gewisse Reihenfolge (die möglicherweise nicht mit der Wall-Clock-Reihenfolge identisch ist), sodass Sie alle seriell ausgeführt hätten (ohne Parallelität). in dieser reihenfolge wären alle ergebnisse exakt gleich geblieben. Es ist schwierig, es richtig zu machen, und die SQL-Spezifikationen sind vage genug, dass Sie sich davon überzeugen können, dass es in Ordnung ist, Schreibverzerrungen auf SERIALIZABLE-Ebene zuzulassen.
James_pic

119

Die Datenbank muss nicht jedes Mal, wenn eine Anwendung Daten ändert, auf Datenintegrität prüfen.

Dies ist ein zutiefst fehlgeleiteter Punkt. Genau zu diesem Zweck wurden Datenbanken erstellt. Wenn Sie Datenintegritätsprüfungen benötigen (und wenn Sie glauben, dass Sie diese nicht benötigen, irren Sie sich wahrscheinlich), ist es mit ziemlicher Sicherheit effizienter und weniger fehleranfällig, wenn die Datenbank sie verarbeitet, als dies in der Anwendungslogik der Fall ist.


5
@ dan1111 Ich verstehe Ihren Kommentar nicht ... Wollen Sie damit sagen: Einfache Einschränkungen werden von der Datenbank erzwungen, sodass sie für den Anwendungscode kein Problem darstellen. Komplexere Einschränkungen sind zu schwer zu implementieren. Geben Sie sie einfach auf. Oder sagen Sie, dass das Implementieren komplexer Einschränkungen mit Hilfe von Datenbank-Triggern (und ähnlichen Mechanismen) zu komplex ist und es daher besser ist, sie im Anwendungscode zu implementieren?
Bakuriu

47
Sie können nicht einmal Integrität oder Einschränkungen in Nicht-DB-Code ausführen. Transaktionen können die Ergebnisse anderer erst sehen, wenn sie festgeschrieben sind (und selbst dann vielleicht nicht). Möglicherweise wird die Illusion von Integrität erzeugt, doch aufgrund von Sperren kann es zu zeitlichen oder schwerwiegenden Problemen mit der Skalierbarkeit kommen. Nur die Datenbank kann dies korrekt ausführen.
LoztInSpace

17
Um an @ LoztInSpaces Kommentar anzuknüpfen, habe ich einmal für eine (schreckliche) Firma gearbeitet, in der eine dieser Tabellen so eingerichtet war, dass die Anwendung die ID nicht automatisch inkrementierte, sondern die ID der letzten Zeilen annahm. hat eine hinzugefügt und diese als neue ID verwendet. Leider wurden ungefähr einmal pro Woche doppelte IDs eingefügt, was den Absturz der Anwendung zum Stillstand brachte.
Trotski94

9
@ dan1111 Du schreibst nie Fehler in die Anwendung, oder?
user253751

4
@DavidPacker Möglicherweise stimme ich zu. Wenn jedoch mehrere Clients auf die Datenbank zugreifen, können Sie nur Einschränkungen in der Datenbank erzwingen. Es sei denn, Sie sperren Tabellen nicht nach Zeilen, sondern nach dem Leistungsverlust, den sie mit sich bringen.
Iker

51

Die Einschränkungen sollten in Ihrer Datenbank liegen, da (mit dem besten Willen der Welt) Ihre Anwendung nicht die einzige sein wird, die jemals auf diese Datenbank zugreift.

Irgendwann muss möglicherweise ein Skript in der Datenbank installiert werden, oder Sie müssen möglicherweise Daten bei der Bereitstellung von einer Tabelle in eine andere migrieren.

Darüber hinaus können Sie weitere Anforderungen haben, z. B. "Großkunde X benötigt dieses Excel-Datenblatt, das heute Nachmittag in unsere Anwendungsdatenbank importiert wird". Hier haben Sie nicht den Luxus, Ihren Anwendungscode an die Anforderungen eines unsauberen SQL-Skripts anzupassen rechtzeitig.

Hier spart die Integrität auf Datenbankebene Ihren Speck.


Stellen Sie sich außerdem den Entwickler vor, der Ihre Rolle bei diesem Unternehmen übernimmt, nachdem Sie das Unternehmen verlassen haben, und der dann damit beauftragt ist, Datenbankänderungen vorzunehmen.

Hasst er Sie, wenn die Datenbank keine FK-Einschränkungen enthält, damit er erkennen kann, welche Beziehungen eine Tabelle hat, bevor er sie ändert? ( Hinweis, die Antwort ist ja )


33
Oh Bruder. Ich kann Ihnen nicht sagen, wie oft ich den Leuten erklären musste, dass eine Datenbank mehr als einen Client hat! Auch wenn jetzt nur ein Client ist und nur ein Weg für die Daten in das System eindringen, basiert Ihre Anwendung und das Schema der Gestaltung dieser Annahme ist der beste Weg für zukünftige Yoshi Vergangenheit Yoshi zu hassen.
Greg Burghardt

9
@nikonyrh Das würde ich nicht machen. Die Einschränkungen sind vorhanden, sodass sich Anwendungen auf konsistente Daten verlassen können. FK zu deaktivieren, nur um es rein zu bekommen, ist Wahnsinn.
Paddy

5
Einverstanden. Auch wenn Ihre Anwendung der einzige Client ist, können verschiedene Versionen Ihrer Anwendung versuchen, geringfügig andere Einschränkungen durchzusetzen. Normalerweise kommt es zu Heiterkeit (na ja, nicht wirklich. Es ist eher wie "Chaos und völlige Frustration" als "Heiterkeit").
Iker

5
Das kann ich absolut bezeugen. In meinem Fall steckte ich bei MyISAM fest, das Fremdschlüssel nicht unterstützt, und so erhielt ich 250 GB Daten mit der von der Anwendung erzwungenen Integrität. Als es darum ging, Daten zu bereinigen, um den Rückstand auf eine besser verwaltbare Größe zu bringen, und als klar wurde, dass die Anwendung selbst dies überhaupt nicht bewältigen konnte, kam es zu einem Chaos. Ich weiß nicht, warum ich die Vergangenheitsform verwende. dies geschieht noch heute , und das Problem (zwei Jahre) hat nach wie vor noch gelöst werden. * sniff *
Leichtigkeit Rennen mit Monica

1
Ich würde argumentieren, dass eine anständige Codebasis das Schreiben eines einmaligen Skripts unter Verwendung der Persistenzschicht aus Ihrer Anwendung mindestens so schnell wie das Schreiben von unformatiertem SQL vereinfachen sollte. Für einmalige Skripte sollte es niemals erforderlich sein, den Code Ihrer Anwendung zu ändern .
Jonathan Cast

17

Sie sollten Beziehungen in der Datenbank haben.

Wie die anderen Antwortnotizen zeigen, ist die Leistung der Einschränkungsprüfung in dieser Datenbank weitaus besser als in Ihrer Anwendung. Datenbankeinschränkungsprüfungen sind eines der Dinge, in denen Datenbanken gut sind.

Wenn Sie jemals zusätzliche Flexibilität benötigen, z. B. Ihre notierten Querverweise auf Datenbanken, können Sie die Einschränkungen absichtlich und unter Berücksichtigung entfernen. Konsistenz in Ihrer Datenbank bedeutet, dass Sie die Möglichkeit haben, diese Einschränkungen zu ändern und die Sicherheit der referenziellen Integrität zu gewährleisten.


1
Wahr. Ich hätte sagen sollen, dass die Ausführung der Einschränkungsprüfung in der Datenbank besser gehandhabt wird als in der Anwendung.
Kirk Broadhurst

13
  • Wir leben nicht länger in einer Back-End-Welt.
  • Die meisten Lösungen umfassen ein Web-Front-End, ein mobiles Front-End, ein Batch-Front-End und ein iPad-Front-End usw.
  • Datenbankmodule verfügen bereits über Tausende getesteter Codezeilen, die zur Durchsetzung der referenziellen Integrität optimiert wurden.

Können Sie es sich wirklich leisten, Code für die Durchsetzung der referenziellen Integrität zu schreiben und zu testen, wenn Sie Probleme beim Lösen des zu schreibenden Codes haben?


2
"Wir leben nicht länger in einer Back-End <-> Front-End-Welt." Haben wir jemals Vor einigen Jahren arbeitete ich an einem Datenbanksystem, auf das Programme in mindestens zwei Dutzend verschiedenen Sprachen zugegriffen haben. Einige der Programme wurden erstmals in den 1970er Jahren veröffentlicht.
Mike Sherrill "Cat Recall"

2

Wenn Sie Ihre Datenintegrität, Einschränkungen, Beziehungen usw. nicht auf Datenbankebene validieren, ist es für Benutzer mit Produktionsdatenbankzugriff (über einen anderen Client, einschließlich eines DB-Zugriffstools) viel einfacher, Ihre Daten durcheinander zu bringen.

Es ist empfehlenswert, die Datenintegrität auf Datenbankebene so streng wie möglich zu gewährleisten. Vertrauen Sie mir, dies erspart Ihnen im Laufe der Zeit enorme Kopfschmerzen in jedem nicht trivialen System. Sie werden auch Anwendungslogikfehler oder Fehler und Inkonsistenzen bei Geschäftsanforderungen schneller erkennen, wenn Sie sorgfältig darüber nachdenken.

Gestalten Sie Ihre Datenbank so normal und atomar wie möglich. Keine "Gott" -Tabellen. Entwerfen Sie Ihre Datenbank mit viel Aufwand so einfach wie möglich, idealerweise mit vielen kleinen Tabellen, die individuell sehr gut definiert sind, eine einzige Verantwortung tragen und in allen Spalten sorgfältig validiert wurden. Die Datenbank ist der letzte Hüter Ihrer Datenintegrität. Es repräsentiert den Bergfried der Burg.


1

Die meisten Leute sagen im Wesentlichen : „Ja, im Allgemeinen ich soll immer die Beziehungen in der Datenbank definieren“. Aber wenn die Disziplinen der Informatik so einfach wären, würden wir "Software Manual Readers" anstelle von "Software Engineers" heißen. Ich stimme tatsächlich zu, dass die Einschränkungen in die Datenbank aufgenommen werden sollten, es sei denn , es gibt einen guten Grund, warum dies nicht der Fall ist. Lassen Sie mich daher einige Gründe nennen, die in bestimmten Situationen als gut angesehen werden könnten :

Doppelter Code

Manchmal ist im Anwendungscode natürlich eine bestimmte Menge an Funktionen enthalten, die von der Datenbank verarbeitet werden können. Wenn das Hinzufügen von Einschränkungen zur Datenbank überflüssig wäre, ist es möglicherweise besser, die Funktionalität nicht zu duplizieren, da Sie gegen die DRY-Prinzipien verstoßen und die Synchronisierung von Datenbank und Anwendungscode verschlimmern.

Anstrengung

Wenn Ihre Datenbank bereits das tut, was sie benötigt, ohne erweiterte Funktionen zu verwenden, möchten Sie möglicherweise abwägen, wo Sie Zeit, Geld und Aufwand investieren sollten. Wenn das Hinzufügen von Einschränkungen einen katastrophalen Ausfall verhindern und damit Ihrem Unternehmen viel Geld sparen würde, dann ist es wahrscheinlich die Mühe wert. Wenn Sie Einschränkungen hinzufügen, die gelten sollten, von denen jedoch garantiert wird, dass sie niemals verletzt werden, verschwenden Sie Zeit und verschmutzen Ihre Codebasis. Garantiert ist hier das maßgebliche Wort.

Effizienz

Dies ist normalerweise kein guter Grund, aber in einigen Fällen besteht möglicherweise eine bestimmte Leistungsanforderung. Wenn der Anwendungscode eine bestimmte Funktionalität schneller als die Datenbank implementieren kann und Sie die zusätzliche Leistung benötigen, müssen Sie die Funktion möglicherweise im Anwendungscode implementieren.

Steuerung

Etwas im Zusammenhang mit der Effizienz. Manchmal müssen Sie die Implementierung einer Funktion sehr genau steuern, und manchmal muss die Datenbank sie hinter einer Blackbox verstecken, die Sie öffnen müssen.

Schlusspunkte

  • Datenbanken werden in Code geschrieben. Es gibt nichts Magisches, was Sie in Ihrem eigenen Code nicht tun können.
  • Nichts ist umsonst. Einschränkungen, Beziehungen usw. verwenden alle CPU-Zyklen.
  • Die Leute in der NoSQL-Welt verstehen sich ohne traditionelle relationale Funktionen sehr gut. In MongoDB zum Beispiel ist die Struktur von JSON-Dokumenten gut genug, um eine gesamte Datenbank zu unterstützen.
  • Die blinde und ignorante Verwendung erweiterter Datenbankfunktionen kann keine Vorteile garantieren. Sie könnten versehentlich etwas funktionieren lassen, um es später zu zerbrechen.
  • Sie haben eine sehr allgemeine Frage gestellt, ohne bestimmte Anforderungen oder Einschränkungen aufzulisten. Die eigentliche Antwort auf Ihre Frage lautet "es kommt darauf an".
  • Sie haben nicht angegeben, ob dies ein Problem im Unternehmensmaßstab ist. Andere Antworten sprechen von Dingen wie Kunden- und Datenintegrität, aber manchmal sind diese Dinge nicht wichtig.
  • Ich gehe davon aus, dass Sie über eine traditionelle relationale SQL-Datenbank sprechen.
  • Meine Perspektive ergibt sich aus der Abkehr von der Verwendung von Tonnen von Einschränkungen und Fremdschlüsseln in kleinen (bis zu 50 Tabellen) Projekten, ohne dass ich irgendwelche Nachteile bemerkte .

Das Letzte, was ich sagen werde, ist, dass Sie wissen, ob Sie die Funktionalität nicht in die Datenbank stellen sollten. Wenn Sie sich nicht sicher sind, sind Sie wahrscheinlich besser dran, wenn Sie die Datenbankfunktionen verwenden, da diese normalerweise sehr gut funktionieren.


1
Wenn die Leute wohlüberlegte Antworten ablehnen, weil sie nicht mit ihrem Dogma übereinstimmen, wird der SE StackExchange zu einem schlechteren Ort.
Carl Leth

5
Die Prämisse dieser Antwort, dass es Gelegenheiten gibt, in denen Sie Einschränkungen aus der Datenbank herauslassen, ist gültig, aber die Erklärung ist schlecht und irreführend. Obwohl ich der Meinung bin, dass die Datenbank für einige Einschränkungen nicht der beste Ort ist , sollte keine relationale Datenbank ohne grundlegende Schlüssel- und referenzielle Integritätsbeschränkungen auskommen . Keine . Hiervon gibt es keine Ausnahme. Jede Datenbank benötigt Primärschlüssel, und die große Mehrheit benötigt Fremdschlüssel. Diese sollten immer von der Datenbank erzwungen werden, auch wenn sie die Logik dupliziert. Die Tatsache, dass du das beschönigst, ist der Grund, warum ich zurückgestimmt habe.
jpmc26

1
"Datenbanken sind in Code geschrieben. Es gibt nichts Magisches, was Sie in Ihrem eigenen Code nicht tun können." Nein, Sie können die referenzielle Integrität im Anwendungscode nicht erzwingen (und wenn Sie sie nicht erzwingen müssen, warum verwenden Sie überhaupt einen Datenbankserver?). Es geht nicht darum, was Code tun kann, es geht darum, wo es getan werden kann.
Hyde

0

Wie immer gibt es viele Antworten. Für mich habe ich eine einfache Regel gefunden (nun, es funktioniert nur für einen modellzentrierten Ansatz). Normalerweise konzentriere ich mich nur auf die verschiedenen Anwendungsebenen.

Wenn das Modell aus mehreren Entitäten besteht und Abhängigkeiten zwischen den Entitäten bestehen, sollte die Persistenzschicht diese Abhängigkeiten mit ihren Möglichkeiten widerspiegeln. Wenn Sie also ein RDBMS verwenden, sollten Sie auch Fremdschlüssel verwenden. Der Grund ist einfach. Auf diese Weise sind die Daten strukturell immer gültig.

Jede Instanz, die an dieser Persistenzschicht arbeitet, kann sich darauf verlassen. Ich gehe davon aus, dass Sie diese Ebene über die Schnittstelle (Service) einkapseln. Hier endet also das Design und die reale Welt beginnt.

Betrachten Sie Ihre Punkte, insbesondere datenbankübergreifende Verweise . In diesem Fall sollte ja keine Referenz im RDBMS selbst implementiert sein, sondern im Service. Aber bevor Sie diesen Weg beschreiten, wäre es nicht besser, dies bereits während des Entwurfs zu berücksichtigen?

Bedeutet, wenn ich bereits weiß, dass es Teile gibt, die in einer anderen DB gespeichert werden müssen, dann kann ich sie bereits dort ablegen und als separates Modell definieren. Richtig?

Sie weisen auch darauf hin, dass die Implementierung in Code flexibler ist . Richtig, aber hört sich das nicht so an, als hätten Sie es mit einem unvollständigen Design zu tun? Fragen Sie sich, warum Sie mehr Flexibilität benötigen?

Das Leistungsproblem ist aufgrund der Integritätsprüfungen in der DB nicht real. Das RDBMS kann solche Dinge viel schneller prüfen als jede Implementierung von Ihnen. Warum? Nun, Sie müssen mit der Medienstörung fertig werden, das RDBMS nicht. Und es kann solche Überprüfungen optimieren, indem es auch seine Statistiken verwendet

Sie sehen, es kommt alles auf das Design zurück. Natürlich können Sie jetzt sagen, aber was ist, wenn eine unbekannte Anforderung auftritt, ein Game Changer? Ja, es könnte passieren, aber solche Änderungen sollten auch entworfen und geplant werden. ;O)


0

Sie haben einige sehr gute Antworten, aber noch einige Punkte

Datenintegrität ist das, wofür eine Datenbank entwickelt wurde

Eine ordnungsgemäße Parallelität wie ein FK-Löschvorgang auf Anwendungsebene wäre schrecklich

Kompetenz in Datenintegrität liegt bei einem DBA

Auf der Programmebene fügen Sie ein, aktualisieren, aktualisieren die Massen, fügen die Massen ein, löschen die Massen ...
Thin Client, Thick Client, Mobile Client ....
Die Datenintegrität ist nicht das Fachwissen eines Programmierers - viele doppelte Codes und jemand wird durcheinander bringen es auf

Angenommen, Sie werden gehackt - Sie sind in jeder Hinsicht in Schwierigkeiten, aber ein Hacker kann über ein kleines Loch viel Schaden anrichten, wenn kein Integritätsschutz in der Datenbank vorhanden ist

Möglicherweise müssen Sie Daten direkt über SQL oder TSQL bearbeiten.
Niemand wird sich an alle Datenregeln erinnern


0

Ihre Frage macht keinen Sinn: Wenn Sie die Datenbank ändern können, ist es Code. Wenn Sie die Datenbank nicht ändern können, müssen Sie Ihre Einschränkungen an anderer Stelle erstellen.

Eine Datenbank, die Sie ändern können, ist genauso viel Code wie jede Zeile aus Ruby, Javascript, C # oder Ada.

Die Frage, wo eine Einschränkung in Ihrem System erfolgen soll, sollte sich auf Zuverlässigkeit, Kosten und einfache Entwicklung beschränken.


0

Hier gibt es jede Menge gute Antworten. Wenn Sie eine App in der Sprache Y haben, können Sie datenbankabhängigen Code in Y erstellen. Wenn dann jemand mit der Sprache Z auf Ihre Datenbank zugreifen möchte, müssen Sie denselben Code erneut schreiben. Gott helfe dir, wenn die Implementierungen nicht genau gleich sind. Oder wenn ein erfahrener Geschäftsbenutzer über Microsoft Access eine Verbindung zu Ihrer Datenbank herstellt.

Meine Erfahrung zeigt, dass Menschen, die keine Datenbankeinschränkungen verwenden möchten, tatsächlich versuchen, etwas Falsches zu tun. Sie versuchen beispielsweise, Daten in großen Mengen zu laden, und möchten für eine Weile Spalten, die nicht null sind, leer lassen. Sie beabsichtigen, "das später zu beheben", da die Situation, die die Nicht-Null-Einschränkung kritisch machte, "in diesem Fall unmöglich passieren kann". Ein weiteres Beispiel ist der Versuch, zwei verschiedene Datentypen in dieselbe Tabelle aufzunehmen.

Erfahrene Leute werden einen Schritt zurücktreten und eine Lösung finden, bei der nicht versucht wird, eine Einschränkung zu umgehen. Die Lösung könnte einfach sein, dass die Einschränkung nicht mehr richtig ist, weil sich das Geschäft natürlich geändert hat.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.