Tabelle di ricerca: sono una perdita nel modello di dominio?


10

Stai costruendo un sistema che tiene traccia delle aziende. Quelle aziende hanno contatti. Questi contatti sono spesso specialisti che rispondono solo a determinati tipi di domande, come fatturazione / pagamento, vendite, ordini e assistenza clienti.

Utilizzando Domain Driven Design e un'architettura di cipolla, ho modellato questo con i seguenti tipi:

  • Azienda
    • Ha contatti
  • Contatto
    • Ha tipi di contatti
  • ContactType (enum)
  • CompanyRepository (interfaccia)
  • EFCompanyRepository (definito in un assembly esterno, utilizza EntityFramework, implementa CompanyRepository)

Il nostro team ha un'opinione divisa su come modellare il database per questa applicazione.

Lato A: The Lean DDDers:

  • È compito del dominio definire quali tipi di contatto sono validi per un contatto. L'aggiunta di una tabella al database per confermare che i ContactTypes sconosciuti non vengono salvati è un segno di un dominio che perde. Diffonde la logica troppo lontano.
  • L'aggiunta di una tabella statica al database e al codice corrispondente è dispendiosa. In questa applicazione il database risolve un problema: persiste e restituiscilo. Scrivere una tabella aggiuntiva e il corrispondente codice CRUD è dispendioso.
  • Modificare la strategia per la persistenza dovrebbe essere il più semplice possibile. È più probabile che cambi le regole di business. Se decido che SQL Server costa troppo, non voglio ricostruire tutta la convalida che ho inserito nel mio schema.

Lato B: i tradizionalisti [che probabilmente non è un bel nome. The DBCentrists?]:

  • È una cattiva idea avere dati nel database che non hanno senso senza leggere il codice. I report e gli altri consumatori devono ripetere da soli l'elenco dei valori.
  • Non è molto il codice per caricare i dizionari di tipo db su richiesta. Non ti preoccupare.
  • Se la fonte di questo è il codice e non i dati, dovrò distribuire bit invece di un semplice script SQL quando cambia.

Nessuna delle due parti ha ragione o torto, ma una di esse è probabilmente più efficiente a lungo termine, contando i tempi di sviluppo per lo sviluppo iniziale, i bug, ecc. Da che parte sta - o c'è un compromesso migliore? Cosa fanno gli altri team che scrivono questo stile di codice?


Preferisco avere tabelle di ricerca nel database e avere codice (modelli T4 in .NET) che genera gli enummi per me in base alle tabelle di ricerca nel mio codice dell'applicazione.
— programmatore

@JasonHolland Il modello T4 esegue effettivamente una query? Altrimenti non sono sicuro di come generi più di un enum vuoto con il nome previsto.
— Drew


Per una tabella con valori statici, quanto codice CRUD devi scrivere? Scriverlo ed essere fatto.
— JeffO,

2
L'argomento tradizionale di CRUD-ist sul "bene, non ha senso riferire" non è un punto di partenza. Non appena si introducono altre responsabilità che il sistema ha (vale a dire, reportistica), è stato riscontrato un requisito aziendale che deve essere gestito in modo appropriato. Il database è lì per archiviare e caricare lo stato protetto delle applicazioni; consentire la segnalazione su crea un accoppiamento tra l'applicazione e le persone che necessitano dei rapporti. Se DDD riguarda qualcosa, si tratta di separare questi contesti.
— Matt

Risposte:


4

Adottando l'architettura DDD e cipolla, hai deciso che il database è secondo al tuo modello di dominio. Ciò significa che non ci sarà nessun altro a fare operazioni sul database diverso dal modello. Se ai tradizionalisti non piace, avrebbero dovuto obiettare in primo luogo all'uso del DDD.

La prima cosa è chiara: è necessaria la "tabella di ricerca" nel modello. Il tuo modello deve distinguere tra diversi tipi di contatti. Ciò significa che mantiene un elenco fortemente tipizzato di tutti i tipi. È inoltre necessario eseguire il mapping da quei tipi forti ai valori serializzati nel database. Questa mappatura può essere all'interno del modulo del database. Ma l'elenco di tutti i possibili tipi rimarrà comunque nel modello. E se il modello deve essere una singola fonte di verità, non può essere all'interno del database. O almeno, quando l'elenco cambia nel modello, deve cambiare nel database. E niente ma!


2

Gli oggetti di dominio smettono di essere oggetti di dominio quando attraversano un confine di processo . Anche se il database è solo un archivio di persistenza, ad un certo punto in futuro le esigenze dell'azienda causeranno una modifica al modello di domaim che è incompatibile con la storia persistente e avrete comunque bisogno di un livello anticorruzione ....

Detto questo, penso che ai tuoi DBCentrists manchi la barca. I modellatori di domini affermano di aver bisogno di un archivio di persistenza. "I rapporti e altri consumatori" hanno bisogno di qualcosa su cui possano interrogare, qualcosa con indici decenti, come è stato notato nei commenti.

Chi ha introdotto il vincolo che tutte queste diverse preoccupazioni dovevano essere supportate da un database? Cosa succede se ci ripeti.

Parola chiave di ricerca: CQRS.


1

Ho trovato meglio archiviare gli enum come loro rappresentazione di stringhe nel database e non includere una tabella di ricerca.

Ovviamente il rovescio della medaglia è che utilizza più spazio su disco e non è normalizzato.

Il lato positivo è che il campo mantiene il suo significato nel db, ad esempio non si ottengono numeri magici corrispondenti al valore int dell'enum e non è necessario gestire il controllo delle versioni di una tabella di ricerca quando l'enum cambia.

Non sono sicuro che lo definirei come una differenza tra DDD e Trad. È più un centralista di database vs codice è il migliore a mio avviso


chiedendosi se i database stessi abbiano una tale caratteristica enum in questi giorni
— herzmeister,

Immagino che dipenda dal DB, con MSSQL puoi fare tutti i tipi di cose folli con CLR. Ma sono fermamente d'accordo con il lato "DB cattivo, codice buono" quando si tratta di cose del genere
— Ewan,

@herzmeister <3 PostgreSQL postgresql.org/docs/9.4/static/datatype-enum.html , Ewan Il DB è il codice una volta accettate le procedure memorizzate. (PLv8 è meraviglioso).
— Sirisian,

@Sirisian sai che fonde la cosa? Io ho una domanda simile. "scala?"
— Ewan,

Vuoi dire che fa un prodotto incrociato per trasformare l'enum in una stringa? Probabilmente no. Non sono sicuro di come sia implementato, ma è più veloce rispetto all'utilizzo di una tabella separata. Si ridimensiona. Trovato anche questo: stackoverflow.com/questions/2318123/… Sembra ancora una valutazione valida 5 anni dopo. (Tendo a scrivere programmi altamente accoppiati a PostgreSQL, quindi uso tutte le funzionalità, ma non tutti possono farlo).
— Sirisian,

0
  • Finché si utilizza un database relazionale, è necessario mantenere le tabelle normalizzate in misura ragionevole. La normalizzazione aiuta a prevenire l'inserimento e l'aggiornamento di anomalie.
  • La relazione one-app <-> one-database non è più comune, più app possono utilizzare più database e un singolo database può essere utilizzato da più app, quindi avere il database imporre l'integrità referenziale il più possibile.
  • RDBMS è tuo amico.
  • Puoi invece utilizzare un archivio di valori-chiave e fare tutto nel codice.
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.