Zgodnie z moim rozumieniem twoich specyfikacji, twoje środowisko biznesowe obejmuje relacje trójstronne na poziomie koncepcyjnym . W związku z tym musisz zdefiniować:
- typ relacji (lub powiązania ) między typami jednostek Osoba i ankieta ;
- rodzaj relacji między ankietą a pytaniem ;
- typ relacji, który ustanawia połączenie między dwoma wyżej wymienionymi typami relacji, aw konsekwencji między osobą , ankietą i pytaniem , tj. odpowiedź (krótsza nazwa, która upraszcza interpretację, z mojego punktu widzenia).
Uważam więc, że podążasz właściwą drogą z podejściem 1 , chociaż wymaga ona drobnych (ale ważnych) udoskonaleń, aby uczynić ją bardziej dokładną. Szczegółowo przedstawię takie udoskonalenia i inne istotne uwagi w poniższych sekcjach.
Zasady biznesowe
Rozwińmy nieco obowiązujące reguły biznesowe i przeformułujmy je w następujący sposób:
- Osoby rejestry zero-jeden-or-wielu ankietach
- Survey dostaje rejestrację zero-jeden-lub-wiele osób
- Survey jest zintegrowany przez jeden-do-wielu pytań
- Pytanie integruje zero-jeden-lub-many Surveys
- Pytanie otrzymuje zero-jeden-lub-wiele Odpowiedzi
- Response jest dokładnie-jednej osoby w kontekście dokładnie jeden lat Survey
Schemat IDEF1X dla ekspozytora
Potem stworzyliśmy IDEF1X się schemat, który jest przedstawiony na rysunku 1 , który syntetyzuje reguł biznesowych sformułowanych powyżej:
Definicja Integration for Information Modeling ( IDEF1X ) jest godne polecenia technika modelowania, które powstało jako standardu w grudniu 1993 roku przez Narodowy Instytut Standardów Stanów Zjednoczonych i Technologii ( NIST ). Jest solidnie oparte na pracach teoretycznych autorem przez jedynego założyciela tego modelu relacyjnego , czyli dr EF Codd a także na widoku związków encji opracowanej przez dr PP Chen .
PersonSurvey relacja
Moim zdaniem relacja PersonSurvey jest wymagana, aby zapewnić sposób autoryzacji, aby osoba mogła wziąć udział w ankiecie . W ten sposób, gdy dana osoba zostanie zarejestrowana w konkretnej ankiecie , jest ona upoważniona do udzielania odpowiedzi na pytania, które obejmują odpowiednią ankietę .
SurveyQuestion relacja
Zakładam, że właściwość (lub atrybut) o nazwie suvery_question.question_number na diagramie jest używana do reprezentowania kolejności prezentacji danego wystąpienia pytania w odniesieniu do określonej ankiety . Jak widać, mam taką właściwość oznaczona jako SurveyQuestion.PresentationOrder i myślę, że należy zapobiec, że (i) dwóch lub więcej Question.QuestionNumber wartości akcji (ii) ta sama PresentationOrder wartość w (iii) tego samego SurveyQuestion wystąpienia.
Aby zilustrować tę potrzebę, dołączyłem złożony klucz ALTERNATYWNY (AK) w polu reprezentującym ten typ jednostki, który składa się z kombinacji właściwości ( SurveyNumber, QuestionNumber, PresentationOrder ). Jak dobrze wiadomo, złożoną AK można zadeklarować w logicznym projekcie DDL za pomocą wielokolumnowego ograniczenia UNIQUE (jak zilustrowałem to w SurveyQuestion
tabeli, która jest częścią układu DDL ekspozycyjnego objaśnionego w kilku sekcjach poniżej).
Odpowiedzi typu jednostki
Tak, z typem jednostki odpowiedzi przedstawiam relację między dwoma innymi relacjami ; to może wydawać się niewygodne na pierwszy rzut oka, ale nie ma nic złego z tym podejściem, tak długo, jak to (a) reprezentuje cechy kontekście biznesowym zainteresowania dokładnie i (b) jest prawidłowo reprezentowana w układzie logicznym poziomie.
Tak, masz całkowitą rację, błędem byłoby zobrazowanie tej części scenariusza na logicznym poziomie abstrakcji za pomocą dwóch Response.SurveyNumber
(lub powiedzmy Response.SurveyId
) wartości, do których odnoszą się dwie różne kolumny w tym samym Response
rzędzie.
Pochodzi logiczny układ SQL-DDL
-- You should determine which are the most fitting
-- data types and sizes for all your table columns
-- depending on your business context characteristics.
-- As one would expect, you are free to make use of
-- your preferred (or required) naming conventions.
CREATE TABLE Person (
PersonId INT NOT NULL,
FirstName CHAR(30) NOT NULL,
LastName CHAR(30) NOT NULL,
GenderCode CHAR(3) NOT NULL,
BirthDate DATE NOT NULL,
CreatedDateTime DATETIME NOT NULL,
--
CONSTRAINT Person_PK PRIMARY KEY (PersonId),
CONSTRAINT Person_AK UNIQUE (
FirstName,
LastName,
GenderCode,
BirthDate
)
);
CREATE TABLE Survey (
SurveyNumber INT NOT NULL,
Description CHAR(255) NOT NULL,
CreatedDateTime DATETIME NOT NULL,
--
CONSTRAINT Survey_PK PRIMARY KEY (SurveyNumber),
CONSTRAINT Survey_AK UNIQUE (Description)
);
CREATE TABLE PersonSurvey (
PersonId INT NOT NULL,
SurveyNumber INT NOT NULL,
RegisteredDateTime DATETIME NOT NULL,
--
CONSTRAINT PersonSurvey_PK PRIMARY KEY (PersonId, SurveyNumber),
CONSTRAINT PersonSurveyToPerson_FK FOREIGN KEY (PersonId)
REFERENCES Person (PersonId),
CONSTRAINT PersonSurveyToSurvey_FK FOREIGN KEY (SurveyNumber)
REFERENCES Survey (SurveyNumber)
);
CREATE TABLE Question (
QuestionNumber INT NOT NULL,
Wording CHAR(255) NOT NULL,
CreatedDateTime DATETIME NOT NULL,
--
CONSTRAINT Question_PK PRIMARY KEY (QuestionNumber),
CONSTRAINT Question_AK UNIQUE (Wording)
);
CREATE TABLE SurveyQuestion (
SurveyNumber INT NOT NULL,
QuestionNumber INT NOT NULL,
PresentationOrder TINYINT NOT NULL,
IsMandatory BIT NOT NULL,
IntegratedDateTime DATETIME NOT NULL,
--
CONSTRAINT SurveyQuestion_PK PRIMARY KEY (SurveyNumber, QuestionNumber),
CONSTRAINT SurveyQuestion_AK UNIQUE (
QuestionNumber,
SurveyNumber,
PresentationOrder
),
CONSTRAINT SurveyQuestionToSurvey_FK FOREIGN KEY (SurveyNumber)
REFERENCES Survey (SurveyNumber),
CONSTRAINT SurveyQuestionToQuestion_FK FOREIGN KEY (QuestionNumber)
REFERENCES Question (QuestionNumber)
);
CREATE TABLE Response (
SurveyNumber INT NOT NULL,
QuestionNumber INT NOT NULL,
PersonId INT NOT NULL,
Content TEXT NOT NULL,
ProvidedDateTime DATETIME NOT NULL,
--
CONSTRAINT Response_PK PRIMARY KEY (SurveyNumber, QuestionNumber, PersonId),
CONSTRAINT ResponseToPersonSurvey_FK FOREIGN KEY (PersonId, SurveyNumber)
REFERENCES PersonSurvey (PersonId, SurveyNumber),
CONSTRAINT ResponseToSurveyQuestion_FK FOREIGN KEY (SurveyNumber, QuestionNumber)
REFERENCES SurveyQuestion (SurveyNumber, QuestionNumber)
);
Dwa złożone KLUCZE ZAGRANICZNE w Response
tabeli
Jest to prawdopodobnie najważniejszy punkt do omówienia: odniesienia z danego Response
wiersza do
SurveyQuestion.SurveyNumber
, i
SurveyPerson.SurveyNumber
musi mieć pasujące wartości . Jeśli chodzi o mnie, najlepszą opcją do egzekwowania tego warunku w deklaratywny sposób jest użycie dwóch złożonych KLUCZÓW ZAGRANICZNYCH (FK).
Jak pokazano w projekcie DDL, pierwszy FK odnosi się do PersonSurvey
tabeli KLUCZ PODSTAWOWY (PK), tj. (PersonId, SurveyNumber)
I jest zgodny z kolumnami Response.PersonId
i Response.SurveyNumber
.
Drugi FK wskazuje na SurveyQuestion
tabelę PK, tj. (SurveyNumber, QuestionNumber)
I odpowiednio składa się z kolumn Response.SurveyNumber
i Response.QuestionNumber
.
W ten sposób Response.SurveyNumber
kolumna jest dość instrumentalna, ponieważ jest używana jako część odniesienia FK w dwóch różnych ograniczeniach.
Dzięki tej metodzie, jeden gwarantuje zarządzania bazą danych systemu gwarantuje integralności referencyjnej z
- (a)
Response
do PersonSurvey
;
- (b)
Response
do SurveyQuestion
; i
- (c) każdy z tabel przedstawiających asocjacyjny typu jednostki do tabel stałego niezależnych typów elementów, a mianowicie
Person
, Survey
i Question
.
Dane pochodne, aby uniknąć nieprawidłowości aktualizacji
Na twoim diagramie zauważyłem dwa elementy, które uważam za warte wspomnienia. Te elementy są powiązane z dwiema PersonSurvey
kolumnami, które można (należy) wyprowadzić .
W tym względzie można uzyskać dane PersonSurvey.IsStarted
odniesienia, sprawdzając, czy dane Person
wystąpienie dostarczyło jedną lub więcej takich danych Responses
do Questions
zintegrowania za Survey
pomocą SurveyQuestion
tabeli.
Możesz także uzyskać PersonSurvey.IsCompleted
punkt danych, określając, czy dana Person
instancja dostarczyła a Response
wszystkim, Questions
które zawierają wartość „PRAWDA” w IsMandatory
kolumnie w określonym SurveyQuestion
wierszu.
Poprzez wyprowadzenie tych wartości zapobiegasz niektórym anomaliom aktualizacji, które ostatecznie powstałyby, gdybyś zachował takie wartości w SurveyQuestion
kolumnie.
Ważna uwaga
Jak słusznie podkreśla @Dave w swoim komentarzu, jeśli napotkasz przyszłe wymagania wymagające zarządzania różnego rodzaju odpowiedziami, które wymagają zarządzania datami, wartościami liczbowymi, wielokrotnym wyborem i innymi możliwymi aspektami, będziesz musiał rozszerzyć ten układ bazy danych.
ID
aNumber
, ale poza tym to jest fantastyczne. Dziękuję Ci.To jeden z powodów, dla których nie lubię prefiksować kolumn podczas migracji ich jako kluczy obcych. W pierwszym przypadku narzędzie do modelowania może zmusić Cię do prefiksu jednego z nich
survey_id
kolumn wsurvey_person_question_response
tabeli. Być może będziesz w stanie to zmienić po nawiązaniu relacji.W razie potrzeby usuń zbędne pole identyfikatora ankiety podczas budowania modelu fizycznego, w którym nie potrzebujesz zduplikowanej kolumny. Jak już zauważyłeś, oba modele mają problemy, ale uważam, że pierwszy model jest ogólnie lepszy.
źródło