Tablas de búsqueda: ¿son una fuga en el modelo de dominio?

10

Está creando un sistema que realiza un seguimiento de las empresas. Esas empresas tienen contactos. Esos contactos a menudo son especialistas que solo responden ciertos tipos de preguntas, como facturación / pago, ventas, pedidos y atención al cliente.

Utilizando el diseño impulsado por dominio y una arquitectura de cebolla, he modelado esto con los siguientes tipos:

  • Empresa
    • Tiene contactos
  • Contacto
    • Tiene tipos de contacto
  • ContactType (enumeración)
  • CompanyRepository (interfaz)
  • EFCompanyRepository (definido en un ensamblado externo, utiliza EntityFramework, implementa CompanyRepository)

Nuestro equipo tiene una opinión dividida sobre cómo modelar la base de datos para esta aplicación.

Lado A: Los DDD Lean:

  • El trabajo del Dominio es definir qué ContactTypes son válidos para un Contacto. Agregar una tabla a la base de datos para validar que los ContactTypes desconocidos no se guardan es una señal de un dominio con fugas. Difunde la lógica demasiado lejos.
  • Agregar una tabla estática a la base de datos y el código correspondiente es un desperdicio. En esta aplicación, la base de datos resuelve un problema: persiste la cosa y me la devuelve. Escribir una tabla adicional y el código CRUD correspondiente es un desperdicio.
  • Cambiar la estrategia para la persistencia debería ser lo más fácil posible. Es más probable que cambie las reglas de negocio. Si decido que SQL Server cuesta demasiado, no quiero tener que reconstruir toda la validación que puse en mi esquema.

Lado B: Los tradicionalistas [probablemente no sea un nombre justo. Los DBCentrists?]:

  • Es una mala idea tener datos en la base de datos que no tengan sentido sin leer el código. Los informes y otros consumidores tienen que repetir la lista de valores ellos mismos.
  • No es tanto código para cargar sus diccionarios de tipo db a pedido. No te preocupes por eso.
  • Si la fuente de esto es código y no datos, tendré que implementar bits en lugar de un simple script SQL cuando cambie.

Ninguno de los lados está bien o mal, pero uno de ellos es probablemente más eficiente a largo plazo, contando el tiempo de desarrollo para el desarrollo inicial, errores, etc. ¿De qué lado está, o hay un compromiso mejor? ¿Qué hacen otros equipos que escriben este estilo de código?

Dibujó
fuente
Prefiero tener tablas de búsqueda en la base de datos y tener código (plantillas T4 en .NET) que genera las enumeraciones para mí en función de las tablas de búsqueda en el código de mi aplicación.
programador
@JasonHolland ¿Realmente la plantilla T4 realiza una consulta? De lo contrario, no estoy seguro de cómo genera más que una enumeración vacía con el nombre esperado.
Dibujó el
2
Sí, realiza una consulta. Echa un vistazo a developerhandbook.com/c-sharp/t4-templates-for-lookup-tables and erraticdev.blogspot.com/2011/01/…
programador
Para una tabla con valores estáticos, ¿cuánto código CRUD necesita escribir? Escríbelo y listo.
JeffO
2
El argumento tradicional de CRUD ist sobre "bueno, no tendrá sentido para informar" no es un iniciador. Tan pronto como introduce alguna otra responsabilidad que tiene el sistema (a saber, informar), ha encontrado un requisito comercial que debe manejarse adecuadamente. La base de datos está allí para almacenar y cargar las aplicaciones propias, estado protegido; permitir que se informe se crea un acoplamiento entre su aplicación y las personas que necesitan los informes. Si DDD se trata de algo, se trata de separar estos contextos.
Matt

Respuestas:

4

Al adoptar DDD y la arquitectura de cebolla, ha decidido que la base de datos es la segunda de su modelo de dominio. Eso significa que no habrá nadie más haciendo operaciones en la base de datos que no sea el modelo. Si a los tradicionalistas no les gusta eso, deberían haberse opuesto al uso de DDD en primer lugar.

