entre Desarrolladores

Recibe ayuda de expertos

Registrate y pregunta

Es gratis y fácil

Recibe respuestas

Respuestas, votos y comentarios

Vota y selecciona respuestas

Recibe puntos, vota y da la solución

Pregunta

1voto

Duda sobre diseño de base de datos: relacionar tabla "widgets" con otras tablas

Hola a todos. Tengo otra duda sobre diseño de base de datos sql.

En una aplicación web que estoy haciendo quiero desarrollar un par de tipos widgets sencillos:

  • Widget de texto plano con un título y un texto.
  • Widget de lista con un título y una serie de elementos de lista que no son otra cosa que texto plano, pero ordenados dentro de la lista.

Estos widgets se pueden crear en distintos tipos de secciones de la aplicación. Pueden tener widgets los profesores, los cursos, las páginas, categorías de cursos...

Sé que lo normal, para relacionar los widgets con cada sección, es tener una tabla relacional por cada sección. Me explico: una tabla relacional que relacione cursos con widgets, otra que relaciones profesores con widgets, otra que relacione páginas con widgets... Pero esa alternativa la veo rara, porque en realidad es una relación uno a muchos (Una sección puede tener muchos widgets, pero un mismo widget sólo puede pertenecer a una sección). Aparte supongo que tiene que haber otra manera más óptima de realizar estas relaciones. Veo muchas tablas que sirven para lo mismo.

En un principio tenía una tabla zonas_widgets a la que apuntaban tanto los cursos, profesores, páginas, como los widgets. Pero me dijeron que ahí sería difícil hacer los joins.

Bueno, una vez más, gracias por todo de antemano. Un saludo y buen fin de semana a todos :)


ANEXO 1

SECCIONES QUE CONTIENEN WIDGETS:
Cursos: id, nombre, descripcion, img, categoría...
Profesores: id, nombre, apellidos, descripcion, img, disciplina...
Páginas: id, nombre, descripción, img...

WIDGETS:
Tipo texto: título, texto.
Tipo lista: título, conjunto de elementos de texto ordenados.

*He obviado muchos campos, pero éstos son los básicos de cada uno. Aparte la app web es multiidioma, pero ese tema ya lo tengo solucionado. Espero que les sirvan de ayuda. Por cualquier otra cosa que falte diganmelo. Gracias :D


ANEXO 2

Les presento ya de paso cómo tengo planeadas las tablas actualmente, por si les es más fácil plantearme cambios a partir de ésto (si hiciese falta):

TABLA ZONAS_WIDGET:
    id (PK)

TABLA WIDGETS
    id
    titulo
    texto
    tipo ENUM('texto', 'lista')
    id_zona_widget (FK -> zonas_widgets)

TABLA ELEMENTOS_LISTA
    id
    texto
    id_widget (FK -> widgets)

TABLA CURSOS
    id
    nombre
    descripcion
    img
    ...
    ...
    id_zona_widget (FK -> zonas_widgets)

TABLA PROFESORES
    id
    nombre
    apellidos
    descripcion
    img
    ...
    ...
    id_zona_widget (FK -> zonas_widgets)

TABLA PAGINAS
    id
    nombre
    descripcion
    img
    ...
    ...
    id_zona_widget (FK -> zonas_widgets)

Cabe destacar que una misma zona widget sólo forma parte de un único curso, profesor, página... (la zona widget es exclusiva de su curso, profesor, página... y ésta no se comparte con ninguna otra. Es decir: multiplicidad 1:1). Sin embarlo varios widgets pueden hacer referencia a la misma zona widget (multiplicidad 1:N).

0voto

Leonardo-Tadei comentado

Hola @Joseda85,

por favor, editá la pregunta y agregá los campos que tendría cada Widget y los campos principales que tienen las tablas de profesores, cursos y secciones, así nos podemos dar una idea de la estructura.

Tu planteo se entiende, pero la solución puede variar mucho dependiendo de los datos.

