Foros del Web » Programación para mayores de 30 ;) » Bases de Datos General » Mysql »

Podés darme vuestra opinión sobre este diseño?

Estas en el tema de Podés darme vuestra opinión sobre este diseño? en el foro de Mysql en Foros del Web. Buenos días, Me gustaría contar con vuestra experiencia en diseños de bbdd Estoy diseñando un bbdd para la siguiente función y no se si voy ...
  #1 (permalink)  
Antiguo 11/11/2009, 00:49
Avatar de neodani  
Fecha de Ingreso: marzo-2007
Mensajes: 1.811
Antigüedad: 17 años, 1 mes
Puntos: 20
Podés darme vuestra opinión sobre este diseño?

Buenos días,

Me gustaría contar con vuestra experiencia en diseños de bbdd
Estoy diseñando un bbdd para la siguiente función y no se si voy bien encaminado.
Tengo 3 tablas (inscripciones, seminarios, pagos_tpv) y una que relaciona las tres inscripcion_seminarios_pagos

Idea: El usuario rellena un formulario de inscripción donde se puede apuntar a varios seminarios a la vez, a través de ese formulario se realiza un pago, los datos del pago los recibe otro script.

¿Creéis que el diseño es correcto? tengo mis dudas con la tabla inscripcion_seminarios_pagos

Muchísimas gracias de antemano!

Diseño:

Código:
-- Datos de las personas inscritas --
CREATE TABLE inscripciones (
	idInscripcion int NOT NULL auto_increment,
	nombre varchar(40) NOT NULL,
	apellidos varchar(40) NOT NULL,
	fnacimiento date,
	dni varchar(20),
	direccion varchar(90) NOT NULL,
	poblacion varchar(40) NOT NULL,
	cpostal varchar(10) NOT NULL,
	provincia varchar(20) NOT NULL,
	tel_particular varchar(10) NOT NULL,
	mov_particular varchar(10) NOT NULL,
	ema_particular varchar(50) NOT NULL,
	tel_profesional varchar(10),
	mov_profesional varchar(10),
	ema_profesional varchar(50),
	fax varchar(15),
	nos_conocio varchar(150) NOT NULL,
	pref_tel_particular char(1) default '0',
	pref_tel_profesional char(1) default '0',
	pref_ema_particular char(1) default '0',
	pref_ema_profesional char(1) default '0',
	idioma varchar(2) default 'es',
	PRIMARY KEY(idInscripcion)
);

-- Tabla relacion inscripciones, seminarios y pagos--
CREATE TABLE inscripcion_seminarios_pagos (
	idInscripcion int NOT NULL,
	idSeminario int NOT NULL,
	idPago int NOT NULL,
	PRIMARY KEY(idInscripcion,idSeminario,idPago)
);

-- Diferentes tipos de seminarios --
CREATE TABLE seminarios (
	idSeminario int NOT NULL auto_increment,
	nombre varchar(30) NOT NULL,
	fecha timestamp,
	PRIMARY KEY(idSeminario)
);

-- Pagos del TPV --
CREATE TABLE pagos_tpv (
	idPago int NOT NULL auto_increment,
	Ds_Date date NOT NULL,
	Ds_Hour time NOT NULL,
	Ds_SecurePayment TINYINT NOT NULL,
	Ds_Card_Country SMALLINT,
	Ds_Amount decimal(7,2) NOT NULL,
	Ds_Currency SMALLINT NOT NULL,
	Ds_Order varchar(12) NOT NULL,
	Ds_MerchantCode int(9) NOT NULL,
	Ds_Terminal SMALLINT NOT NULL,
	Ds_Signature varchar(40) NOT NULL,
	Ds_Response SMALLINT,
	Ds_MerchantData TEXT,
	Ds_TransactionType varchar(1) NOT NULL,
	Ds_ConsumerLanguage SMALLINT NOT NULL,
	Ds_ErrorCode varchar(7),
	Ds_AuthorisationCode varchar(6),
	PRIMARY KEY(idPago)
);
  #2 (permalink)  
Antiguo 11/11/2009, 03:53
Colaborador
 
Fecha de Ingreso: marzo-2008
Ubicación: Sabadell
Mensajes: 4.897
Antigüedad: 16 años, 1 mes
Puntos: 574
Respuesta: Podés darme vuestra opinión sobre este diseño?

