Secondo la mia comprensione delle vostre specifiche, il vostro ambiente aziendale implica una relazione ternaria a livello concettuale . A questo proposito, è necessario definire:
- il tipo di relazione (o associazione ) tra i tipi di entità Person e Survey ;
- il tipo di relazione tra Sondaggio e Domanda ;
- il tipo di relazione che stabilisce la connessione tra i due suddetti tipi di relazione e, di conseguenza, tra Persona , Sondaggio e Domanda , ovvero Risposta (un nome più breve che semplifica l'interpretazione, dal mio punto di vista).
Quindi, ritengo che tu sia sulla buona strada con il tuo Approccio 1 , anche se richiede alcuni piccoli (ma importanti) perfezionamenti per renderlo più accurato. Descriverò in dettaglio tali perfezionamenti e altre considerazioni pertinenti nelle sezioni seguenti.
Regole di business
Ampliamo un po 'le regole aziendali applicabili e riformuliamole nel modo seguente:
- Una persona registra in zero-one-o-many Surveys
- Un sondaggio ottiene la registrazione di zero-uno-o-molte persone
- Un sondaggio è integrato da una a molte domande
- Una domanda integra zero-one-o-many Surveys
- Una domanda riceve zero-una-o-molte risposte
- Una risposta è fornita da esattamente una persona nel contesto di esattamente un sondaggio
Diagramma IDEF1X dell'esposizione
Quindi, ho creato l'IDEF1X un diagramma che è presentato in Figura 1 , che sintetizza le regole di business formulate sopra:
una definizione di integrazione per la modellazione delle informazioni ( IDEF1X ) è una tecnica di modellazione altamente raccomandabile che è stata stabilita come standard nel dicembre 1993 dal National Institute of Standards and Technology ( NIST )degli Stati Uniti. È solidamente basato sul lavoro teorico creato dall'unico fondatore del modello relazionale , vale a dire il dott. EF Codd e anche sulla visione entità-relazione sviluppata dal dott. PP Chen .
La relazione PersonSurvey
A mio avviso , la relazione PersonSurvey è tenuta a fornire un mezzo di autorizzazione affinché una persona possa prendere parte a un determinato sondaggio . In questo modo, una volta che una determinata persona è stata registrata in un sondaggio specifico , è autorizzata a fornire risposte alle domande che integrano il rispettivo sondaggio .
La relazione SurveyQuestion
Suppongo che la proprietà (o l'attributo) chiamata suvery_question.question_number nel diagramma sia utilizzata per rappresentare l' ordine di presentazione di una determinata istanza della domanda rispetto a un determinato sondaggio . Come puoi vedere, ho indicato una proprietà come SurveyQuestion.PresentationOrder e penso che dovresti impedire che (i) due o più valori Question.QuestionNumber condividano (ii) lo stesso valore PresentationOrder in (iii) la stessa occorrenza di SurveyQuestion .
Per illustrare tale necessità, ho incluso un ALTERNATE KEY composito (AK) nella casella che rappresenta questo tipo di entità, che comprende la combinazione di proprietà ( SurveyNumber, QuestionNumber, PresentationOrder ). Come ben sapete, un AK composito può essere dichiarato in un progetto DDL logico con l'aiuto di un vincolo UNIQUE multi-colonna (come ho esemplificato nella SurveyQuestion
tabella che fa parte del layout DDL espositivo esposto alcune sezioni di seguito).
Il tipo di entità Response
Sì, con il tipo di entità Response sto descrivendo una relazione tra altre due relazioni ; esso può sembrare imbarazzante a prima vista, ma non c'è niente di sbagliato in questo approccio, finché (a) rappresenta le caratteristiche del contesto di business di interesse in modo accurato e (b) è rappresentato correttamente in un layout logico di livello.
Sì, hai perfettamente ragione, sarebbe un errore rappresentare quella parte dello scenario a livello logico di astrazione per mezzo di due Response.SurveyNumber
(o, diciamo, Response.SurveyId
) valori a cui fanno riferimento due colonne diverse nella stessa Response
riga.
Layout logico SQL-DDL derivato
-- 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)
);
Due tasti ESTERI compositi nella Response
tabella
Questo è, probabilmente, il punto più importante da discutere: i riferimenti fatti da una data Response
riga a
SurveyQuestion.SurveyNumber
, e
SurveyPerson.SurveyNumber
deve avere valori corrispondenti . Per quanto mi riguarda, l'opzione migliore per applicare questa condizione in modo dichiarativo è l'uso di due CHIAVE STRANIERE composte (FK).
Come mostrato nel progetto DDL, il primo FK sta facendo un riferimento alla PersonSurvey
tabella PRIMARY KEY (PK), ovvero (PersonId, SurveyNumber)
, ed è conforme alle colonne Response.PersonId
e Response.SurveyNumber
.
Il secondo FK punta alla SurveyQuestion
tabella PK, ovvero (SurveyNumber, QuestionNumber)
, ed è, di conseguenza, composto dalle colonne Response.SurveyNumber
e Response.QuestionNumber
.
In questo modo, la Response.SurveyNumber
colonna è piuttosto strumentale poiché viene utilizzata come parte di un riferimento FK in due diversi vincoli.
Con questo metodo, si garantisce l' integrità referenziale garantita dal sistema di gestione del database
- (a)
Response
al PersonSurvey
;
- (b)
Response
al SurveyQuestion
; e
- (c) ciascuna delle tabelle che rappresentano un tipo di entità associativa alle tabelle che rappresentano tipi di entità indipendenti, vale a dire
Person
, Survey
e Question
.
Dati derivati per evitare anomalie di aggiornamento
Ho notato nel tuo diagramma due elementi che valuto la pena menzionare. Questi elementi sono correlati a due PersonSurvey
colonne che possono (dovrebbero) essere derivate .
A tale proposito, è possibile derivare l'origine PersonSurvey.IsStarted
eseguendo una query se una determinata Person
occorrenza ne ha fornito uno o più Responses
per Questions
integrare un esatto Survey
tramite la SurveyQuestion
tabella.
E puoi anche ottenere il PersonSurvey.IsCompleted
punto dati determinando se una determinata Person
istanza ha fornito Response
a tutto Questions
ciò che contiene un valore di "VERO" nella IsMandatory
colonna in una SurveyQuestion
riga specifica .
Tramite la derivazione di questi valori, si stanno impedendo alcune anomalie di aggiornamento che si sarebbero eventualmente verificate nel caso in cui si fossero mantenuti tali valori nella SurveyQuestion
colonna.
Considerazione importante
Come giustamente sottolinea @Dave nel suo commento, se si fronteggia un requisito futuro che richiede la gestione di diversi tipi di risposte che implicano la gestione di date, valori numerici, scelta multipla e altri possibili aspetti, sarà necessario estendere questo layout del database.
ID
eNumber
, ma per il resto è fantastico. Grazie.