Nachschlagetabellen: Sind sie ein Leck im Domänenmodell?


10

Sie bauen ein System auf, das Unternehmen im Auge behält. Diese Unternehmen haben Kontakte. Bei diesen Kontakten handelt es sich häufig um Spezialisten, die nur bestimmte Arten von Fragen beantworten, z. B. Abrechnung / Zahlung, Verkauf, Bestellung und Kundenunterstützung.

Unter Verwendung von domänengesteuertem Design und einer Zwiebelarchitektur habe ich dies mit den folgenden Typen modelliert:

  • Unternehmen
    • Hat Kontakte
  • Kontakt
    • Hat Kontakttypen
  • ContactType (Aufzählung)
  • CompanyRepository (Schnittstelle)
  • EFCompanyRepository (in einer externen Assembly definiert, verwendet EntityFramework, implementiert CompanyRepository)

Unser Team ist sich uneinig, wie die Datenbank für diese Anwendung modelliert werden soll.

Seite A: Die Lean DDDers:

  • Es ist Aufgabe der Domain, zu definieren, welche ContactTypes für einen Contact gültig sind. Das Hinzufügen einer Tabelle zur Datenbank, um zu überprüfen, ob unbekannte ContactTypes nicht gespeichert werden, ist ein Zeichen für eine undichte Domäne. Es verbreitet die Logik zu weit.
  • Das Hinzufügen einer statischen Tabelle zur Datenbank und des entsprechenden Codes ist verschwenderisch. In dieser Anwendung löst die Datenbank ein Problem: Behalten Sie das Ding bei und geben Sie es mir zurück. Das Schreiben einer zusätzlichen Tabelle und des entsprechenden CRUD-Codes ist verschwenderisch.
  • Das Ändern der Persistenzstrategie sollte so einfach wie möglich sein. Es ist wahrscheinlicher, dass sich diese Geschäftsregeln ändern. Wenn ich feststelle, dass SQL Server zu viel kostet, möchte ich nicht die gesamte Validierung neu erstellen müssen, die ich in mein Schema eingefügt habe.

Seite B: Die Traditionalisten [das ist wahrscheinlich kein fairer Name. Die DBCentristen?]:

  • Es ist eine schlechte Idee, Daten in der Datenbank zu haben, die ohne Lesen von Code keinen Sinn ergeben. Berichte und andere Verbraucher müssen die Werteliste selbst wiederholen.
  • Es ist nicht so viel Code, um Ihre DB-Wörterbücher bei Bedarf zu laden. Mach dir keine Sorgen.
  • Wenn die Quelle hierfür Code und keine Daten sind, muss ich bei Änderungen Bits anstelle eines einfachen SQL-Skripts bereitstellen.

Keine Seite ist richtig oder falsch, aber eine von ihnen ist auf lange Sicht wahrscheinlich effizienter und zählt die Entwicklungszeit für die anfängliche Entwicklung, Fehler usw. Welche Seite ist das - oder gibt es einen besseren Kompromiss? Was machen andere Teams, die diesen Codestil schreiben?


Ich bevorzuge Nachschlagetabellen in der Datenbank und Code (T4-Vorlagen in .NET), der die Aufzählungen für mich basierend auf den Nachschlagetabellen in meinem Anwendungscode generiert.
Programmierer

@JasonHolland Führt die T4-Vorlage tatsächlich eine Abfrage durch? Ansonsten bin ich mir nicht sicher, wie es mehr als eine leere Aufzählung mit dem erwarteten Namen erzeugt.
Drew


Wie viel CRUD-Code müssen Sie für eine Tabelle mit statischen Werten schreiben? Skript es und fertig sein.
JeffO

2
Das traditionelle CRUD-Argument über "Nun, es macht keinen Sinn für die Berichterstattung" ist kein Anfänger. Sobald Sie eine andere Verantwortung einführen, die das System hat (dh Berichterstattung), haben Sie eine Geschäftsanforderung gefunden, die angemessen behandelt werden muss. Die Datenbank dient zum Speichern und Laden des eigenen geschützten Status der Anwendung. Wenn Sie die Berichterstattung zulassen, wird eine Kopplung zwischen Ihrer Anwendung und den Personen hergestellt, die die Berichte benötigen. Wenn es bei DDD um irgendetwas geht, geht es darum, diese Kontexte zu trennen.
Matt

Antworten:


4

Durch die Übernahme der DDD- und Zwiebelarchitektur haben Sie entschieden, dass die Datenbank nach Ihrem Domänenmodell an zweiter Stelle steht. Das bedeutet, dass außer dem Modell niemand andere Operationen an der Datenbank ausführt. Wenn Traditionalisten das nicht mögen, hätten sie in erster Linie gegen die Verwendung von DDD protestieren sollen.

