Problema con Foreign Key MySQL

Iniciado por InuKen, 19 Julio 2009, 01:48 AM

0 Miembros y 1 Visitante están viendo este tema.

InuKen

Hola que tal compañeros, este es mi primer mensaje y les agradezco por tener un espacio como este para poder participar o preguntar, asi como tambien si el tema que cree esta en un lugar equivocado lo siento, he buscado un foro o subforo de bd y no he encontrado ninguno, se me ocurrio por ello ponerlo aqui.

Estoy estudiando MySQL, acabo de terminar la introduccion a mysql en una escuela, mas sin embargo no nos enseñaron nada de teoria sobre las bases de datos relacionales, esto lo tuve que buscar por mi propia cuenta.

Armando mi propio modelo de entidad relacional sobre una conferencia donde se van a dar diversos temas de ciencia, estoy intentando crear dos tablas para empezar, una de ellas es la tabla dominante " temas " en la cual he creado una primary key compuesta por tres campos, esto lo logro crear sin problema alguno, el problema se presenta cuando creo las demas tablas e intento poner sus llaves foraneas que se conecten con la tabla " temas ". Simplemente MySQL no me deja, me da error 1005:150.

Estuve buscando por internet sobre este error y segun pude encontrar que es debido a que las tablas que intento relacionar son incompatibles, pero por mas que busco las incompatibilidades no las encuentro. De antemano agradeceria de su apoyo para salir de esta gran duda.

Mi script es el siguiente:

drop database if exists conferencia;

create database conferencia;

use conferencia;

drop table if exists conferencias;

create table conferencias(
exp_id int ,
temas varchar(20) not null,
desc_corta varchar(30) not null,
total_part int not null,
costo decimal(5,2) ,
horario datetime not null,
lugar varchar(10) not null,
primary key (exp_id,temas,costo)
);

drop table if exists expositores;

create table expositores(
exp_id int ,
Nombre varchar(12) not null,
ApellidoP varchar(12) not null,
ApellidoM varchar(12) not null,
Fecha_Nac datetime not null,
salario decimal(6,2) not null,
foreign key (exp_id) references conferencias (exp_id)
);

drop table if exists precios;

create table precios(

temas varchar(20) not null ,
costo decimal(5,2) ,
precio_dsc varchar(10) ,
foreign key (temas) references conferencias (temas)
);

--------------------------

El problema se presenta en la foreign key de la tabla precios, es cuando me marca el error 1005:150.

rigoxls

Saludos

Bueno, mirando la base de datos a simple vista esta bien, y de hecho cuando la probe en mi servidor local y en internet no me genero error, lo unico que te puedo decir es que generalmente las llaves primarias y foraneas deberian ser numericas tipo int, por lo general, igual no es regla absoluta, pero si se deberian evitar dejar campos char, varchar, text y demas tipos similares como llaves primarias y foraneas...
No hay verdades absolutas sin ciegas posiciones !!!

InuKen

Que raro, de hecho intente en otro servidor mysql que tengo en mi laptop y me marca el mismo error, que no se puede crear la tabla precio, pero si quito la foreign key de la tabla (precio) las tres tablas se generan sin problema.

Uhhhm, soy nuevo en esto del mysql y bueno, tal vez mi tabla (temas) no debe de llevar tantas llaves primarias en forma compuesta, aunque en ningun lado he leido que eso sea incorrecto.

Por cierto man, tendras msn? Si es asi agregame por favor: kenshin.kaoru@gmail.com es mi MSN, te agradeceria que me agregaras para conversar.

Spider-Net

Seguramente el problema es que no estás utilizando el motor InnoDB. Cuando creas bases de datos relacionales con claves foráneas has de utilizar el motor InnoDB siempre.

CitarInnoDB es una tecnología de almacenamiento de datos de fuente abierta para la base de datos MySQL, incluido como formato de tabla estándar en todas las distribuciones de MySQL AB a partir de las versiones 4.0. Su característica principal es que soporta transacciones de tipo ACID y bloqueo de registros e integridad referencial. InnoDB ofrece una fiabilidad y consistencia muy superior a MyISAM, la anterior tecnología de tablas de MySQL, si bien el mejor rendimiento de uno u otro formato dependerá de la aplicación específica.