És una relacion ternaria (tres tablas) que se soluciona con una cuarta tabla donde se guardan los identificadores... en principio correcto.

Quizas se podria optimizar creando una tabla usuarios donde se guardarian los datos de los usuarios, para futuras inscripciones eliminando repeticiones, y luego armando la relacion ternaria entre usuarios/Seminarios/Pagos y en la tabla que las relaciona habira que agregar los datos de cada inscripción, basicamente la fecha, así como los identificadores....

Es una reflexión al vuelo!!!

Quim

Última edición por quimfv; 11/11/2009 a las 03:58
  #3 (permalink)  
Antiguo 11/11/2009, 05:10
Avatar de gnzsoloyo
Moderador criollo
 
Fecha de Ingreso: noviembre-2007
Ubicación: Actualmente en Buenos Aires (el enemigo ancestral)
Mensajes: 23.324
Antigüedad: 16 años, 4 meses
Puntos: 2658
Respuesta: Podés darme vuestra opinión sobre este diseño?

Estoy de acuerdo con quimfv, el modelo es en principio correcto. Posiblemewnte esta tabla sea bastante más optimizable:
Código sql:
Ver original
  1. CREATE TABLE inscripciones (
  2.     idInscripcion INT NOT NULL AUTO_INCREMENT,
  3.     nombre VARCHAR(40) NOT NULL,
  4.     apellidos VARCHAR(40) NOT NULL,
  5.     fnacimiento DATE,
  6.     dni VARCHAR(20),
  7.     direccion VARCHAR(90) NOT NULL,
  8.     poblacion VARCHAR(40) NOT NULL,
  9.     cpostal VARCHAR(10) NOT NULL,
  10.     provincia VARCHAR(20) NOT NULL,
  11.     tel_particular VARCHAR(10) NOT NULL,
  12.     mov_particular VARCHAR(10) NOT NULL,
  13.     ema_particular VARCHAR(50) NOT NULL,
  14.     tel_profesional VARCHAR(10),
  15.     mov_profesional VARCHAR(10),
  16.     ema_profesional VARCHAR(50),
  17.     fax VARCHAR(15),
  18.     nos_conocio VARCHAR(150) NOT NULL,
  19.     pref_tel_particular CHAR(1) DEFAULT '0',
  20.     pref_tel_profesional CHAR(1) DEFAULT '0',
  21.     pref_ema_particular CHAR(1) DEFAULT '0',
  22.     pref_ema_profesional CHAR(1) DEFAULT '0',
  23.     idioma VARCHAR(2) DEFAULT 'es',
  24.     PRIMARY KEY(idInscripcion));
Sobre la base de la normalización, hay al menos dos tablas desprendiéndose de ella, como es el caso de los teléfonos, que en mi opinión deberían ir en otra tabla, unificando los profesionales, particulares y comerciales en una sola con un campo para distingir tipo. Además, poner los prefijos en otro campo no resulta funcional, ya que conceptualmente es parte del mismo número y no se debe hacer una atomización tan detallada.
__________________
¿A quién le enseñan sus aciertos?, si yo aprendo de mis errores constantemente...
"El problema es la interfase silla-teclado." (Gillermo Luque)
  #4 (permalink)  
Antiguo 11/11/2009, 12:21
Avatar de neodani  
Fecha de Ingreso: marzo-2007
Mensajes: 1.811
Antigüedad: 17 años, 1 mes
Puntos: 20
Respuesta: Podés darme vuestra opinión sobre este diseño?

Muchas gracias a ambos, os respondo a continuación

Cita:
Iniciado por quimfv Ver Mensaje
Quizas se podria optimizar creando una tabla usuarios donde se guardarian los datos de los usuarios, para futuras inscripciones eliminando repeticiones
Esto de la tabla usuario lo pensé, sería lo ideal, que el usuario se registrase y si se quiere apuntar a otro curso no tuviese que rellenar sus datos personales...

Evitando no tener que pedirle los datos cada vez que quisiese apuntarse a un curso, lo estudiaré, pero eso implica que luego deben poder modificar sus datos personales, direccion, telefono etc...


Y sobre lo que comentas gnzsoloyo, coincido que se podría optimizar la tabla inscripciones dividiéndola en usuarios

