Ir para conteúdo


Revista PROGRAMAR – Edição 46 (Setembro 2014): Download já disponível!

- - - - -

[MYSQL] Foreign KEY


  • Por favor inicie sessão para responder
15 respostas a este tópico

#1 Gurzi

Gurzi

    Unsigned User

  • Membro
  • PipPipPipPipPipPip
  • 2579 mensagens

Publicado 14 de Janeiro de 2007 - 20:49

Boas pessoal, tive a ler e pelo que percebi, para criar uma foreign key tenho que usar o ENGINE=INNODB;

Acontece que ao tentar sucessivamente criar uma foreign KEY para IDCatalogo não consigo fazer .. devolve sempre um erro..
Já apagueii, já criei de novo.. A ultima tentativa foi:


Código (SQL):
 CREATE TABLE catalogo_autoria(
no INT( 11 ) NOT NULL AUTO_INCREMENT ,
autoria_IDAutor INT( 11 ) NOT NULL ,
autoria_IDLivro INT( 11 ) NOT NULL ,
catalogo_IDCatalogo INT( 11 ) NOT NULL ,
PRIMARY KEY ( no ) ,
INDEX ( autoria_IDAutor, autoria_IDLivro ) ,
FOREIGN KEY ( autoria_IDAutor, autoria_IDLivro ) REFERENCES Autoria( IDAutor, IDLivro ) ON UPDATE CASCADE ,
INDEX ( catalogo_IDCatalogo ) ,
FOREIGN KEY ( catalogo_IDCatalogo ) REFERENCES Catalogo( IDCatalogo )
) ENGINE = INNODB ;

e devolveu este erro :(o tal erro que me dá sempre)

#1005 - Can't create table './novaecl_Nve/catalogo_autoria.frm' (errno: 150)

#2 Knitter

Knitter

    Stack Overflow

  • Membro
  • PipPipPipPipPipPipPip
  • 6135 mensagens

Publicado 14 de Janeiro de 2007 - 22:29

Reescreve isso desta maneira:

