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

Relacion ternaria -> base de datos

Estas en el tema de Relacion ternaria -> base de datos en el foro de Bases de Datos General en Foros del Web. Buenas, Tengo una duda acerca de como pasar de una relacion ternaria (en el modelo ER) a un conjunto de tablas. Haber Yo tengo 3 ...
  #1 (permalink)  
Antiguo 23/09/2010, 12:16
 
Fecha de Ingreso: agosto-2009
Mensajes: 15
Antigüedad: 14 años, 7 meses
Puntos: 0
Relacion ternaria -> base de datos

Buenas,

Tengo una duda acerca de como pasar de una relacion ternaria (en el modelo ER) a un conjunto de tablas. Haber Yo tengo 3 entidades:

Turno (idturno,dia,inicio,fin)
Usuario (idusuario,usuario,contrasena)
Red (idred)

La relación es que un usuario puede reservar una red durante un turno con la restricción de que solo puede realizar una unica reserva. Entonces yo he hecho lo siguiente:

Código SQL:
Ver original
  1. CREATE TABLE usuario
  2. (
  3. idusuario   tinyint UNSIGNED NOT NULL UNIQUE AUTO_INCREMENT,
  4. usuario     VARCHAR(10) NOT NULL UNIQUE,
  5. contrasena  VARCHAR(10) NOT NULL,
  6. administrador   BOOLEAN NOT NULL DEFAULT 0,
  7.  
  8. PRIMARY KEY (idusuario),
  9. UNIQUE INDEX (usuario,contrasena)
  10. )ENGINE=InnoDB;
  11.  
  12. CREATE TABLE turno
  13. (
  14. idturno     tinyint UNSIGNED NOT NULL UNIQUE AUTO_INCREMENT,
  15. dia     tinyint UNSIGNED NOT NULL,
  16. inicio      TIME NOT NULL,
  17. fin         TIME NOT NULL,
  18.  
  19. PRIMARY KEY (idturno),
  20. UNIQUE INDEX (dia,inicio)
  21. )ENGINE=InnoDB;
  22.  
  23. CREATE TABLE red
  24. (
  25. idred       tinyint UNSIGNED NOT NULL UNIQUE,
  26.  
  27. PRIMARY KEY (idred)
  28. )ENGINE=InnoDB;
  29. INSERT INTO red VALUES (1),(2),(3);
  30.  
  31. CREATE TABLE reserva
  32. (
  33. idusuario   tinyint UNSIGNED NOT NULL UNIQUE,
  34. idturno     tinyint UNSIGNED NOT NULL,
  35. idred       tinyint UNSIGNED NOT NULL,
  36.  
  37.  
  38. PRIMARY KEY (idusuario),
  39. FOREIGN KEY (idusuario) REFERENCES usuario (idusuario) ON DELETE CASCADE ON UPDATE CASCADE,
  40. FOREIGN KEY (idred) REFERENCES red (idred) ON DELETE CASCADE ON UPDATE CASCADE,
  41. FOREIGN KEY (idturno) REFERENCES turno (idturno) ON DELETE CASCADE ON UPDATE CASCADE
  42. )ENGINE=InnoDB;


Mis dudas son:
-¿Es la forma correcta de hacerlo?
-¿Estaria en 3FN?
-La entidad de red no tiene mas atributos que el propio identificador ¿esta mál crear una tabla para ella? (No se me ocurre otra forma de hacerlo)
-De esta forma la primary key coincide con la foreign key: ¿Hay que definir ambas ose puede especificar la referencia en la primary key? (MySQL tiende a crearme indices con todo y acabo teniendolos repetidos)

Y ya que estoy aprovecho y pregunto una cosilla mas por si alguien sabe respondermelas:
-¿Con que cardinalidad se representaria cada una de las entidades en el diagrama ER? (Yo tengo puesto: turno-1, red-1, usuario-n)


Gracias de antemno ^^
  #2 (permalink)  
Antiguo 26/09/2010, 07:38
Avatar de mayid
Colaborador
 
Fecha de Ingreso: marzo-2009
Ubicación: BsAs
Mensajes: 4.014
Antigüedad: 15 años
Puntos: 101
Respuesta: Relacion ternaria -> base de datos

Yo no veo bien que tengas una tabla Red con un solo campo:

Red (idred)

Te paso un tutorial sobre normalización, para que leas sobre atomizar. Creo que también ahí se habla sobre lo opuesto:
http://www.conclase.net/mysql/curso/?cap=004#

El tema es si absorver la tabla red como un atributo del turno...
  #3 (permalink)  
Antiguo 26/09/2010, 08:20
 
Fecha de Ingreso: agosto-2009
Mensajes: 15
Antigüedad: 14 años, 7 meses
Puntos: 0
Respuesta: Relacion ternaria -> base de datos

En su momento me plantee el crear un dominio con idred, pero MySQL no permite crear dominios ^^U,

Haber yo podria por un lado añadir la idred como atributos a la relacion reserva y de tal manera que quedara:

Código SQL:
Ver original
  1. CREATE TABLE reserva
  2. (
  3. idusuario   tinyint UNSIGNED NOT NULL UNIQUE,
  4. idturno     tinyint UNSIGNED NOT NULL,
  5. idred       tinyint UNSIGNED NOT NULL,
  6. PRIMARY KEY (idusuario),
  7. FOREIGN KEY (idusuario) REFERENCES usuario (idusuario) ON DELETE CASCADE ON UPDATE CASCADE,
  8. FOREIGN KEY (idturno) REFERENCES turno (idturno) ON DELETE CASCADE ON UPDATE CASCADE
  9. UNIQUE INDEX (idturno,idred)
  10. )ENGINE=InnoDB;

La cuestión es que tengo otra relación (que se me olvido mencionar) entre usuario y red que es activo, es decir una tabla tal que así:

Código SQL:
Ver original
  1. CREATE TABLE activo
  2. (
  3. idusuario   tinyint UNSIGNED NOT NULL UNIQUE,
  4. idred   tinyint UNSIGNED NOT NULL UNIQUE,
  5. inicio      datetime NOT NULL,
  6.  
  7. PRIMARY KEY (idusuario,idred),
  8. FOREIGN KEY (idusuario) REFERENCES usuario (idusuario) ON DELETE CASCADE ON UPDATE CASCADE,
  9. FOREIGN KEY (idred) REFERENCES red (idred) ON DELETE CASCADE ON UPDATE CASCADE
  10. )ENGINE=InnoDB;

donde almaceno (y puedo comprobar mas tarde) si una red se encuentra acutalmente en uso, y en caso afimativo, que usuario esta en ella y desde cuando.

En esta tabla podria hacer lo mismo y pasar idred como atributo de la relación. La cuestión es que la cosa no me queda clara del todo ya que al eliminar red como entidad esta relación queda un poco descolgada (no se si me explico). Ademas idred aquí y en la otra tabla referencian lo mismo, pero sin una tabla red no tengo manera de relacionarlas ¿no?

Quizas combinar las tablas red y activo sea otra opción, pero de hacer eso la tabla resultante ¿seguiria estando en 3FN?, ademas como la red no esta siempre en uso el atributo datetime no siempre tiene sentido en la tabla.

Nose, ¿que hariais vosotros?

P.D.: El interes en tener la base de datos normalizada no es cosa mia, sino que todo esto forma parte de un PFC y el tutor asi lo ha querido, entoces o estan totalmente normalizadas o encuentro una explicació bonita y convicenten que poder plantar en la memoria ^^U

Etiquetas: relacion
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 07:42.