Código sql:
Ver originalCREATE TABLE `libro` (
`cod_libro` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
`nom_libro` VARCHAR(100) NOT NULL,
`tema_libro` VARCHAR(100) NOT NULL,
`desc_libro` VARCHAR(400) DEFAULT NULL,
`año_libro` SMALLINT UNSIGNED DEFAULT NULL,
`num_libro` VARCHAR(4) NOT NULL,
`cod_autor` INT(10) UNSIGNED NOT NULL,
`cod_editorial` INT(10) UNSIGNED NOT NULL,
PRIMARY KEY (`cod_libro`),
KEY `FK_cod_autor` (`cod_autor`),
KEY `FK_cod_editorial` (`cod_editorial`),
CONSTRAINT `FK_cod_autor` FOREIGN KEY (`cod_libro`) REFERENCES `libro` (`cod_libro`) ON DELETE CASCADE ON UPDATE CASCADE,
CONSTRAINT `FK_cod_editorial` FOREIGN KEY (`cod_editorial`) REFERENCES `editorial` (`cod_editorial`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
En términos generales, la tabla esta bien definida. El problema está en el modelado lógico: No puedes establecer una relación de tipo N:1 entre Libro y Autor, porque un libro
puede tener uno o más de un autor, y cada autor
puede tener a su vez uno o más libros. Es una relación N:N, con lo que se debe crear una tabla que la regule y que contenga ambas claves, digamos LIBRO_AUTOR.
Una nota que te puedo hacer es que hay muchos campos con los tipos mal definidos, como por ejemplo, las fechas.
Las fechas las estás definiendo como VARCHAR(20), lo cual no sólo es un desperdicio de espacio, sino que además te dará problemas a la hora de las búsquedas por año, meses o días, ya que tendrás que usar funciones de conversión entre caracteres y fecha. Esto no hace más que impactar sobre la performance, por más que no se note con tablas de pocos registros.
Veamos el caso:
Código sql:
Ver original--
-- Definition of table `presta_libro`
--
DROP TABLE IF EXISTS `presta_libro`;
CREATE TABLE `presta_libro` (
`fecha_presta` VARCHAR(20) NOT NULL,
`fecha_devo` VARCHAR(20) DEFAULT NULL,
`cod_libro` INT(10) UNSIGNED NOT NULL,
`ci_usuario` INT(10) UNSIGNED NOT NULL,
KEY `FK_cod_libro` (`cod_libro`),
KEY `FK_cod_usuario` USING BTREE (`ci_usuario`),
CONSTRAINT `FK_ci_usuario` FOREIGN KEY (`ci_usuario`) REFERENCES `usuario` (`ci_usuario`) ON DELETE CASCADE ON UPDATE CASCADE,
CONSTRAINT `FK_cod_libro` FOREIGN KEY (`cod_libro`) REFERENCES `libro` (`cod_libro`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
En este caso ambas fechas deberían ser Datetime, sobre todo si la devoluvión de los libros tiene una hora de cierre antes de su penalización.
Podría quedar:
Código sql:
Ver original--
-- Definition of table `presta_libro`
--
DROP TABLE IF EXISTS `presta_libro`;
CREATE TABLE `presta_libro` (
`fecha_presta` DATETIME NOT NULL,
`fecha_devo` DATETIME DEFAULT NULL,
`cod_libro` INT(10) UNSIGNED NOT NULL,
`ci_usuario` INT(10) UNSIGNED NOT NULL,
KEY `FK_cod_libro` (`cod_libro`),
KEY `FK_cod_usuario` USING BTREE (`ci_usuario`),
CONSTRAINT `FK_ci_usuario` FOREIGN KEY (`ci_usuario`) REFERENCES `usuario` (`ci_usuario`) ON DELETE CASCADE ON UPDATE CASCADE,
CONSTRAINT `FK_cod_libro` FOREIGN KEY (`cod_libro`) REFERENCES `libro` (`cod_libro`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
En esta tabla, además, está faltando la PK, que bien podría ser la fecha+codigo de usuario + código de libro.