Tabele przeglądowe: czy są one nieszczelne w modelu domeny?

10

Budujesz system, który śledzi firmy. Te firmy mają kontakty. Kontakty te są często specjalistami, którzy odpowiadają tylko na niektóre rodzaje pytań, takie jak fakturowanie / płatność, sprzedaż, zamówienia i obsługa klienta.

Używając projektu opartego na domenie i architektury cebuli, modelowałem to z następującymi typami:

  • Firma
    • Ma kontakty
  • Kontakt
    • Ma typy kontaktów
  • ContactType (wyliczenie)
  • CompanyRepository (interfejs)
  • EFCompanyRepository (zdefiniowany w zewnętrznym zestawie, używa EntityFramework, implementuje CompanyRepository)

Nasz zespół ma podzielone zdanie na temat modelowania bazy danych dla tej aplikacji.

Strona A: Lean DDDers:

  • Zadaniem domeny jest określenie, które typy kontaktów są ważne dla kontaktu. Dodanie tabeli do bazy danych w celu sprawdzenia, czy nieznane typy ContactTes nie zostały zapisane, jest oznaką nieszczelnej domeny. Zbyt daleko rozprzestrzenia logikę.
  • Dodawanie tabeli statycznej do bazy danych i odpowiedniego kodu jest marnotrawstwem. W tej aplikacji baza danych rozwiązuje jeden problem: utrwal to i zwróć mi. Pisanie dodatkowej tabeli i odpowiedniego kodu CRUD jest marnotrawstwem.
  • Zmiana strategii uporczywości powinna być jak najłatwiejsza. Bardziej prawdopodobne jest, że zmieni to reguły biznesowe. Jeśli zdecyduję, że SQL Server kosztuje zbyt dużo, nie chcę odbudowywać całego sprawdzania poprawności, które wprowadziłem do mojego schematu.

Strona B: Tradycjonaliści [to prawdopodobnie nie jest uczciwa nazwa. DBCentrists?]:

  • To zły pomysł, aby mieć dane w bazie danych, które nie mają sensu bez czytania kodu. Raporty i inni konsumenci muszą sami powtórzyć listę wartości.
  • Nie jest tak dużo kodu, aby ładować słowniki typu db na żądanie. Nie martw się o to.
  • Jeśli źródłem tego jest kod, a nie dane, będę musiał wdrożyć bity zamiast prostego skryptu SQL, gdy się zmieni.

Żadna ze stron nie ma racji ani nie ma racji, ale jedna z nich jest prawdopodobnie bardziej wydajna na dłuższą metę, licząc czas rozwoju początkowego rozwoju, błędów itp. Po której stronie - czy jest lepszy kompromis? Co robią inne zespoły piszące ten styl kodu?

Rysował
źródło
Wolę mieć tabele odnośników w bazie danych i kod (szablony T4 w .NET), który generuje dla mnie wyliczenia na podstawie tabel odnośników w kodzie aplikacji.
programista
@JasonHolland Czy szablon T4 faktycznie wykonuje zapytanie? W przeciwnym razie nie jestem pewien, w jaki sposób generuje więcej niż pusty wyliczenie o oczekiwanej nazwie.
Drew
W przypadku tabeli ze wartościami statycznymi ile kodu CRUD należy napisać? Skryptuj i gotowe.
JeffO
2
Tradycyjny argument CRUD-is dotyczący „cóż, raportowanie nie ma sensu” nie jest początkowy. Gdy tylko wprowadzisz jakąś inną odpowiedzialność, którą system ma (tj. Raportowanie), znalazłeś wymóg biznesowy, który należy odpowiednio rozwiązać. Baza danych służy do przechowywania i ładowania własnego, chronionego stanu aplikacji; zezwalanie na raportowanie tworzy połączenie między twoją aplikacją a osobami, które potrzebują raportów. Jeśli DDD dotyczy czegoś, chodzi o rozdzielenie tych kontekstów.
Matt

Odpowiedzi:

4

Przyjmując architekturę DDD i cebulową, zdecydowałeś, że baza danych jest drugim po modelu domeny. Oznacza to, że nikt inny nie będzie wykonywać operacji na bazie danych poza modelem. Jeśli tradycjonaliści tego nie lubią, powinni przede wszystkim sprzeciwić się użyciu DDD.