Recordá que la Normalización no es una cuestión de opniones: se aplica la norma solbre la totalidad de los datos a almacenar y de ahí surgen las tablas y sus relaciones.

Saludos cordiales!

0voto

Joseda85 comentado

Acabo de añadir esa info. Aparte también he puesto como tengo planteadas las tablas actualmente. Lo que veo raro es que habiendo una multiplicidad 1:1 entre las distintas secciones y las zonas widgets, éstas últimas estén en otra tabla aparte, ya que cuando la multiplicidad es 1:! se suele poner todo bajo la misma tabla. Pero es que no encuentro otra solución. Gracias por vuestra ayuda.

1 Respuesta

2votos

Leonardo-Tadei Puntos227320

Hola @Joseda85,

gracias por el detalle en la pregunta. Hay una cuestión que no entiendo: para qué querés guardar los widgets?
Si no entiendo mal, el contenido podría salir directamente de una query y lo que tendrías que guardar es solamene cuales son y de qué tipo.

Estoy pensando en algo como:

Widget_tipo
----------------
id
tipo (texto o lista)

Widget_contenido
------------------------
id
contenido (curso, profesor, etc)

Widget
----------
id
id_tipo
id_contenido
id_referencia (el curso, profesor, etc)

De esta forma no estás violando la Normalización y tenés todos los datos sin repeticiones para ejecutar una query que depende del tipo y del contenido y que recibe como parámetro el id_referencia.

Con estos datos ejecutás una query que genere el Widget y te ahorrás tener los datos almacenados por 2da vez y actualizarlos con trigger cada vez que hay un cambio.

Saludos cordiales!

PD: puede ser que haya entendido todo mal y que las tablas que proponés estén justificadas por algún otro motivo.
PPD: no me gustan los ENUM y por eso no los uso. Usarlos implica que ante un nuevo tipo de Widget tenés que editar la estructura de la DB, y la idea es que nuevos tipos de cosas existentes no impliquen modificar la estructura.

0voto

Joseda85 comentado

No sé si he entendido bien. Te refieres a que dependiendo del id_contenido, el id_referencia sería el id de un curso, un profesor o una página (a modo de clave foránea, pero sin establecer esta relación en el código para crear la base de datos). Lo primero que se me ocurrió fue algo así al plantearme el problema, pero pensaba que no era buena práctica ya que en una base de datos relacional no se puede establecer una clave foránea que dependiendo del valor de una columna, la clave apunte a una tabla u otra. Por eso he montado toda la parafernalia de tablas que he escrito arriba jeje. Un saludo :)

1voto

Leonardo-Tadei comentado

Entiendo lo que decís y tenés razón en tu planteo; pero el enfoque que te propongo no es guardar los widget, sino la configuraqción del widget, para que luego un store procedure lo genere usando esos valores como parámetro.
En este caso, dado que

id_referencia

pasa a ser un valor de la configuración, no tiene por qué ser una clave foránea, ya que el propio store procedure puede validar la integridad o borrar el widget si la referencia desaparece.

Fijate que en tu propuesta tampoco la FK te garantiza integridad, ya que es contra > Zona_Widget y no contra la entidad real, que también queda fuera del esquema.

Saludos cordiales!

PD: para hacer esto manteniendo integridad referencial, tenés que crear una tabla de widgets para cada sección, y discriminar solamente su tipo... igual, gran parte del truco mental es pensar primero cómo vas a generar los widget, porque este problema tiene más información oculta de lo que parece.

0voto

Joseda85 comentado

Ah bien, no lo entendí antes. Ahora sí. Es interesante ese planteamiento. Siempre que hago una pregunta por aquí acabo aprendiendo más de lo que me esperaba, jeje. Muchas gracias por todo.
Un saludo :)

Por favor, accede o regístrate para responder a esta pregunta.

Otras Preguntas y Respuestas


...

Bienvenido a entre Desarrolladores, donde puedes realizar preguntas y recibir respuestas de otros miembros de la comunidad.

Conecta