Sollten wir Foreign-Key-Einschränkungen bei persistenten Domänenmodellen verwenden?

7

Vor einiger Zeit hatte ich mit meinen Kollegen eine Diskussion über die Beständigkeit von Domain-Modellen und darüber, ob wir ausländische Schlüsseleinschränkungen auf Datenbankebene.

Meine erste Reaktion war, dass die bloße Verwendung einer relationalen Datenbank die Durchsetzung solcher Beschränkungen implizierte, aber einige argumentierten, dass die Datenbank als nichts anderes als ein Persistenzmechanismus betrachtet werden sollte und daher sollten wir keine Geschäftslogik darin platzieren. Am Ende verwendeten wir keine Fremdschlüssel-Einschränkungen.

Hier ist meine Frage (ich hoffe, es ist nicht allzu allgemein gehalten): Wird es als gute Praxis angesehen, in diesen Fällen wichtige Einschränkungen durchzusetzen?

    
Saulo Silva 02.07.2009, 19:55
quelle

6 Antworten

9

Erzwinge Constraints, aber verlasse dich NICHT darauf in deiner Geschäftslogik

  • Nein Geschäft Logik in der Datenbank: Ich stimme dem Prinzip zu. Wenn Ihr Nicht-SQL Geschäftscode auf die Datenbankeinschränkungen angewiesen ist, um die Konsistenz Ihrer Datenbank zu überprüfen, sollten Sie Ihre Geschäftslogik überdenken.
  • Es gibt nichts Falsches daran, Datenbankeinschränkungen zusätzlich für Ihre Geschäftslogik zu haben. Vor allem, weil Dinge wie referentielle Integrität mit FOREIGN KEYs und anderen UNIQUE Constraints einfach zu erledigen sind und RDBMS diese Aufgabe sehr effizient und ohne großen Aufwand für Sie erledigen.
  • Werden Sie nicht auch Indizes in der Datenbank verwenden, weil es nicht rein persistenzbezogen ist?
  • Das Finden und Beheben von Softwarefehlern kann einige Zeit in Anspruch nehmen, aber Sie definitiv wollen nicht noch mehr Zeit damit verbringen, Daten zu bereinigen oder (noch schlimmer) Daten zu verlieren, nur weil Sie sich selbst ein Problem erspart haben Schreiben eines einzeiligen Skripts für einen FK. Wirklich: Ihr bekommt hier etwas umsonst und Ihr lehnst es ab?
  • [EDIT-1]: können Sie garantieren, dass die Daten in Ihrer Datenbank über Ihre Anwendung NUR verwaltet werden? Es scheint immer Ausnahmen zu geben, meistens von Power-Usern, die manchmal (sehr selten :-) Fehler machen und einige SQL-Anweisungen ausführen, um Ihren Code zu bereinigen, Status zu aktualisieren (zu ungültigen Werten wegen Tippfehlern) usw. li>
  • [EDIT-2]: domänengetriebenes Modell ist keine Entschuldigung dafür, keinen guten DB-Administrator einzustellen. Die Verwendung von ORM ist keine Entschuldigung dafür, keinen guten DB-Entwickler einzustellen.

Aber wenn Sie und Ihr Team in der Lage sind, fehlerfreie Software zu schreiben und alle möglichen Ausnahmeszenarien in Ihrem Code zu behandeln (einschließlich Hardware- / Netzwerk- / Dummy-Benutzer- / Programmierfehler), dann "Hei, warum sollte man sich mit redundanten FK-Einschränkungen befassen ..." - -Teaser -

    
van 03.07.2009, 05:00
quelle
7

Ich denke, ich betrachte es nicht so sehr als etwas für die Geschäftslogik, sondern verhindere, dass "schlechte" Daten in die Datenbank eingegeben werden. Sobald die Datenbank sehr groß wird, werden diese Einschränkungen in der Zukunft Kopfschmerzen verhindern.

Dies tritt besonders dann in Kraft, wenn mehrere Entwickler Apps für dieselben Daten entwickeln. Dies stellt sicher, dass sie nur gültige Daten eingeben können. Es ist sicherlich von Vorteil, Beschränkungen in einem Punkt statt in x Apps zu kontrollieren.

    
Chris Klepeis 02.07.2009 19:59
quelle
3

