Asesoramiento en un diseño básico, diseño de base de datos por primera vez.

8

Estoy tomando un curso para convertirme en desarrollador de Java.

El curso implica el uso de bases de datos, pero lamentablemente nunca diseñamos ninguno.

La mayoría de las veces obtenemos bases de datos prefabricadas y tenemos que implementar código para insertar, actualizar, leer o eliminar datos.

Pero cuando llegue mi prueba final, es probable que esté haciendo algo que involucre una base de datos y, por lo tanto, quiero intentar diseñar algunas más pequeñas para acostumbrarme a un diseño, ya que noté que un buen diseño de base de datos hace una gran diferencia cuando escribiendo el código para trabajar con él.

Espero que este tipo de preguntas estén permitidas aquí y que no sean demasiado amplias.


Este es un pequeño diseño que hice para algo simple como clubsy memberscon addressesy phonenumbers.

  • Habrá múltiples clubes.
  • Cada club tendrá múltiples miembros (obvio)
  • Un miembro no puede ser parte de varios clubes
  • Un miembro puede tener múltiples números de teléfono y direcciones de correo electrónico
  • Un miembro solo puede tener una dirección
  • Una dirección puede pertenecer a diferentes miembros (parejas o hermanos)

Mis mayores confusiones:

  • Si deseo agregar una columna Clubque describa al propietario, que también será miembro, ¿cuál es el mejor enfoque sin tener el mismo miembro en la lista dos veces?

  • ¿Debo poner todas mis tablas en el incremento automático de una identificación o sería una mala idea? (beneficios / desventajas?)

  • 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? (ver imagen 2)

  • Y mi pregunta probablemente más novata en absoluto ... ¿Pongo las claves foráneas de phonenumbery emailen sus respectivas tablas vinculadas a una ID_persona o debo colocar el número de teléfono y los ID de correo electrónico en la tabla de persona?

(Mis disculpas por que el idioma en las imágenes no sea inglés, espero que esto no sea un gran problema)

Diseño

Llaves extranjeras

Vahx
fuente

Respuestas:

11

Respuestas a sus preguntas individuales.

Si deseo agregar una columna Clubque 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 Persontabla, 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 ido 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 DDLdeclaraciones 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_numbery emailen sus respectivas tablas vinculadas a una person_ido debo poner phone_numbery email idsen 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 Persony PhoneNumber, por lo tanto, sugiero la creación de una tabla asociativa nombrada PersonPhoneNumberpara 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 Persondesde la EmailAddresstabla, y esta tabla también debe tener un PK compuesto, que estaría compuesto por las columnas PersonIdy Address. De esta manera, puede asegurarse de que la misma combinación de EmailAddress.PersonIdy EmailAddress.Addressse pueda insertar solo una vez.

Si también desea asegurarse de que un determinado EmailAddres.Addresspuede 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 .

Fig. 1. Modelo de datos de clubes y socios: primeras especificaciones

Teniendo en cuenta el modelo referido, debe seguir los siguientes pasos:

  1. Crea una tabla llamada PersonAddressarreglar una relación entre Persony Address. Establezca las columnas PersonIdy AddressIdcomo el PK compuesto de esta tabla.

  2. Configure una RESTRICCIÓN ÚNICA para la PersonAddress.PersonIdcolumna 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.PersonIdha convertido en una CLAVE ALTERNATIVA [2] .

  3. Si el valor de AddressIdun PersonAddressintento 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 PersonIdque se ha registrado AddressIdtambién está registrado como el Marriage.WifeIdsi el PersonIdes un hombre (dato derivado de la Person.GenreCode) o (b) que PersonIdes el Marriage.HusbandIdcuando el PersonIdes 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.

  4. Si no se cumplieron las condiciones anteriores, todavía existe la posibilidad de que una PersonAddressinserción intente tener éxito. Debe comprobar que el PersonIdvalor que está involucrado en dicho intento de inserción comparte al menos uno Progeny.ParentIdcon el PersonIdque ya ha registrado el PersonAddress.AddressId. Si se cumple esta condición, significa que se almacenan como Siblingsen 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 DMLoperaciones 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 Persony Clubcomo 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 Peopley Clubsse definirían a través Partydel supertipo. Consulte la Figura 2 para ver una descripción de esta sugerencia.

Fig. 2. Modelo de datos de clubes y socios: segundas especificaciones

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 Partyy Addressque se expresa a través de la PartyAddressentidad.

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 PartyPhoneNumberentidad que describe la asociación muchos-a-muchos que se lleva a efecto entre las Partyy PhoneNumberentidad 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, Partysuministra 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 ClubMemberque estaría actuando como otra relación de muchos a muchos, esta vez, naturalmente , interconectados Persony 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 IsClubOwnercolumna 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 ClubIdy MemberId(un nombre de función [3] dado a PersonId), y estas columnas deben definirse también como FK que apuntan, correspondientemente, a Cluby Person.

Fig. 3. Modelo de datos de clubes y miembros: persona como miembro de varios clubes

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 MemberIdcolumna, 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 .

Fig. 4. Modelo de datos de clubes y socios: miembro y propietario como tipos de entidad separados

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 Persones el Ownerde a Club. Como se muestra, esta tabla contendría un PK compuesto por las columnas FK que hacen referencia Person.PersonIdy Club.ClubId, de esta manera, cualquier combinación de ClubOwner.OwnerId(o ClubOwner.PersonId, si lo prefiere) y ClubOwner.ClubIdpuede insertarse en una sola oportunidad.

Por supuesto, con esta configuración aún puede derivar en forma booleana si a Persones el Ownerde un particular Clubcon 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.

MDCCL
fuente
2
  1. Si un propietario siempre es miembro de su club. Agregue ownerId a la tabla del club y coloque el personId allí del miembro que es el propietario.
  2. El aumento automático de una identificación es bueno. Puedes agregar otro campo 'código', allí pones el código de miembro en la tarjeta del club allí.
  3. Debería estar automáticamente bien (creo)
  4. Ponga personId en los números de teléfono y la tabla de correo electrónico.

... ¿No puedes ser miembro de varios clubes? Si puede, cree una tabla ClubMember con clubId y personId. De esa manera puedes conectar a una persona a varios clubes.

aldwinaldwin
fuente
1
¿Qué sucede si quiero que mi club tenga un número telefónico también? ¿también pongo el número clubIdde teléfono y dejo el club o la persona en nulo?
Vahx
No 'sobre-separar todos los objetos (normalización de datos). Simplemente ponga 1 número de teléfono en la mesa del club. La normalización es buena, pero demasiada normalización puede causar problemas.
aldwinaldwin
1
pero supongamos que quiero hacer esto? Tomaré la dirección como ejemplo, los miembros tienen una dirección pero los clubes también necesitarán una dirección
Vahx
1
Cree un registro de dirección y ponga el addressId en el club. Debido a que un club tiene 1 dirección, un miembro tiene 1 dirección. Para los números de teléfono, debe poner personId en el registro de número de teléfono para tener 1 a muchos. ..... Podría hacer una tabla personPhoneNumber (personId, phonenumberId) + table clubPhoneNumber (clubId, phonenumberId) lo que la convierte en una relación de muchos, muchos, entonces.
aldwinaldwin