De modo que tendrías que hacer lo siguiente:

Código (sql) [Seleccionar]
drop database if exists conferencia;

create database conferencia;

use conferencia;

drop table if exists conferencias;

create table conferencias(
exp_id int ,
temas varchar(20) not null,
desc_corta varchar(30) not null,
total_part int not null,
costo decimal(5,2) ,
horario datetime not null,
lugar varchar(10) not null,
primary key (exp_id,temas,costo)
) ENGINE=InnoDB;

drop table if exists expositores;

create table expositores(
exp_id int ,
Nombre varchar(12) not null,
ApellidoP varchar(12) not null,
ApellidoM varchar(12) not null,
Fecha_Nac datetime not null,
salario decimal(6,2) not null,
foreign key (exp_id) references conferencias (exp_id)
) ENGINE=InnoDB;

drop table if exists precios;

create table precios(

temas varchar(20) not null ,
costo decimal(5,2) ,
precio_dsc varchar(10) ,
foreign key (temas) references conferencias (temas)
) ENGINE=InnoDB;


Además al instalar el MySql debes de marcar la casilla de: Enable InnoDB sino no funcionará aunque crees bien la sentencia SQL ya que el motor no estará instalado.

Si estás utilizando AppServ es bastante sencillo:


Justo en esta pantalla debes marcar la casilla Enable InnoDB y ya está. Con eso no tendrías que tener problemas para utilizar las claves foráneas.

Un saludo!

^Tifa^

Algo que debes tener en cuenta chico antes de proseguir:

Para uso de llave foraneas:

* Las 3 tablas en este caso deben estar en motor InnoDB.
* Los datos de relacion entre llaves foraneas he indice de la tabla padre
deben ser del mismo tipo y del mismo tamanio.

--- Tu Error se debe a lo siguiente ---



EL motor InnoDB requiere explicitamente, que los indices utilizados como llaves foraneas o los registros de la tabla padre usados como relacion TENGAN UN INDICE CON NOMBRE!



Leyendo lo anterior y teniendolo siempre en cuenta, tu problema se resuelve con :::

Código (sql) [Seleccionar]


create table conferencias(
exp_id int not null auto_increment,
temas varchar(20) not null,
desc_corta varchar(30) not null,
total_part int not null,
costo decimal(5,2) ,
horario datetime not null,
lugar varchar(10) not null,
primary key (exp_id,temas,costo)
) engine = InnoDB;


create table expositores(
exp_id int,
Nombre varchar(12) not null,
ApellidoP varchar(12) not null,
ApellidoM varchar(12) not null,
Fecha_Nac datetime not null,
salario decimal(6,2) not null,
index indice (exp_id),
foreign key (exp_id) references conferencias (exp_id)
) engine = InnoDB;


create table precios(
temas varchar(20) not null ,
costo decimal(5,2) ,
precio_dsc varchar(10) ,
index indice_dos(temas),
foreign key (temas) references conferencias (temas)
) engine = InnoDB;




O sencillamente crea el indice en la tabla padre:

Código (sql) [Seleccionar]


create table conferencias(
exp_id int not null auto_increment,
temas varchar(20) not null,
desc_corta varchar(30) not null,
total_part int not null,
costo decimal(5,2) ,
horario datetime not null,
lugar varchar(10) not null,
constraint PK_Llave primary key (exp_id,temas,costo)
) engine = InnoDB;



La proxima vez que te salga este tipo de errores, sino encuentras solucion en google, y tus tablas estan en motor InnoDB ejecuta en MySQL:

mysql> SHOW INNODB STATUS;

Y busca entre toda esa info donde diga

------------------------
LATEST FOREIGN KEY ERROR
------------------------

Y el detalle del mismo :)  Para ejecutar esa consulta tu usuario debe tener privilegios PROCESS