WPROWADZENIE I ISTOTNE INFORMACJE:
Poniższy przykład ilustruje problem, przed którym stoję:
Zwierzę ma rasę, którą może być kot lub pies . Kot może być syjamski lub perski . Psem może być owczarek niemiecki lub retrader labrador .
Zwierzę jest silną istotą, podczas gdy jego rasa jest atrybutem, który może mieć jedną z dwóch oferowanych wartości (kot lub pies). Obie te wartości są złożone (dodałem tutaj tylko typ psa / kota, aby zilustrować problem, ale może również zawierać imię kota / psa i kilka innych rzeczy).
PROBLEM:
Nie wiem, jak utworzyć tabele relacyjne dla tego przykładu.
MOJE DZIAŁANIA DO ROZWIĄZANIA PROBLEMU:
Próbowałem narysować schemat ER, używając notacji Chena, która reprezentuje problem, ale będąc początkującym nie wiem, czy zrobiłem to dobrze. Oto co mam:
Przepraszam, jeśli narysowałem coś nie tak, popraw mnie, jeśli tak jest. Nie chcę po prostu uzyskać „darmowego rozwiązania”, ale także nauczyć się radzić sobie z tym problemem, aby móc go rozwiązać samodzielnie w przyszłości.
Jedyne, co przychodzi mi do głowy, to stworzenie dwóch osobnych tabel, jednej dla kotów i jednej dla psów. Ponadto atrybut rasy w tabeli Zwierząt przechowuje tylko wartość kota lub psa . Coś takiego:
Animal< # Animal_ID, race, other attributes >
Cat < # Cat_ID, $ Animal_ID, breed >
Dog < # Dog_ID, $ Animal_ID, breed >
Naprawdę mam złe przeczucia co do mojego rozwiązania i obawiam się, że jest to złe, stąd poniższe pytanie.
PYTANIA:
- Jak mogę przekształcić mój przykład w diagram ER?
- Jak przekształcić ten diagram ER w tabele relacyjne?
Jeśli wymagane są dalsze informacje, zostaw komentarz, a ja zaktualizuję swój post jak najszybciej. Dodaj też odpowiednie tagi, ponieważ jestem tutaj dość nowy.
Dziękuję Ci.
źródło
Odpowiedzi:
Właściwą strukturą dla tego scenariusza jest model SubClass / Dziedziczenie i jest on prawie identyczny z koncepcją zaproponowaną w tej odpowiedzi: Heterogeniczna uporządkowana lista wartości .
Model zaproponowany w tym pytaniu jest właściwie dość podobny , ponieważ
Animal
jednostka zawiera typ (tj.race
) I właściwości wspólne dla wszystkich typów. Konieczne są jednak dwie niewielkie zmiany:Usuń pola Cat_ID i Dog_ID z odpowiednich encji:
Kluczowym założeniem jest to, że wszystko to
Animal
, bez względu narace
:Cat
,Dog
,Elephant
, i tak dalej. Biorąc pod uwagę, że punkt wyjścia, każde szczególnościrace
zAnimal
nie naprawdę potrzebny jest oddzielny identyfikator, ponieważ:Animal_ID
jest wyjątkowyCat
,Dog
oraz wszelkie innerace
podmioty, dodane w przyszłości nie przez siebie, w pełni reprezentować jakiś konkretnyAnimal
; mają jedynie znaczenie, gdy używany w połączeniu z informacjami zawartymi w jednostce dominującejAnimal
.Stąd
Animal_ID
nieruchomość wCat
,Dog
itp podmiotów jest zarówno PK i FK powrotem doAnimal
jednostki.Rozróżnij rodzaje
breed
:To, że dwie właściwości mają tę samą nazwę, niekoniecznie oznacza, że są one takie same, nawet jeśli ta sama nazwa implikuje taki związek. W tym przypadku, co naprawdę trzeba to faktycznie
CatBreed
iDogBreed
jako oddzielne „typów”Uwagi wstępne
VARCHAR
ale jeśli chcesz przechowywać coś poza standardowym zestawem ASCII, powinieneś naprawdę użyćNVARCHAR
.Race
,CatBreed
iDogBreed
) nie są automatycznie zwiększane (tj. TOŻSAMOŚĆ w kategoriach T-SQL), ponieważ są stałymi aplikacji (tj. Są częścią aplikacji), które są statycznymi wartościami wyszukiwania w bazy danych i są reprezentowane jakoenum
s w C # (lub innych językach). Jeśli wartości są dodawane, są one dodawane w kontrolowanych sytuacjach. Zastrzegam stosowanie pól automatycznego przyrostu dla danych użytkownika, które przychodzą za pośrednictwem aplikacji.„Rasa” jako podejście „wyścigowe”
Ten pierwszy zestaw tabel to tabele wyszukiwania / typów:
Ta druga lista to główna jednostka „Zwierząt”:
Trzeci zestaw tabel to uzupełniające się podklasy, które uzupełniają definicję każdego
Race
zAnimal
:Model wykorzystujący
breed
typ współdzielony pokazano po sekcji „Uwagi dodatkowe”.Dodatkowe uwagi
breed
wydaje się być centralnym punktem zamieszania. Jcolebrand zasugerował (w komentarzu do pytania), żebreed
jest to właściwość wspólna dla różnychrace
s, a pozostałe dwie odpowiedzi mają ją jako taką w swoich modelach. Jest to jednak błąd, ponieważ wartości dlabreed
nie są współużytkowane przez różne wartościrace
. Tak, jestem świadomy, że dwa inne proponowane modele próbują rozwiązać ten problem, tworzącrace
rodzicbreed
. Chociaż to technicznie rozwiązuje problem relacji, nie pomaga w rozwiązaniu ogólnego pytania dotyczącego modelowania tego, co zrobić z nietypowymi właściwościami, ani jak poradzić sobie zrace
tym, co nie mabreed
. Ale w przypadku, gdy zagwarantowano, że taka własność istniałaby we wszystkichAnimal
s, do tego dołączę opcję (poniżej).Animal
), lubrace
s były przechowywane wAnimal
encji, która jest bardzo płaskim (i prawie nierelacyjnym) sposobem reprezentowania tych danych. Tak, ludzie robią to przez cały czas, ale oznacza to, że dla wielu właściwości, które nie są przeznaczone dla tego konkretnego, jest wiele pól NULL na wierszrace
ORAZ wiedza, które pola na wiersz są powiązane z danymrace
rekordem.race
wAnimal
przyszłości, które nie mająbreed
jako własność. A nawet jeśli wszystkoAnimal
s mająbreed
, że nie zmieni strukturę ze względu na to, co zostało wcześniej zauważono okołobreed
: Tobreed
zależy odrace
(czylibreed
dlaCat
nie to samo, cobreed
dlaDog
).„Rasa” jako podejście do własności wspólnej / wspólnej
Proszę zanotować:
Poniższy kod SQL można uruchomić w tej samej bazie danych, co model przedstawiony powyżej:
Race
Tabeli jest taka samaBreed
Tabela jest nowyAnimal
tabel dołączono znak „2
Breed
jest to obecnie wspólna własność, nie wydaje się słuszne, aby nieRace
odnotować tego w głównej / macierzystej jednostce (nawet jeśli jest to technicznie poprawne). ObaRaceID
iBreedID
są reprezentowane wAnimal2
. Aby zapobiec niedopasowaniu międzyRaceID
zanotowanymAnimal2
i aBreedID
innymRaceID
, dodałem FK na obu,RaceID, BreedID
który odwołuje się do UNIKALNEGO OGRANICZENIA tych pól wBreed
tabeli. Zwykle nie znoszę wskazywać FK na WYJĄTKOWE OGRANICZENIE, ale oto jeden z niewielu ważnych powodów, aby to zrobić. WYJĄTKOWY OGRANICZENIE jest logicznie „kluczem alternatywnym”, co czyni go ważnym dla tego zastosowania. Należy również pamiętać, żeBreed
tabela wciąż ma PK tylkoBreedID
.BreedID
na powtórzenie tego samego dla różnych wartościRaceID
.BreedID
, więc nadal powinno być możliwe odniesienie się do konkretnej wartościBreed
bez jejRaceID
dostępności.Breed
(i dlatego wolę tabeleRace
-specyficzneBreed
).Breed
mają te same właściwości. W tym modelu nie ma łatwego sposobu na uzyskanie rozbieżnych właściwości międzyDog
„rasami” iElephant
„rasami”. Istnieje jednak sposób, aby to zrobić, co zostało odnotowane w sekcji „Edycja końcowa”.Breed
się więcej niż jedną rasą. Nie jestem pewien, czy jest to pożądane (a może nie w koncepcji zwierząt, ale być może w innych sytuacjach, w których używałby tego typu modelu), ale nie jest to możliwe tutaj.Ostateczna edycja (mam nadzieję ;-)
Breed
, to jest możliwe stosowanie tego samego podklasy / spadku koncepcji, ale wBreed
postaci głównej jednostki. W tym ustawieniuBreed
tabela miałaby właściwości wspólne dla wszystkich typówBreed
(podobnie jakAnimal
tabela) iRaceID
reprezentowałaby typBreed
(taki sam jak wAnimal
tabeli). Wtedy trzeba podklasy, takie jak tabeleBreedCat
,BreedDog
i tak dalej. W przypadku mniejszych projektów można to uznać za „nadmierną inżynierię”, ale wspomniano o niej jako o opcjach w sytuacjach, które z niej skorzystałyby.W przypadku obu podejść czasami pomaga tworzenie widoków jako skrót do pełnych elementów. Rozważ na przykład:
CreatedDate
Pola zostanie dodana doAnimal
tabeli. To pole nie jest potrzebne w żadnej z tabel podklasy (np.AnimalCat
), Ponieważ wiersze wstawiane dla obu tabel powinny być wykonywane w tym samym czasie w ramach transakcji.LastModifiedDate
Pola zostanie dodana doAnimal
tabeli i wszystkich stołach podklasy. To pole jest aktualizowane tylko wtedy, gdy ta konkretna tabela jest aktualizowana: jeśli aktualizacja wystąpi w określonym,AnimalCat
ale nieAnimal
dla określonegoAnimalID
, to ustawione zostanie tylkoLastModifiedDate
pole wAnimalCat
.źródło
D
, dlatego chciałem zastosować metodę z twojej odpowiedzi. Dwie jednostki mają wspólny atrybut,E
który nie występuje w trzeciej jednostce. Czy powinienem zignorować ten fakt i zastosować standardowe rozwiązanie, czy też istnieje sposób na dalszą optymalizację mojego projektu?Po pierwsze, dobrze sobie radzisz z rozróżnianiem między modelowaniem ER a modelowaniem relacyjnym. Wielu początkujących nie.
Oto kilka modnych słów, których możesz użyć do wyszukiwania pomocnych artykułów w Internecie.
Twój przypadek jest klasycznym przypadkiem klasy / podklasy lub, jeśli chcesz, wpisz / podtyp.
Fraza używana w modelowaniu ER to „uogólnienie / specjalizacja”. Wiele artykułów pokazuje to pod modelowaniem zwanym EER (Enhanced Entity-Relationship). Nie było to w oryginalnej prezentacji modelowania ER przez Petera Chena. Został dodany później. Aby uzyskać całkiem dobre podsumowanie gen / spec w formacie pdf, kliknij tutaj
Następnie, konwertując przypadek klasy / podklasy na modelowanie relacyjne, projektujesz tabele. Istnieje więcej niż jedno podejście. Dwa główne podejścia nazywane są dziedziczeniem pojedynczej tabeli i dziedziczeniem tabeli klas. Każda ma zalety i wady. Najlepsza prezentacja tych dwóch wzorów pochodzi od Martina Fowlera. Możesz zobaczyć jego zarys tutaj i tutaj .
Dużą zaletą dziedziczenia pojedynczego stołu jest prostota. Wszystko jest przechowywane w jednym stole. Dużą wadą jest wiele wartości NULLS. Może to marnować miejsce i czas i powodować mylącą logikę.
Dziedziczenie tabeli klas wymaga złączeń, ale są one proste i szybkie. Zwłaszcza jeśli używasz techniki zwanej wspólnym kluczem podstawowym, w której PK w tabelach podklasy jest kopią PK w tabeli nadklasy. Można tworzyć widoki dla każdej podklasy, która łączy dane nadklasy z danymi podklasy.
Wreszcie w tym obszarze znajduje się tag, który zbiera pytania podobne do twoich.
Oto on: podtypy
źródło
Widzę możliwy projekt jako
Stół
Race
Stół
Breed
Stół
Animal
Te wartości PK powyżej byłyby kolumną automatycznego zwiększania wartości. Inne kolumny w
Animal
tabeli można odpowiednio nazwać.źródło
Twoja obecna metoda nie jest zła. Jeśli jednak planujesz później dodać więcej ras (ptaków, ryb itp.), Utworzenie osobnej tabeli dla każdej z nich może być kłopotliwe. Poleciłbym coś takiego:
Według mnie rasa powinna mieć tylko jedną rasę. Jeśli więc zapiszesz rasę w tabeli zwierząt, będziesz mógł określić rasę, dołączając do tabeli rasy. Oczywiście dodaj dowolne inne atrybuty (imię, opis itp.) Do tabel Rasy i Wyścigu, jeśli to konieczne.
źródło