Das erste ist klar: Sie benötigen die "Nachschlagetabelle" im Modell. Ihr Modell muss zwischen verschiedenen Arten von Kontakten unterscheiden. Das heißt, es wird eine stark typisierte Liste aller Typen geführt. Es muss auch eine Zuordnung von diesen starken Typen zu Werten erfolgen, die in die Datenbank serialisiert werden. Diese Zuordnung kann sich im Datenbankmodul befinden. Die Liste aller möglichen Typen befindet sich jedoch weiterhin im Modell. Und wenn das Modell eine einzige Quelle der Wahrheit sein soll, kann es sich nicht in der Datenbank befinden. Wenn sich die Liste im Modell ändert, muss sie sich zumindest in der Datenbank ändern. Und kein Aber!


2

Domänenobjekte sind keine Domänenobjekte mehr, wenn sie eine Prozessgrenze überschreiten . Selbst wenn es sich bei der Datenbank nur um einen Persistenzspeicher handelt, werden die Anforderungen des Unternehmens zu einem späteren Zeitpunkt zu einer Änderung des Domaim-Modells führen, die nicht mit dem persistierten Verlauf übereinstimmt, und Sie benötigen ohnehin eine Antikorruptionsschicht ....

Das heißt, ich denke, Ihre DBCentrists vermissen das Boot. Die Domain-Modellierer sagen, dass sie einen Persistenzspeicher benötigen. "Berichte und andere Verbraucher" benötigen etwas, das sie abfragen können - etwas mit anständigen Indizes, wie in Kommentaren erwähnt wurde.

Wer hat die Einschränkung eingeführt, dass all diese unterschiedlichen Anliegen von einer Datenbank unterstützt werden müssen ? Was passiert, wenn Sie das zurückschieben?

Suchbegriff: CQRS.


1

Ich habe festgestellt, dass es am besten ist, Aufzählungen als Zeichenfolgendarstellung in der Datenbank zu speichern und keine Nachschlagetabelle einzuschließen.

Der Nachteil dabei ist natürlich, dass mehr Speicherplatz benötigt wird und nicht normalisiert wird.

Das Plus ist, dass das Feld seine Bedeutung in der Datenbank beibehält. Sie erhalten beispielsweise keine magischen Zahlen, die dem int-Wert der Aufzählung entsprechen, und Sie müssen die Versionierung einer Nachschlagetabelle nicht verwalten, wenn sich die Aufzählung ändert.

Ich bin mir nicht sicher, ob ich dies als einen Unterschied zwischen DDD und Trad charakterisieren würde. Es ist meiner Ansicht nach eher ein Datenbank-Zentralist gegen Code


Ich

Ich denke, es würde von der Datenbank abhängen, Sie können alle möglichen verrückten CLR-Sachen mit MSSQL machen. Aber ich bin fest mit der "DB schlecht, Code gut" Seite, wenn es um solche Dinge geht
Ewan

@herzmeister <3 PostgreSQL postgresql.org/docs/9.4/static/datatype-enum.html , Ewan Die Datenbank ist Code, sobald Sie gespeicherte Prozeduren akzeptieren . (PLv8 ist wunderbar).
Sirisian

@ Sirisian Sie wissen, dass es etwas mischt? Ich habe eine ähnliche Frage. "skaliert es?"
Ewan

Meinst du, macht es ein Kreuzprodukt, um die Aufzählung in eine Zeichenfolge zu verwandeln? Wahrscheinlich nicht. Ich bin nicht sicher, wie es implementiert ist, aber es ist schneller als die Verwendung einer separaten Tabelle. Es skaliert. Fand dies auch: stackoverflow.com/questions/2318123/… Scheint auch 5 Jahre später noch eine gültige Einschätzung zu sein. (Ich neige dazu, Programme zu schreiben, die stark an PostgreSQL gekoppelt sind, daher nutze ich alle Funktionen, aber das kann nicht jeder).
Sirisian

0
  • Solange Sie eine relationale Datenbank verwenden, sollten Sie die Tabellen in angemessenem Umfang normalisieren. Durch die Normalisierung werden Einfügungs- und Aktualisierungsanomalien vermieden.
  • Die Beziehung zwischen einer App und einer Datenbank ist nicht mehr üblich. Mehrere Apps können mehrere Datenbanken verwenden, und eine einzelne Datenbank kann von mehreren Apps verwendet werden. Daher ist es gut, wenn die Datenbank die referenzielle Integrität so weit wie möglich erzwingt.
  • Das RDBMS ist dein Freund.
  • Sie können stattdessen einen Schlüsselwertspeicher verwenden und alles im Code ausführen.
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.