Ich habe das Gefühl, dass das Ignorieren wirklich nützlicher Tools (Datenintegrität auf Datenbankebene) im Interesse einer reinen Entwicklungsmethodik kontraproduktiv ist. Datenbanken sind wirklich gut in dieser Art von Sache ... lass sie es tun.

Irgendwann fängt jede Methode an zu brechen und Sie müssen nur praktisch sein.

    
William Edmondson 02.07.2009 20:01
quelle
2

Früher dachte ich, aber meine Meinung hat sich geändert, seit ich angefangen habe, viele ressourcenorientierte Systeme zu schreiben. In der Regel sind weit mehr als nur Fremdschlüsseleinschränkungen erforderlich, um ein Stück Daten zu validieren - z. B. muss ein Ticket, das den Status "zugewiesen" hat, einen gültigen "assigned_to" -Wert haben, und so weiter. Alle diese Regeln sollten in einer Validierungsroutine irgendeiner Art platziert werden, und während es theoretisch nicht weh tut , eine zusätzliche Validierung auf Datenbankebene zu haben, wenn Ihre Validierung auf App-Ebene funktioniert, prüfen Sie die fremde Schlüsseleinschränkung sind nur verschwendete Zyklen. Schlimmer noch, Sie haben jetzt Logik an Ihrem Datenmodell, die an zwei Stellen wiederholt wird - der Validierungscode und die Datenbankbeschränkungen.

Denken Sie so darüber nach: Möchten Sie eine andere Anwendungslogik in die Datenbank verschieben (z. B. über gespeicherte Prozeduren), wenn Sie nicht müssen? Wenn Sie aufgrund von Leistungsüberlegungen nicht dazu gezwungen wären, sollte die Antwort im Allgemeinen "nein" lauten.

    
John Hyland 02.07.2009 20:20
quelle
2

"Meine erste Reaktion war, dass die bloße Verwendung einer relationalen Datenbank die Durchsetzung solcher Einschränkungen implizierte, aber einige argumentierten, dass die Datenbank als nichts anderes als ein Persistenzmechanismus betrachtet werden sollte und daher sollten wir keine Geschäftslogik darin platzieren. Am Ende verwendeten wir keine Fremdschlüssel-Einschränkungen. "

Ja, na ja, die mittelmäßige Mehrheit gewinnt diese Art von Debatte immer nur durch die Kraft der Zahlen, leider.

Wenn Sie immer noch diesen Kampf kämpfen wollen, könnten Sie Ihre Gegner fragen, wie sie verhindern wollen, dass jemand "direkte Datenbankeditoren" (ala db2-aid, spufi, ...) benutzt und wie sie vorhaben, irgendjemanden davon abzuhalten Verfälschung der Datenbank mit solchen Tools (die ihre programmierten Geschäftsbeschränkungen per Definition umgehen).

    
Erwin Smout 02.07.2009 21:50
quelle
0

Wenn Sie dem Paradigma "Domain Driven Design" folgen möchten, lautet die Antwort "yes" für alle Elemente in einem Aggregat und "Nein" für Aggregationsverknüpfungen.

In fast allen Fällen möchten Sie, dass alles unter dem Aggregatstamm gelöscht wird, wenn das Stammverzeichnis selbst gelöscht wird. Dies wird durch die Verwendung von Fremdschlüsseln mit überlappenden Löschvorgängen auf Datenbankebene erreicht. Sie könnten auch Ihre Repositorys die kaskadierenden Löschungen selbst durchführen lassen, wenn Sie dies nicht auf DB-Ebene tun wollten, aber der Punkt steht immer noch, dass Aggregierte Kinder nicht ohne Root existieren sollten.

Bei Problemen mit der Aggregation von Aggregaten werden Sie wahrscheinlich geschäftliche Entscheidungen darüber treffen, was passieren soll, wenn das eine oder das andere entfernt wird. Oftmals möchten Sie dies asynchron behandeln, um Skalierbarkeit zu ermöglichen, sodass Ihr Domänenmodell letztendlich konsistent wird. Daher ist es in diesen Fällen nicht sinnvoll, Fremdschlüssel zu erzwingen, da es ein Zeitfenster gibt, in dem der eine oder andere Schlüssel möglicherweise nicht existiert.

Hoffe das hilft! Und für weitere Informationen, lesen Sie auf jeden Fall Evans 'Buch über Domain Driven Design - und die vielen Links im Internet auch.

    
Michael Hart 03.07.2009 03:58
quelle