Estás perdiendo un detalle:
No es un problema e simplicidad de tablas. Es un problema de integridad de datos entrantes.
Esto significa que no importa si la tabla es más o menos compleja:
si sigues entrando datos con las PK duplicadas o con las FK faltantes o incorrectas, el error seguirá produciéndose.
Esto puede producirse por ingresar los datos en una secuencia incorrecta o bien por faltar alguno de ellos.
Pero existe otro punto a analizar:
En el modelo de tablas que propones yo encuentro un problema que se puede producir en el transcurso de la implementación:
Has puesto tanta complejidad en la definición de las PK que eventualmente puede haber un problema en las inserciones.
Por un lado tienes que recordar que
todas las tablas que propones tienen una
cardinalidad 1:1, lo que significa que cada registro de una tabla se relaciona con un único registro de la la otra, si solamente tenemos en cuenta la cadena de relaciones que has planteado cliente -> ordendeproduccion -> pedidos -> pagos. Esto implica que para mantener la integridad de datos
solamente hace falta que la siguiente tabla contenga la PK de la anterior. El error conceptual es que, habiendo puesto un campo AUTO_INCREMENT, es absolutamente innecesario crear una PK en la segunda tabla con ambas claves.
Cabe aquí la nota: Una PK es un campo que identifica unívocamente un registro en una tabla. Un campo autoincremental es por definición único, por lo que la clave no requiere de ningún oro campo adicional.
Dicho así, entenderás que estás sobrecargando sin necesidad la PK de las siguientes tablas. La PK de la primera es su ID, el de la segunda el suyo , el de la tercera también, y el de la cuarta igual. No requieren de otro campo.
Ahora bien, a partir de la segunda tabla, lo que
pueden requerir (no necesariamente, pero si por
simplicidad de consultas), es
agregar como FK los identificadores de todas las tablas precedentes. Pero estas FK no deben formar parte de la PK. Pueden, si, conformar claves de índices, pero ese es otro asunto.
Entonces, un modelo funcional y con pocos problemas de inserción sería:
Código sql:
Ver originalCREATE TABLE clientes (
idcliente INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
nombre VARCHAR(45) NULL,
telefono INT NULL,
compania VARCHAR(45) NULL,
PRIMARY KEY(idcliente)
);
CREATE TABLE ordenproduccion (
idordenproduccion INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
idcliente INTEGER UNSIGNED NOT NULL,
modelo VARCHAR(10) NULL,
cantidad INTEGER UNSIGNED NULL,
talla VARCHAR(5) NULL,
color VARCHAR(10) NULL,
descripcion VARCHAR(15) NULL,
precio DOUBLE NULL,
observaciones VARCHAR(100) NULL,
nopedido INTEGER UNSIGNED NULL,
PRIMARY KEY(idordenproduccion),
FOREIGN KEY(idcliente)
REFERENCES clientes(idcliente)
ON DELETE NO ACTION
ON UPDATE NO ACTION
);
CREATE TABLE pedido (
idpedido INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
idcliente INTEGER UNSIGNED NOT NULL,
idordenproduccion INTEGER UNSIGNED NOT NULL,
fechapedido DATE NULL,
fechaentrega DATE NULL,
nonota INTEGER UNSIGNED NULL,
vendedor VARCHAR(10) NULL,
PRIMARY KEY(idpedido),
FOREIGN KEY(idordenproduccion)
REFERENCES ordenproduccion(idordenproduccion)
ON DELETE NO ACTION
ON UPDATE NO ACTION,
FOREIGN KEY(idcliente)
REFERENCES clientes(idcliente)
ON DELETE NO ACTION
ON UPDATE NO ACTION
);
CREATE TABLE pagos (
idpago INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
idpedido INTEGER UNSIGNED NOT NULL,
idcliente INTEGER UNSIGNED NOT NULL,
idordenproduccion INTEGER UNSIGNED NOT NULL,
noprendas INTEGER UNSIGNED NULL,
totapagar DOUBLE NULL,
formapago VARCHAR(20) NULL,
pagado DOUBLE NULL,
restante DOUBLE NULL,
fecha DATE NULL,
PRIMARY KEY(idpago),
FOREIGN KEY(idordenproduccion)
REFERENCES ordenproduccion(idordenproduccion)
ON DELETE NO ACTION
ON UPDATE NO ACTION,
FOREIGN KEY(idcliente)
REFERENCES clientes(idcliente)
ON DELETE NO ACTION
ON UPDATE NO ACTION,
FOREIGN KEY(idpedido)
REFERENCES pedido(idpedido)
ON DELETE NO ACTION
ON UPDATE NO ACTION
);
Esto, si lo pruebas, verás que puede crearse sin ningún inconveniente, y no exigirá los procesos de integridad como lo hace el mdoelo anterior.
Prueba y veamos.