Cita:
Iniciado por gnzsoloyo Ver Mensaje
Estoy de acuerdo con quimfv, el modelo es en principio correcto. Posiblemewnte esta tabla sea bastante más optimizable:
Pero no acabo de entender el tema que mencionas de los telefonos.

Cita:
Iniciado por gnzsoloyo Ver Mensaje
Sobre la base de la normalización, hay al menos dos tablas desprendiéndose de ella, como es el caso de los teléfonos, que en mi opinión deberían ir en otra tabla, unificando los profesionales, particulares y comerciales en una sola con un campo para distingir tipo.
Te refieres algo así? Pero como pones si los datos particulares o profesionales?

Código sql:
Ver original
  1. CREATE TABLE contacto (
  2. idcontacto  INT NOT NULL,
  3. telefono VARCHAR(10),
  4. movil VARCHAR(10),
  5. email VARCHAR(10),
  6. }

Esto no lo entendí, prefijos? no hay prefijos, los datos
pref_tel_particular char(1) DEFAULT '0',
pref_tel_profesional char(1) DEFAULT '0',
pref_ema_particular char(1) DEFAULT '0',
pref_ema_profesional char(1) DEFAULT '0',

Son para saber porqué método desean ser contactados

Cita:
Iniciado por gnzsoloyo Ver Mensaje
Además, poner los prefijos en otro campo no resulta funcional, ya que conceptualmente es parte del mismo número y no se debe hacer una atomización tan detallada.
Muchas gracias
  #5 (permalink)  
Antiguo 11/11/2009, 12:38
Avatar de gnzsoloyo
Moderador criollo
 
Fecha de Ingreso: noviembre-2007
Ubicación: Actualmente en Buenos Aires (el enemigo ancestral)
Mensajes: 23.324
Antigüedad: 16 años, 4 meses
Puntos: 2658
Respuesta: Podés darme vuestra opinión sobre este diseño?

Bien. Si esos campos son preferencias de contacto, eso puede resolverse con un campo ENUM que tenga cuatro valores posibles, ya que en definitiva solamente necesitas un dato: QUé medio usar apra el contacto. Ese valor bien puede ser uncódigo numérico en que se asigne:
Cita:
1: Teléfono particular.
2: Telefono profesional.
3: e-Mail particular.
4: e-Mail profesional.
Respecto a los teléfonos, la cosa es parecida:
Código sql:
Ver original
  1. CREATE TABLE contacto_Tel(
  2.   idcontacto  INT NOT NULL,
  3.   telefono VARCHAR(14),
  4.   tipo_tel TINYINT NOT NULL,
  5.   PRIMARY KEY(idcontacto, telefono),
  6.   FOREIGN KEY idcontacto REFERENCES contacto(idcontacto)  
  7.   )
Los e-Mails:
Código sql:
Ver original
  1. CREATE TABLE contacto_eMail(
  2.   idcontacto  INT NOT NULL,
  3.   eMail VARCHAR(100),
  4.   tipo_email TINYINT NOT NULL,
  5.   PRIMARY KEY(idcontacto, eMail),
  6.   FOREIGN KEY idcontacto REFERENCES contacto(idcontacto)  
  7.   );

Esa sería más o menos la idea.
Con dos tablas relacionadas de esa forma, podrías tener uno o muchos teléfonos o e-Mails de la misma persona.
__________________
¿A quién le enseñan sus aciertos?, si yo aprendo de mis errores constantemente...
"El problema es la interfase silla-teclado." (Gillermo Luque)
  #6 (permalink)  
Antiguo 11/11/2009, 15:21
Avatar de neodani  
Fecha de Ingreso: marzo-2007
Mensajes: 1.811
Antigüedad: 17 años, 1 mes
Puntos: 20
Respuesta: Podés darme vuestra opinión sobre este diseño?

Muchas gracias por responder gnzsoloyo

Los campos ENUM siempre los he visto como una lista de opciones de la cual puedes escoger solo una. El usuario puede escoger, 1, 2 incluso si quiere las 4 opciones, funcionaría en ese caso el ENUM, o te restringe a una sola opción?¿

Cita:
Iniciado por gnzsoloyo Ver Mensaje
Bien. Si esos campos son preferencias de contacto, eso puede resolverse con un campo ENUM que tenga cuatro valores posibles, ya que en definitiva solamente necesitas un dato: QUé medio usar apra el contacto. Ese valor bien puede ser uncódigo numérico en que se asigne:
Sobre las dos tablas de telefono, un par de dudas...

