Según mi comprensión de sus especificaciones, su entorno empresarial implica una relación ternaria de nivel conceptual . En este sentido, debe definir:
- el tipo de relación (o asociación ) entre los tipos de entidad Persona y Encuesta ;
- el tipo de relación entre encuesta y pregunta ;
- el tipo de relación que establece la conexión entre los dos tipos de relación mencionados anteriormente y, como consecuencia, entre Persona , Encuesta y Pregunta , es decir, Respuesta (un nombre más corto que simplifica la interpretación, desde mi punto de vista).
Por lo tanto, considero que está en el camino correcto con su Enfoque 1 , aunque requiere algunas mejoras pequeñas (pero importantes) para que sea más preciso. Detallaré tales refinamientos y otras consideraciones relevantes en las siguientes secciones.
Reglas del negocio
Expandamos un poco las reglas comerciales aplicables y reformúlelas de la siguiente manera:
- Una persona se registra en encuestas de cero uno o muchos
- Una encuesta obtiene el registro de cero-una o muchas personas
- Una encuesta está integrada por preguntas de uno a muchos
- Una pregunta integra encuestas de cero uno o muchos
- Una pregunta recibe cero uno o muchos Respuestas
- Una respuesta es proporcionada por exactamente una persona en el contexto de exactamente una encuesta
Diagrama IDEF1X expositivo
Luego, he creado el IDEF1X, un diagrama que se presenta en la Figura 1 , que sintetiza las reglas comerciales formuladas anteriormente:
Una definición de integración para el modelado de información ( IDEF1X ) es una técnica de modelado altamente recomendable que fue establecida como estándar en diciembre de 1993 por el Instituto Nacional de Estándares y Tecnología de los Estados Unidos ( NIST ). Se basa sólidamente en el trabajo teórico escrito por el único fundador del modelo relacional , es decir, el Dr. EF Codd y también en la visión de entidad-relación desarrollada por el Dr. PP Chen .
La relación PersonSurvey
A mi entender, la relación PersonSurvey debe proporcionar un medio de autorización para que una persona pueda participar en una encuesta determinada . De esta manera, una vez que cierta persona se ha registrado en una encuesta específica , él o ella está autorizada a proporcionar respuestas a las preguntas que integran la encuesta respectiva .
La relación de SurveyQuestion
Supongo que la propiedad (o atributo) llamada suvery_question.question_number en su diagrama se usa para representar el Orden de presentación de una instancia de Pregunta dada con respecto a una Encuesta en particular . Como puede ver, he designado propiedades como SurveyQuestion.PresentationOrder , y creo que debe evitar que (i) dos o más valores de Question.QuestionNumber compartan (ii) el mismo valor de PresentationOrder en (iii) la misma ocurrencia de SurveyQuestion .
Para representar esa necesidad, he incluido una CLAVE ALTERNA (AK) compuesta en el cuadro que representa este tipo de entidad, que se compone de la combinación de propiedades ( SurveyNumber, QuestionNumber, PresentationOrder ). Como bien sabe, un AK compuesto puede declararse en un diseño DDL lógico con la ayuda de una restricción ÚNICA de varias columnas (como ejemplifiqué en la SurveyQuestion
tabla que forma parte del diseño DDL expositivo expuesto en algunas secciones a continuación).
El tipo de entidad de respuesta
Sí, con el tipo de entidad Respuesta estoy representando una relación entre otras dos relaciones ; que puede parecer extraño a primera vista, pero no hay nada malo con este enfoque, con tal de que (a) representa las características del contexto negocios de interés con precisión y (b) se representa adecuadamente en un diseño de nivel lógico.
Sí, tiene toda la razón, sería un error representar esa parte del escenario en el nivel lógico de abstracción por medio de dos Response.SurveyNumber
(o, digamos Response.SurveyId
) valores referenciados desde dos columnas diferentes en la misma Response
fila.
Diseño lógico derivado de 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)
);
Dos teclas extranjeras compuestas en la Response
mesa
Este es, probablemente, el punto más importante para discutir: las referencias hechas desde una Response
fila dada a
SurveyQuestion.SurveyNumber
y
SurveyPerson.SurveyNumber
debe tener valores coincidentes . En lo que a mí respecta, la mejor opción para hacer cumplir esta condición de manera declarativa es hacer uso de dos CLAVES EXTRANJERAS compuestas (FK).
Como se muestra en el diseño DDL, el primer FK hace referencia a la PersonSurvey
tabla PRIMARY KEY (PK), es decir (PersonId, SurveyNumber)
, y está conformado por las columnas Response.PersonId
y Response.SurveyNumber
.
El segundo FK apunta a la SurveyQuestion
tabla PK, es decir (SurveyNumber, QuestionNumber)
, y, en consecuencia, está formado por las columnas Response.SurveyNumber
y Response.QuestionNumber
.
De esta manera, la Response.SurveyNumber
columna es bastante instrumental ya que se usa como parte de una referencia FK en dos restricciones diferentes.
Con este método, uno garantiza la integridad referencial garantizada por el sistema de gestión de la base de datos de
- (a)
Response
a la PersonSurvey
;
- (b)
Response
a la SurveyQuestion
; y
- (c) cada una de las tablas que representan un tipo de entidad asociativa a las tablas que representan tipos de entidad independientes, a saber
Person
, Survey
y Question
.
Datos derivados para evitar anomalías de actualización
He notado en su diagrama dos elementos que valoro mencionar. Estos elementos están relacionados con dos PersonSurvey
columnas que pueden (deberían) derivarse .
En ese sentido, puede derivar el PersonSurvey.IsStarted
dato al consultar si una Person
ocurrencia dada ha proporcionado uno o más Responses
para Questions
integrar una exacta a Survey
través de la SurveyQuestion
tabla.
Y también puede obtener el PersonSurvey.IsCompleted
punto de datos determinando si una Person
instancia dada ha proporcionado un valor Response
a todos los Questions
que mantienen un valor de 'VERDADERO' en la IsMandatory
columna en una SurveyQuestion
fila específica .
Mediante la derivación de estos valores, está evitando algunas anomalías de actualización que eventualmente habrían surgido en caso de que haya mantenido dichos valores en la SurveyQuestion
columna.
Importante consideración
Como @Dave señala correctamente en su comentario, si enfrenta un requisito futuro que exige la gestión de diferentes tipos de respuestas que implican la gestión de fechas, valores numéricos, opción múltiple y otros aspectos posibles, tendrá que ampliar este diseño de base de datos.
ID
yNumber
, pero por lo demás, esto es fantástico. Gracias.Esta es una razón por la que no me gusta prefijar columnas cuando las migro como claves foráneas. En su primer caso, la herramienta de modelado puede obligarlo a prefijar una de las
survey_id
columnas de lasurvey_person_question_response
tabla. Es posible que pueda ajustar esto después de que se establezca la relación.Si es necesario, elimine el campo de identificación de encuesta redundante cuando cree el modelo físico donde no necesita la columna duplicada. Como ha identificado, ambos modelos tienen problemas, pero creo que el primer modelo es mejor en general.
fuente