Respuestas a sus preguntas individuales.
Si deseo agregar una columna Club
que describa al propietario, que también será miembro, ¿cuál es el mejor enfoque sin tener el mismo miembro en la lista dos veces?
Si, como se indica en sus especificaciones a Person can be a Member of only one Club
, y está interesado en almacenar este dato simplemente como verdadero o falso , una opción es agregar una BIT(1)
o una columna BOOLEAN
( TINYINT
) a la Person
tabla, y puede llamar a esta columna IsClubOwner
. De esta manera, puede registrar el hecho de que una persona determinada es propietaria de un club exclusivamente una vez. Aparte de eso, este método también permite la posibilidad de retener a varias personas como propietarios de la misma ocurrencia del club . Puede ver una representación a nivel lógico de este enfoque en la Figura 1 .
Sin embargo, está buscando el mejor enfoque y, según mi experiencia, dicho enfoque implica el desarrollo de una estructura mucho más ampliable y versátil. A este respecto, siga la progresión de un ejercicio de modelado para estos y otros puntos a continuación, en las secciones tituladas "Cubriendo sus especificaciones restantes", "Persona como miembro de varios clubes" y "Miembro y propietario como tipos de entidad separados".
¿Debo poner todas mis tablas en incrementos automáticos de id
o sería una mala idea? (¿ventajas / desventajas?)
Si enfrenta un requisito explícito que indica la definición de una tabla con una columna de tales características, y esa columna tiene un significado contextual válido o tiene un propósito particular, como ser un sustituto de una CLAVE PRIMARIA (PK) natural amplia , entonces sí, deberías proceder de esa manera.
De lo contrario, si no tiene dicho requisito, considero que sería innecesario ya que debe almacenar y administrar una columna adicional sin sentido y (¿tal vez?) También un ÍNDICE adicional en su base de datos.
Como de costumbre, debe analizar cada caso junto con sus repercusiones generales para decidir cómo continuar.
Si agrego claves foráneas en la pestaña de claves foráneas, ¿estas corresponderán automáticamente a la tabla correcta o tengo que agregarlas también a las columnas?
En este sentido, mi consejo para usted es crear la estructura de su base de datos de forma manual, para codificar sus propias DDL
declaraciones hasta que obtenga una comprensión firme del tema. Si lo hace, le será más fácil comprender los procesos que las herramientas gráficas están realizando "bajo el capó".
Para mí, por ejemplo, crear una declaración como la siguiente:
CONSTRAINT FK_PersonPhoneNumber_to_Person FOREIGN KEY (PersonId)
REFERENCES Person (PersonId)
Es mucho más instructivo que usar herramientas GUI para ejecutar este tipo de tareas, especialmente ahora que está creando sus primeros diseños.
Y mi pregunta probablemente más novata de todas ... ¿Pongo las claves foráneas de phone_number
y email
en sus respectivas tablas vinculadas a una person_id
o debo poner phone_number
y email
ids
en la tabla de persona?
Personalmente, creo que esta y todas sus otras preguntas son completamente válidas y están bien contextualizadas .
Volviendo a los aspectos técnicos que nos preocupan, esta investigación precisa ofrece una buena oportunidad para revisar las dos afirmaciones siguientes:
A Person can be reached through zero-one-or-many PhoneNumbers
A PhoneNumber can be used to reach one-to-many People
Entonces, uno puede concluir que hay una relación de muchos a muchos entre Person
y PhoneNumber
, por lo tanto, sugiero la creación de una tabla asociativa nombrada PersonPhoneNumber
para representar dicha relación en su base de datos. El PK de esta tabla debe estar compuesto por dos columnas diferentes: PersonId
(una TECLA EXTRANJERA [FK] apuntando hacia Person.PersonId
) y PhoneNumber
(un FK que hace referencia a PhoneNumber.Number
). Para obtener una descripción de nivel lógico de todo lo anterior, consulte la Figura 1 .
Por otro lado, examinemos las dos proposiciones que siguen:
A Person can be contacted via zero-one-or-many EmailAddresses
An EmailAddress can be used to contact exactly one Person
Entonces, sí, debe establecer una referencia FK Person
desde la EmailAddress
tabla, y esta tabla también debe tener un PK compuesto, que estaría compuesto por las columnas PersonId
y Address
. De esta manera, puede asegurarse de que la misma combinación de EmailAddress.PersonId
y EmailAddress.Address
se pueda insertar solo una vez.
Si también desea asegurarse de que un determinado EmailAddres.Address
puede almacenarse en una sola fila, solo tiene que establecer una RESTRICCIÓN ÚNICA para esta columna.
Modelos de datos lógicos propuestos
Para exponer mis sugerencias más claramente, incluí cuatro modelos lógicos IDEF1X [1] distintos que se muestran en la Figura 1 , Figura 2 , Figura 3 y Figura 4 . Proporcionaré una explicación de las características más relevantes que se muestran en cada una de ellas en las secciones correspondientes. También puede descargar de Dropbox un PDF que integra en un solo modelo la mayoría de los elementos en discusión.
Cubriendo sus especificaciones restantes
Relacionar personas y direcciones
Inspeccionemos las dos siguientes afirmaciones (ligeramente redactadas) que son relevantes para las personas y las direcciones :
A Person can only have one Address
An Address can belong to different People (couples or siblings)
Entonces, para lidiar con estas restricciones, puede optar por implementar un modelo de datos similar al que puede ver en la Figura 1 .
Teniendo en cuenta el modelo referido, debe seguir los siguientes pasos:
Crea una tabla llamada PersonAddress
arreglar una relación entre Person
y Address
. Establezca las columnas PersonId
y AddressId
como el PK compuesto de esta tabla.
Configure una RESTRICCIÓN ÚNICA para la PersonAddress.PersonId
columna para garantizar que se pueda insertar un valor específico como máximo en una fila de dicha tabla. En el nivel lógico, esta circunstancia implica que se PersonAddress.PersonId
ha convertido en una CLAVE ALTERNATIVA [2] .
Si el valor de AddressId
un PersonAddress
intento de inserción determinado aún no se ha almacenado, deje que la inserción continúe; de lo contrario, cuando dicho valor ya exista en una fila, debe verificar que (a) el PersonId
que se ha registrado AddressId
también está registrado como el Marriage.WifeId
si el PersonId
es un hombre (dato derivado de la Person.GenreCode
) o (b) que PersonId
es el Marriage.HusbandId
cuando el PersonId
es una mujer (derivado también en virtud de Person.GenreCode
). Si una de estas condiciones se cumple en la situación adecuada, entonces debe dejar que INSERT continúe.
Si no se cumplieron las condiciones anteriores, todavía existe la posibilidad de que una PersonAddress
inserción intente tener éxito. Debe comprobar que el PersonId
valor que está involucrado en dicho intento de inserción comparte al menos uno Progeny.ParentId
con el PersonId
que ya ha registrado el PersonAddress.AddressId
. Si se cumple esta condición, significa que se almacenan como Siblings
en la base de datos, por lo que este INSERT debe tener éxito.
Como en cualquier implementación de base de datos relacional, debe considerar seriamente la ejecución de sus DML
operaciones dentro de las transacciones ACID para que pueda proteger la integridad y la coherencia de los datos con los que está trabajando.
Asistir a los requisitos que agregó en los comentarios: Direcciones y números de teléfono que sirven igualmente a Clubes y Personas
Con la condición de que desee dar la oportunidad de que las direcciones y los números de teléfono sirvan tanto a las personas como a los clubes , puede utilizar una relación de supertipo-subtipo . Aquí hay una respuesta en la que le doy un tratamiento más detallado a este tipo de estructuras, en caso de que esté interesado.
En el escenario actual, podría definir Person
y Club
como subtipos de una nueva entidad nombrada Party
, un término comúnmente utilizado en círculos legales para representar (a) una persona o (b) un grupo de personas (como se señaló en el sentido no. 6 ). Con este método, las relaciones entre Addresses
(o PhoneNumbers
) y People
y Clubs
se definirían a través Party
del supertipo. Consulte la Figura 2 para ver una descripción de esta sugerencia.
Fiesta y domicilio
Entonces podemos leer en este nuevo modelo que:
A Party keeps zero-one-or-many Addresses
An Address is kept by one-to-many Parties
Por lo tanto, existe una relación de muchos a muchos relacionados Party
y Address
que se expresa a través de la PartyAddress
entidad.
Fiesta y número de teléfono
Además, podemos interpretar que:
A Party is reached through zero-one-or-many PhoneNumbers
A PhoneNumber is used by one-to-many Parties
Es por eso que he añadido la PartyPhoneNumber
entidad que describe la asociación muchos-a-muchos que se lleva a efecto entre las Party
y PhoneNumber
entidad tipos.
Fiesta y Club o Persona
Entonces, también se puede leer que:
A Party is either a Club or a Person
Por lo tanto, Party
suministra una conexión de cualquiera de los dos Clubs
o People
a Addresses
(o PhoneNumbers
).
Persona como miembro de múltiples clubes
Como @aldwinaldwin menciona en su respuesta, si desea proporcionar la funcionalidad para que una persona sea miembro de varios clubes , puede incluir una tabla llamada ClubMember
que estaría actuando como otra relación de muchos a muchos, esta vez, naturalmente , interconectados Person
y Club
.
Agregaré a lo anterior que esta tabla también puede ser útil en el objetivo de almacenar a cualquier persona concreta como propietaria de múltiples clubes , mediante la inclusión de la IsClubOwner
columna booleana ya mencionada . De hecho, se puede decir que esta nueva tabla es la representación de un tipo de entidad integral por derecho propio.
Como se demostró en la Figura 3 , dicha tabla requiere un PK compuesto formado por las columnas ClubId
y MemberId
(un nombre de función [3] dado a PersonId
), y estas columnas deben definirse también como FK que apuntan, correspondientemente, a Club
y Person
.
Una estructura más adaptable
Al emplear esta configuración, también puede cumplir con la regla inicial que establece eso a Person can be a member of only one Club
, pero solo tiene que agregar una RESTRICCIÓN ÚNICA a la MemberId
columna, de modo que se pueda ingresar un cierto valor en no más de una ocasión. Entonces, como puede observar, esta estructura es mucho más adaptable que la que se muestra en la Figura 1 , ya que al soltar la RESTRICCIÓN ÚNICA (o ÍNDICE) abriría la funcionalidad antes mencionada de permitir que una persona se convierta en miembro de diferentes clubes en el Mismo tiempo.
Miembro y propietario como tipos de entidad separados
Como saben, el almacenamiento de varios hechos sobre el papel desempeñado por una persona como propietario de un club, además de su mera existencia en un atributo verdadero o falso, puede ser muy ventajoso. Por ejemplo, es posible que desee mantener la fecha de vigencia en la que una persona definida se convirtió en la propietaria de un club , por lo tanto, puede manejar esta situación introduciendo un tipo de entidad separada llamada ClubOwner
, como se presenta en la Figura 4 .
Una vez que construye una tabla basada en este nuevo tipo de entidad, puede agregar las columnas de ajuste que representan las características que entran en juego exclusivamente cuando a Person
es el Owner
de a Club
. Como se muestra, esta tabla contendría un PK compuesto por las columnas FK que hacen referencia Person.PersonId
y Club.ClubId
, de esta manera, cualquier combinación de ClubOwner.OwnerId
(o ClubOwner.PersonId
, si lo prefiere) y ClubOwner.ClubId
puede insertarse en una sola oportunidad.
Por supuesto, con esta configuración aún puede derivar en forma booleana si a Person
es el Owner
de un particular Club
con la ayuda de una consulta que devuelve un valor escalar que puede evaluarse como verdadero o falso .
Notas
1. La definición de integración para el modelado de información ( IDEF1X ) es una técnica de modelado de datos altamente recomendable que fue definida como un 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 (a) algunos de los documentos teóricos escritos por el autor del Modelo Relacional , es decir, el Dr. EF Codd ; en (b) la teoría Entidad-Relación , desarrollada por el Dr. PP Chen ; y también en (c) la Técnica de diseño de base de datos lógica , creada por Robert G. Brown . Vale la pena señalar que IDEF1X fueformalizado a través de la lógica de primer orden .
2. Una CLAVE ALTERNATIVA es un atributo (o una combinación de atributos) que contiene valores que identifican de manera única una ocurrencia de entidad pero que no se eligió como PK del tipo de entidad pertinente; cada tipo de entidad puede tener cero, una o más CLAVES ALTERNAS. En un modelo IDEF1X, se indican como "AK" más su número respectivo, por ejemplo, AK1, AK2, etc. Por lo general, se implementan en una estructura SQL DDL a través de una RESTRICCIÓN ÚNICA (o un ÍNDICE ÚNICO ).
3. Los nombres de roles son denotaciones (o alias) asignados a atributos FK para expresar el significado que tienen dentro del alcance de su entidad respectiva. Su uso es recomendado desde 1970 por el Dr. Codd en su documento seminal titulado "Un modelo relacional de datos para grandes bancos de datos compartidos" . Por su parte, IDEF1X (mantener la fidelidad respecto a las prácticas relacionales) también aboga por el nombramiento de roles.
clubId
de teléfono y dejo el club o la persona en nulo?