Pierwsza rzecz jest jasna: potrzebujesz „tabeli odnośników” w modelu. Twój model musi rozróżniać różne typy kontaktów. Oznacza to, że utrzymuje silnie wpisaną listę wszystkich typów. Konieczne jest również mapowanie tych silnych typów na wartości, które są serializowane do bazy danych. To odwzorowanie może znajdować się w module bazy danych. Ale lista wszystkich możliwych typów będzie nadal znajdować się w modelu. A jeśli model ma być pojedynczym źródłem prawdy, to nie może znajdować się w bazie danych. A przynajmniej, gdy lista zmienia się w modelu, musi się zmienić w bazie danych. I żadnych ale!

Euforyk
źródło
2

Obiekty domeny przestają być obiektami domeny, gdy przekroczą granicę procesu . Nawet jeśli baza danych jest tylko magazynem trwałości, w pewnym momencie w przyszłości wymagania firmy spowodują zmianę w modelu domaim, który jest niezgodny z utrwaloną historią, a i tak będziesz potrzebować warstwy antykorupcyjnej …

To powiedziawszy, myślę, że twoi DBCentrists brakuje łodzi. Projektanci domen twierdzą, że potrzebują magazynu trwałości. „Raporty i inni konsumenci” potrzebują czegoś, do czego mogą zapytać - czegoś z przyzwoitymi indeksami, jak zauważono w komentarzach.

Kto wprowadził ograniczenie, że wszystkie te obawy muszą być obsługiwane przez jedną bazę danych? Co się stanie, jeśli odeprzesz to.

Szukane słowo kluczowe: CQRS.

VoiceOfUnreason
źródło
1

Znalazłem, że najlepiej jest przechowywać wyliczenia jako ich ciąg znaków w bazie danych i nie zawierać tabeli odnośników.

Oczywiście wadą jest to, że zużywa więcej miejsca na dysku i nie jest znormalizowany.

Plusem jest to, że pole zachowuje swoje znaczenie w db, nie kończą się na przykład magicznymi liczbami odpowiadającymi wartości int wyliczenia i nie musisz zarządzać wersjonowaniem tabeli odnośników, gdy zmienia się wyliczanie.

Nie jestem jednak pewien, czy scharakteryzuję to jako różnicę między DDD a tradem. To bardziej, że centralista bazy danych kontra kod jest według mnie najlepszy

Ewan
źródło
zastanawiam się, czy same bazy danych mają obecnie taką funkcję wyliczania
herzmeister
Myślę, że to zależy od DB, możesz robić różne szalone rzeczy CLR z MSSQL. Ale ja jestem zdecydowanie po stronie „Zła baza danych, dobry kod”, jeśli chodzi o takie rzeczy
Ewan
@herzmeister <3 PostgreSQL postgresql.org/docs/9.4/static/datatype-enum.html , Ewan Baza danych jest kodem po przyjęciu procedur przechowywanych. (PLv8 jest cudowny).
Sirisian
@Sirisian wiesz, że to coś łączy? Mam podobne pytanie. „czy skaluje się?”
Ewan
Czy masz na myśli, czy to robi krzyżowy produkt, aby przekształcić wyliczenie w strunę? Prawdopodobnie nie. Nie jestem pewien, jak to zaimplementowane, ale jest szybsze niż używanie osobnej tabeli. Skaluje się. Znalazłem to również: stackoverflow.com/questions/2318123/... Nadal wydaje się być prawidłową oceną 5 lat później. (Zwykle piszę programy silnie sprzężone z PostgreSQL, więc używam wszystkich funkcji, ale nie każdy może to zrobić).
Sirisian
0
  • Tak długo, jak używasz relacyjnej bazy danych, powinieneś normalizować tabele w rozsądnym zakresie. Normalizacja pomaga zapobiegać wstawianiu i aktualizowaniu anomalii.
  • Relacja jedna-aplikacja <-> jedna-baza danych nie jest już powszechna, wiele aplikacji może korzystać z wielu baz danych, a jedna baza danych może być używana przez wiele aplikacji, więc posiadanie bazy danych w miarę możliwości wymusza integralność referencyjną.
  • RDBMS jest twoim przyjacielem.
  • Zamiast tego możesz korzystać z magazynu kluczy i wartości i robić wszystko w kodzie.
Tulains Córdova
źródło