Lo primero es claro: necesita la "tabla de búsqueda" en el modelo. Su modelo necesita diferenciar entre diferentes tipos de contactos. Eso significa que mantiene una lista fuertemente tipada de todos los tipos. También debe haber una asignación de esos tipos fuertes a valores que se serializan en la base de datos. Esta asignación puede estar dentro del módulo de base de datos. Pero la lista de todos los tipos posibles seguirá estando en el modelo. Y si el modelo debe ser una fuente única de verdad, entonces no puede estar dentro de la base de datos. O al menos, cuando la lista cambia en el modelo, debe cambiar en la base de datos. ¡Y sin peros!

Eufórico
fuente
2

Los objetos de dominio dejan de ser objetos de dominio cuando cruzan un límite de proceso . Incluso si la base de datos es solo una tienda de persistencia, en algún momento en el futuro, las demandas de la empresa causarán un cambio en el modelo de domaim que es inconsistente con el historial persistente, y de todos modos necesitará una capa anticorrupción ....

Dicho esto, creo que a sus DBCentrists les falta el bote. Los modeladores de dominio dicen que necesitan un almacén de persistencia. Los "informes y otros consumidores" necesitan algo que puedan consultar, algo con índices decentes, como se ha señalado en los comentarios.

¿Quién introdujo la restricción de que todas estas preocupaciones diferentes necesitaban ser respaldadas por una base de datos? ¿Qué sucede si empujas hacia atrás en eso?

Palabra clave de búsqueda: CQRS.

VoiceOfUnreason
fuente
1

He encontrado que es mejor almacenar enumeraciones como su representación de cadena en la base de datos y no incluir una tabla de búsqueda.

Obviamente, la desventaja de esto es que usa más espacio en disco y no está normalizado.

El lado positivo es que el campo conserva su significado en la base de datos, no terminas con números mágicos que responden al valor int de la enumeración, por ejemplo, y no tienes que gestionar el versionado de una tabla de búsqueda cuando la enumeración cambia.

Sin embargo, no estoy seguro de caracterizar esto como una diferencia DDD vs Trad. Es más un código de base de datos centralista vs mejor es en mi opinión

Ewan
fuente
preguntándose si las bases de datos tienen una función de enumeración en estos días
herzmeister
Supongo que dependería de la base de datos, puede hacer todo tipo de cosas CLR locas con MSSQL. Pero estoy firmemente con el lado 'DB mal, código bueno' cuando se trata de tales cosas
Ewan
@herzmeister <3 PostgreSQL postgresql.org/docs/9.4/static/datatype-enum.html , Ewan El DB es el código una vez que adopta los procedimientos almacenados. (PLv8 es maravilloso).
Sirisian
@Sirisian, ¿sabes que combina algo? Tengo una pregunta similar. "¿escala?"
Ewan
¿Quiere decir que hace un producto cruzado para convertir la enumeración en una cadena? Probablemente no. No estoy seguro de cómo se implementa, pero es más rápido que usar una tabla separada. Se escala. También encontré esto: stackoverflow.com/questions/2318123/… Todavía parece una evaluación válida 5 años después. (Tiendo a escribir programas altamente acoplados a PostgreSQL, así que uso todas las funciones, pero no todos pueden hacerlo).
Sirisian
0
  • Mientras esté utilizando una base de datos relacional, debe mantener las tablas normalizadas en un grado razonable. La normalización ayuda a prevenir las anomalías de inserción y actualización.
  • La relación de una aplicación <-> una base de datos ya no es común, varias aplicaciones pueden usar múltiples bases de datos y una sola base de datos puede ser usada por múltiples aplicaciones, por lo que hacer que la base de datos haga cumplir la integridad referencial tanto como sea posible es bueno.
  • El RDBMS es tu amigo.
  • En su lugar, puede ir con un almacenamiento de valor clave y hacer todo en código.
Tulains Córdova
fuente