Código (SQL):
CREATE TABLE catalogo_autoria(
no INT( 11 ) NOT NULL AUTO_INCREMENT ,
autoria_IDAutor INT( 11 ) NOT NULL ,
autoria_IDLivro INT( 11 ) NOT NULL ,
catalogo_IDCatalogo INT( 11 ) NOT NULL ,
PRIMARY KEY PK_no ( no ) ,
-- INDEX IDX_indice_autoria ( autoria_IDAutor, autoria_IDLivro ), não sei para que queres estes indices, mas se os quiseres mantes tens de ter a sintaxe correcta
FOREIGN KEY FK_autor (autoria_IDAutor) REFERENCES  Autoria( IDAutor  ON UPDATE CASCADE ,
FOREIGN KEY FK_livro (autoria_IDLivro ) REFERENCES Autoria( IDLivro ) ON UPDATE CASCADE ,
-- INDEX ( catalogo_IDCatalogo ) , não sei para que queres estes indices, mas se os quiseres mantes tens de ter a sintaxe correcta
FOREIGN KEY FK_catalogo ( catalogo_IDCatalogo ) REFERENCES Catalogo( IDCatalogo )
) ENGINE = INNODB ;

Para teres chaves estangeiras não tens de usar o motor INNODB. A sintaxe do sql está errada, precisas indicar os nomes das chaves e dos indices.

#3 Rui Carlos

Rui Carlos

    Stack Overflow

  • Staff
  • 12375 mensagens

Publicado 14 de Janeiro de 2007 - 22:34

Ver MensagemKnitter, em 14 de Janeiro de 2007 - 22:29, disse:

Para teres chaves estangeiras não tens de usar o motor INNODB.

não percebo muito de MySQL, mas penso que se não usares o INNODB ele não te verifica as restrições de integridade referencial.

#4 greed

greed

    Boolean User

  • Membro
  • PipPipPip
  • 186 mensagens

Publicado 17 de Janeiro de 2007 - 10:13

foreign key nao tem nada a ver cm o INNODB, funciona na mesma sem INNODB.
ja tentaste sem os index's cm o Knitter disse???

Normalmente eu faço os indexs a parte no codigo.

abrc.

#5 Rui Carlos

Rui Carlos

    Stack Overflow

  • Staff
  • 12375 mensagens

Publicado 17 de Janeiro de 2007 - 11:43

Ver Mensagemgreed, em 17 de Janeiro de 2007 - 10:13, disse:

foreign key nao tem nada a ver cm o INNODB, funciona na mesma sem INNODB.
ja tentaste sem os index's cm o Knitter disse???

mas restrições de integridade associadas às chaves estrangeiras são ignorada se não usares o InnoDB.

Citar

In MySQL Server 3.23.44 and up, the InnoDB storage engine supports checking of foreign key constraints, including CASCADE, ON DELETE, and ON UPDATE. See Section 14.2.6.4, “FOREIGN KEY Constraints”.

For storage engines other than InnoDB, MySQL Server parses the FOREIGN KEY syntax in CREATE TABLE statements, but does not use or store it. In the future, the implementation will be extended to store this information in the table specification file so that it may be retrieved by mysqldump and ODBC. At a later stage, foreign key constraints will be implemented for MyISAM tables as well.


#6 greed

greed

    Boolean User

  • Membro
  • PipPipPip
  • 186 mensagens

Publicado 17 de Janeiro de 2007 - 12:51

Sim isso e' obvio, se tiverem a usar xampp cuidado com isso, pq akela merda n faz os cascades bem mmo com ENGINE = INNODB em cada tabela, mais vale instalar php+apache+mysql de raiz.

#7 Knitter

Knitter

    Stack Overflow

  • Membro
  • PipPipPipPipPipPipPip
  • 6135 mensagens

Publicado 17 de Janeiro de 2007 - 16:09

Ver Mensagemgreed, em 17 de Janeiro de 2007 - 12:51, disse:

Sim isso e' obvio, se tiverem a usar xampp cuidado com isso, pq akela me*** n faz os cascades bem mmo com ENGINE = INNODB em cada tabela, mais vale instalar php+apache+mysql de raiz.

O xampp trás o INNODB desligado, mesmo que digas que a tabela é INNODB através da instrução, o motor simplesmente não está a funcionar, ele usa sempre o MyISAM. Tive o mesmo problema e resolvi-o activando o INNODB no ficheiro de configuração do MySQL.

Só removi os indices porque não sei para que é que ele os quer, como não especicou removi-os da equação, a questão, se não me engano, é a sintaxe do SQL, que penso, não estava correcta.

#8 greed

greed

    Boolean User

  • Membro
  • PipPipPip
  • 186 mensagens

Publicado 18 de Janeiro de 2007 - 04:44

Ver MensagemKnitter, em 17 de Janeiro de 2007 - 16:09, disse:

Ver Mensagemgreed, em 17 de Janeiro de 2007 - 12:51, disse:

Sim isso e' obvio, se tiverem a usar xampp cuidado com isso, pq akela me*** n faz os cascades bem mmo com ENGINE = INNODB em cada tabela, mais vale instalar php+apache+mysql de raiz.

O xampp trás o INNODB desligado, mesmo que digas que a tabela é INNODB através da instrução, o motor simplesmente não está a funcionar, ele usa sempre o MyISAM. Tive o mesmo problema e resolvi-o activando o INNODB no ficheiro de configuração do MySQL.

Só removi os indices porque não sei para que é que ele os quer, como não especicou removi-os da equação, a questão, se não me engano, é a sintaxe do SQL, que penso, não estava correcta.

cm e k fizeste isso ent, ja agr...?

thx

#9 Knitter

Knitter

    Stack Overflow

  • Membro
  • PipPipPipPipPipPipPip
  • 6135 mensagens

Publicado 19 de Janeiro de 2007 - 03:51

No meu caso, a pasta de instalação do xamp tem a seguinte estrutura:"C:\Xampp\xampp\mysql\bin", dentro desta pasta, que tem as configurações para o mysql, tens um ficheiro chamado "my.cnf", no caso do windows, o ficheiro aparece como um atalho, mas podes abri-lo com um editor de texto.
Encontra a secção que diz:

Citar

skip-innodb
# Uncomment the following if you are using InnoDB tables

Eu comentei a linha que diz "skip-innodb" e descomentei todas as que estão relacionadas com o INNODB. Fiquei com:

Citar

#skip-innodb
# Uncomment the following if you are using InnoDB tables
innodb_data_home_dir = C:/Xampp/xampp/mysql/data/
innodb_data_file_path = ibdata1:10M:autoextend
innodb_log_group_home_dir = C:/Xampp/xampp/mysql/data/
innodb_log_arch_dir = C:/Xampp/xampp/mysql/data/
# You can set .._buffer_pool_size up to 50 - 80 %
# of RAM but beware of setting memory usage too high
set-variable = innodb_buffer_pool_size=16M
set-variable = innodb_additional_mem_pool_size=2M
# Set .._log_file_size to 25 % of buffer pool size
set-variable = innodb_log_file_size=5M
set-variable = innodb_log_buffer_size=8M
innodb_flush_log_at_trx_commit=1
set-variable = innodb_lock_wait_timeout=50

Não mudei nenhum dos valores que estavam, apenas descomentei. O único problema que encontrei, é que agora não consigo desativar o serviço do mysql, pode ser uma dessa opções, não lhes tomei muita atenção.

Encontrei esta solução numa pesquisa no google, num fórum um utilizador fez estas mudanças mas referiu que leu na documentação do xampp, não sei se lá está mas se estiver poderá estar mais completo e com todas as opções explicadas.

Tenho o INNODB a funcionar e, até onde posso testar, tenho os CASCADE sem problemas, mas não testei profundamente.

#10 greed

greed

    Boolean User

  • Membro
  • PipPipPip
  • 186 mensagens

Publicado 19 de Janeiro de 2007 - 14:36

e em linux? E' o mesmo ficheiro? tenho q tentar deixa la...dps posto aqui resultados.

#11 Knitter

Knitter

    Stack Overflow

  • Membro
  • PipPipPipPipPipPipPip
  • 6135 mensagens

Publicado 19 de Janeiro de 2007 - 16:26

Sim, em linux o ficheiro é o mesmo, não está é na mesma directoria.... ok observação inútil :D
Mas sim o ficheiro é o mesmo, só tens de o conseguir encontrar, não sei onde ele se encontra... mas porque raio é que usaste o xampp em linux? Deixa-la, se conseguires resolver o problema avisa.

#12 greed

greed

    Boolean User

  • Membro
  • PipPipPip
  • 186 mensagens

Publicado 19 de Janeiro de 2007 - 17:08

Ver MensagemKnitter, em 19 de Janeiro de 2007 - 16:26, disse:

Sim, em linux o ficheiro é o mesmo, não está é na mesma directoria.... ok observação inútil :D
Mas sim o ficheiro é o mesmo, só tens de o conseguir encontrar, não sei onde ele se encontra... mas porque raio é que usaste o xampp em linux? Deixa-la, se conseguires resolver o problema avisa.

tao lol, instala php+apache+mysql...era o q eu precisava...portanto instalei...lampp alias...acho q nao e' xampp, mas vai dar ao mesmo.

#13 Machacaz

Machacaz

    void

  • Membro
  • PipPip
  • 41 mensagens

Publicado 24 de Janeiro de 2007 - 22:07

Olá. Este é o meu primeiro post neste forúm...

Tenho também uma dúvida de SQl, derivado de trabalho para a escola :-[
Acontece que criei uma tabela e dava-me jeito que esta tivesse como chave primária um atributo do tipo varchar. Até aqui sem probemas.
Quando quero criar uma tabela que use como chave forasteira esse "varchar" não consigo.
Tenho sucessivos erros. :wallbash: :wallbash: :wallbash:
Queria saber se era possível?

Tabela inicial
Código :
tabela voos
create table tf_voo(id_voo varchar(5) not null Primary Key, LocalPartida varchar(200)not null, LocalChegada varchar(200) not null
)type=innodb;

Tabela que se pretende criar:
Código :
create table tf_viagem(id_viagem int not null Primary Key,
id_trip int not null, Data date not null, hora time not null, id_voo varchar not null,
INDEX ( id_trip ) ,
FOREIGN KEY ( id_trip ) REFERENCES tf_tripulacao( id_trip ),
index (id_voo),
Foreign Key (id_voo) References tf_voos (id_voo)
)type=innodb;


#14 greed

greed

    Boolean User

  • Membro
  • PipPipPip
  • 186 mensagens

Publicado 24 de Janeiro de 2007 - 22:15

Ver MensagemMachacaz, em 24 de Janeiro de 2007 - 22:07, disse:

Olá. Este é o meu primeiro post neste forúm...

Tenho também uma dúvida de SQl, derivado de trabalho para a escola :-[
Acontece que criei uma tabela e dava-me jeito que esta tivesse como chave primária um atributo do tipo varchar. Até aqui sem probemas.
Quando quero criar uma tabela que use como chave forasteira esse "varchar" não consigo.
Tenho sucessivos erros. :wallbash: :wallbash: :wallbash:
Queria saber se era possível?

Tabela inicial
Código :
tabela voos
create table tf_voo(id_voo varchar(5) not null Primary Key, LocalPartida varchar(200)not null, LocalChegada varchar(200) not null
)type=innodb;

Tabela que se pretende criar:
Código :
create table tf_viagem(id_viagem int not null Primary Key,
id_trip int not null, Data date not null, hora time not null, id_voo varchar not null,
INDEX ( id_trip ) ,
FOREIGN KEY ( id_trip ) REFERENCES tf_tripulacao( id_trip ),
index (id_voo),
Foreign Key (id_voo) References tf_voos (id_voo)
)type=innodb;

Tira os index's so para ter a certeza que nao tem nada a ver com isso.
Outra coisa, fazes "references tf_voos", nao devia ser "references tf_voo"??

abrc.

edit: mostra os erros.

#15 Tool

Tool

    Boolean User

  • Membro
  • PipPipPip
  • 116 mensagens

Publicado 24 de Janeiro de 2007 - 22:21

id_voo varchar not null,    ->  id_voo varchar(5) not null,
Foreign Key (id_voo) References tf_voos (id_voo)  ->  tu tens a tebela tf_voo  e nao tf_voos

corrige isso... e experimenta.
pk usas um index numa chave externa? nao te melhora a velocidadade de acesso...

#16 Machacaz

Machacaz

    void

  • Membro
  • PipPip
  • 41 mensagens

Publicado 24 de Janeiro de 2007 - 23:07

Greed já tinha experimentado isso. O erro não era daí...
Corrigi o problema usando a sugestão do Tool (grande banda!):
Código :
id_voo varchar not null,    ->  id_voo varchar(5) not null

A diferença de nomes de tabelas só acontecia no txt de onde copiei o comando, ou seja, deste erro eu sabia mas obrigado pela atenção.

Obrigado pela ajuda.

Tool a outra maneira que conheço para usar chaves forasteiras é

Citar

KEY FK(chave forasteira),
CONSTRAINT FK FOREIGN KEY(chave forasteira[/i) REFERENCES tblInstituicoes ([i]chaveprimária)
) type = InnoDB;