5

Pracuję nad aplikacją do zarządzania podróżami. Omawiany projekt wygląda następująco:Należy unikać zależności kołowej

Każda osoba w trasie jest wyznaczona jako Podróżniczka. Każdy podróżujący ma paszport. Teraz Podróżnikiem może być Członek Główny lub Podoficer, w zależności od tego, czy jest on głową rodziny. A MainMember decyduje się na takie rzeczy, jak pakiet TourPackage, łączna kwota dla jego rodziny podróżującej itp. Podmorski jest zależny od głównego użytkownika podczas podróży. Tak więc, jeśli MainMember zostanie usunięty, wszystkie jego SubMembers muszą zostać usunięte.

Tak, Podróżny ma paszport. (Relacja jeden do jednego) Podróżny jest albo członkiem zarządu, albo członkiem grupy. (jeden do zera/jeden między Traveler-MainMember i Traveler-SubMember) A MainMember może mieć kilka SubMembers. (jeden-do-wielu) Submember ma tylko jedną MainMembers. (wiele-do-jednego)

Moje obecne ERD jest coś w następujący sposób.

Traveler ER Diagram

Jak widać, trzy stoliki - podróżników, MainMember i podelementu - utworzyli kołową zależność. Nie jestem pewien, czy to zrani moją aplikację. Jeśli usuwam Traveler, który jest elementem MainMember, wówczas 1. Rekord produktu Traveler został usunięty. 2. Odpowiedni rekord MainMember został usunięty. 3. Rekordy podrzędne zależne od członka głównego są usuwane. 4. Rekordy Traveler dla SubMembers zostaną usunięte.

Chociaż nie wydaje się to być problemem, ponieważ usuwanie Traveler-MainMember zawsze usunie tylko Traveler-SubMember (s). Mimo to mam złe przeczucia.

Czy każdy może mnie poprowadzić do lepszego projektu?

AKTUALIZACJA -

czekając na odpowiedzi, ja przyszedłem z innego projektu, na podstawie @ post Daveo użytkownika. Zasadniczo produkt Traveler zawiera samoodnoszący się klucz obcy. Byłby wykorzystywany przez rekordy Podmorskich do identyfikacji swoich rodziców.

Oto ERD do tego.

ERD with Self Referential table

Teraz, jak nie było problemem uzależnienia od kołowego w moim poprzednim wzorem, jak wskazano przez @Branko, chciałbym wiedzieć, który projekt jest lepszy?

Ponadto, który projekt lepiej byłoby zaimplementować za pomocą Hibernacji? Myślę, że drugie podejście może doprowadzić do złożoności podczas implementacji przez Hibernate.

Chciałbym również docenić niektóre wskazówki dotyczące wzorów realizacji (dziedziczenie w obiektach hibernacji, itp.) Dla projektu, który wolisz.

+0

używać dziedziczenia dla MainMember i SubMember (rozszerzając Traveler) –

+0

@guido - Rzeczywiście, to jest moja myśl, kiedy wdrażam te podmioty POJO. Ale w jaki sposób rozwiązuje to okrągłą zależność w projekcie bazy danych? Albo źle zrozumiałem twoje oświadczenie. Będę wdzięczny, jeśli rozwiniesz to jako odpowiedź. –

+0

zajrzyj tutaj http://openjpa.apache.org/builds/1.0.0/apache-openjpa-1.0.0/docs/manual/jpa_overview_mapping_inher.html#jpa_overview_mapping_inher_tpc –

Odpowiedz

4

Jak widać, trzy stoliki - podróżnik, MainMember i podelementu - utworzyli zależność cykliczną.

nie, to nie jest okrągły zależność - nie „węzeł” w tym wykresie można osiągnąć się stosując Graph „krawędzie” we właściwym kierunku . Byłoby to dokładniej opisane jako zależność "scalona" lub nawet (proto) "w kształcie rombu".

I nie, nie zaszkodzi to twojej aplikacji.

Jesteś skutecznego wdrożenia dziedziczenie podejście (aka kategorii, podklasy, podtypy, hierarchia generalizacji etc.), przy użyciu "każdą klasę w osobnej tabeli". To podejście jest czyste, ale nie może zagwarantować, że po wyjęciu z pudełka zostanie wykryta obecność i wyłączność. Istnieją sposoby na amend it, tak jest, i istnieją inne strategie wdrażania dziedziczenia, które mogą, ale mają one własne pros and cons.

Moim zdaniem, twój model jest w porządku, ponieważ to, co próbujesz osiągnąć, i egzekwowanie obecności/wyłączności na poziomie aplikacji jest prawdopodobnie mniejszym złem niż cierpienie za to, że próbuje wymusić na poziomie bazy danych.


"kierunek" jest od odwoływania się do wskazanej tabeli. Traveller nie odnosi się do MainMember ani SubMember i dlatego przerywa cykl.

ile jesteś w DBMS (takich jak MS SQL Server), że nie popiera działań referencyjnych na takie „połączone” zależnościami (w tym przypadku trzeba by wdrożyć ON DELETE CASCADE przez wyzwalacze).

Traveller nie może istnieć samodzielnie (nie może być "abstract"), to musi być MainMember lub SubMember.

Traveller nie może być zarówno MainMember i SubMember.

+0

Dzięki za wyczyszczenie tego. Nawet ja wątpię, czy była to zależność okrągła (nawet podczas kąpieli rysowałam "proto diamentowy kształt" ;-)). Twoja odpowiedź to potwierdziła. –

+0

Proszę spojrzeć na inny wzór, który wykonałem później. Chciałbym poznać Twoją opinię na temat tego, który projekt jest lepszy i dlaczego tak jest. –

1

Mam tylko dwie tabele w bazie danych.

podróżników i hasło

podróżników będzie mieć pole parent_id która połączy z powrotem do stołu podróżników i przechowywania który podróżny Główna/Head. Przechowuj również pola wspólne dla członka głównego/podrzędnego w tej tabeli, np. Numer kontaktowy

Następnie przy użyciu dziedziczenia i ORM utwórz dwie różne klasy w rzeczywistej aplikacji. MainMember i podelementu MainMember byłyby wszystkie wiersze w Traveler gdzie parent_id jest null podelementu byłyby wszystkie wiersze w Traveler gdzie parent_id nie jest null

+0

Jednak to podejście zakończy się dużą liczbą pustych wartości w tabeli pojedynczego produktu Traveler. MainMember ma 6 specyficznych cech, a SubMember ma 2. Zatem kolumny MainMember pozostaną puste dla SubMember i na odwrót. To był główny powód, dla którego oddzieliłem dwie tabele od Traveler - aby przechowywać ich specjalne znaki. –

+0

jaki jest problem z wartościami pustymi? – Daveo

+0

Dobrze. Zastanówmy się nad rekordem Submember. 6 z 17 (tak, Traveler ma wiele właściwości) kolumny pozostaną zasadniczo puste, ponieważ te właściwości należą do MainMember. Poza tym Submember czuje się nie na miejscu w tej sytuacji - trzymanie właściwości MainMember razem z nim. Tutaj leży moja troska. Jakie są twoje przemyślenia na ten temat? –