El idcontacto de cada tabla es una clave independiente no?
Cuando haces el REFERENCES contacto(idcontacto) que es "contacto"??

No deberían estar relacionada con la clave primaria de la tabla inscripciones, para saber que ese correo o ese telefono pertenece a esa persona?

Respecto a los teléfonos, la cosa es parecida:
Código sql:
Ver original
  1. CREATE TABLE contacto_Tel(
  2.   idcontacto  INT NOT NULL,
  3.   telefono VARCHAR(14),
  4.   tipo_tel TINYINT NOT NULL,
  5.   PRIMARY KEY(idcontacto, telefono),
  6.   FOREIGN KEY idcontacto REFERENCES contacto(idcontacto)  
  7.   )
Los e-Mails:
Código sql:
Ver original
  1. CREATE TABLE contacto_eMail(
  2.   idcontacto  INT NOT NULL,
  3.   eMail VARCHAR(100),
  4.   tipo_email TINYINT NOT NULL,
  5.   PRIMARY KEY(idcontacto, eMail),
  6.   FOREIGN KEY idcontacto REFERENCES contacto(idcontacto)  
  7.   );

Esa sería más o menos la idea.
Con dos tablas relacionadas de esa forma, podrías tener uno o muchos teléfonos o e-Mails de la misma persona.[/QUOTE]


Muchas gracias de nuevo
  #7 (permalink)  
Antiguo 11/11/2009, 16:40
Avatar de gnzsoloyo
Moderador criollo
 
Fecha de Ingreso: noviembre-2007
Ubicación: Actualmente en Buenos Aires (el enemigo ancestral)
Mensajes: 23.324
Antigüedad: 16 años, 4 meses
Puntos: 2658
Respuesta: Podés darme vuestra opinión sobre este diseño?

Bueno, la idea es que la PK de cada una de esas tablas esté compuesta en cada caso por la PK de la persona, más un campo que pueda identificarlos univocamente. En el caso de teléfonos sería la PK de la persona + telefono, porque jamás la misma persona podría aparecer con el mismo teléfono dos veces; y lo mismo en el caso del e-Mail.
Al mismo tiempo, la PK de la persona es una FK que debe referenciar a la tabla donde se guardan los datos de la persona.

Te comento que por cuestiones de mnemotécnica, siempre es conveniente que el nombre de las tablas tenga una consistencia semántica. Así, por ejemplo, una tabla que guarde la INSCRIPCION no debería ser una tabla donde se guarden datos de una PERSONA, un ALUMNO o un PROFESOR. Esas serían otras tablas; Inscripción debería ser la que contiene el ID de la persona que se inscribe y los detalles que hacen al acto de inscripción, no los que identifican a la persona.
El respeto a una sintaxis consistente ayuda muchas veces a ubicarse rápidamente cuál es la tabla que uno necesita, sin tener que para ello mirar los nombres de sus campos...

Volviendo al tema: Por definición de bases de datos, un campo sólo puede tener un valor en un instante dado. En ese contexto, un campo ENUM sirve para predefinir un conjunto de valores que el campo puede tomar (restricción de dominio), pero solamente puede tener uno a la vez. Cualquier circunstancia en la que una misma instancia de entidad (digamos, una persona) tenga un atributo que puede tomar simultáneamente más de un valor, implica necesariamente la existencia de una relación nueva en donde cada uno de esos valores está representado por un registro distinto de la nueva tabla. Jamás puede darse que existan atributos multivaluados (más de un valor al mismo tiempo). Eso es parte de la 1FN.
Mi sugerencia de usar n campo ENUM es porque tienes un conjunto muy acotado de opciones invariables. Si estas opciones pudiesen variar en el tiempo, entonces ese campo sería la FK de una tabla que conserve la descripción del tipo.
Cita:
Cuando haces el REFERENCES contacto(idcontacto) que es "contacto"??
Es un error de escritura. Quería referirme a la tabla donde está la persona.
__________________
¿A quién le enseñan sus aciertos?, si yo aprendo de mis errores constantemente...
"El problema es la interfase silla-teclado." (Gillermo Luque)
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 16:22.