Dica: corrigindo o error 150 (#10005) no MySQL

Neste último bimestre em minhas aulas de banco de dados redescobri a integridade referencial em banco de dados, e suas ações em caso de alteração e exclusão. Redescobrir? Sim… Desde que comecei a mexer com PHP/MySQL eu nunca tinha feito isso, porque as tabelas MyISAM (antigas) não dão suporte a esta funcionalidade. Para quem não conhece, pretendo fazer um vídeo tutorial sobre isso em breve, pois é um assunto bastante interessante e economiza bastante tempo na hora de programar. Mas só para dar uma idéia, ele serve para garantir que a integridade de uma chave estrangeira e as ações de quando o registro pai for apagado.

Por exemplo, se tenho uma tabela posts com campos id, titulo, conteudo e uma tabela comentários com os campos id, autor, post_id, o único valor válido para post_id é um valor de id válido em posts. Ou seja, garante-se a integridade no próprio banco de dados. Uma outra funcionalidade é qual ação deverá ser tomada se, por exemplo, um post for apagado, que poderia ser apagar todos os comentários relacionados, evitando comentários sem posts. Isso tudo no banco, sem precisar programar nada!

Este post, é para quem já fez/faz o uso deste recurso e que já se deparou com o erro 150 (#10005).

A dica muito valiosa veio do forum do MySQL, o qual diz que os dois campos devem ser idênticos em seus tipos. Ou seja (aqui estava meu erro) até mesmo se ele é unsigned deve ser igual. As outras condições são:

  • Ambas as tabelas do tipo InnoDB;
  • Na tabela que faz a referência, deve haver um indíce que corresponde a chave estrangeira;
  • Na tabela referenciada, deve haver um indíce que corresponde a chave primária;
  • Não são suportados para este tipo de relacionamento, campos text e blob;
  • Os campos devem ter o mesmo tipo (em todas as características);

Bom é isso, espero que isso ajude alguém…

Abraços pessoal e até a próxima…

15 Comentários »

  1. Medina said,

    Março 12, 2008 @ 05:30

    Muito boa dica…

    sabia o inconveniente com os tipos e tamanho de dados. O que não sabia era a respeito dos Unsigned.

    Valeu pela dia…

    forte abraço.

  2. Henrique said,

    Junho 24, 2008 @ 20:21

    Túlio foi muito importante saber desta dica, me livrei de um erro que dava no MySQL Administrator na hora de criar uma chave primária. Realmente o campos que vão ser “ligados” devem ter os mesmo atributos (UNSIGNED, etc…).

    abraço

  3. Roder said,

    Novembro 7, 2008 @ 19:44

    Valeu!!! Muito boa essa dica… Resolveu nosso problema!!!

  4. Alessandro said,

    Novembro 10, 2008 @ 14:51

    Muito boa a dica!! Valeu

  5. Almino Melo said,

    Janeiro 24, 2009 @ 15:50

    Esse erro acontece também quando temos um nome igual ao de outra Chave Estrangeira. Ou seja: não podemos ter dois nomes de chaves estrangeiras iguais.

  6. Jonnathan Weber said,

    Maio 10, 2009 @ 18:50

    quanto a ter atributos com mesmo nome, não acho que seja do jeito que o almino falou, pois eu tenho aqui duas tabelas com mesmo atributo e o mysql criou normal.

  7. Ricarte Jr said,

    Junho 4, 2009 @ 23:43

    Muito boa amigo. Só depois que eu li tudo foi que consegui resolver o problema. rs Estava uma briga feia. Valeu!

  8. Fabio said,

    Agosto 27, 2009 @ 11:45

    Tulio,

    Este banco é muito rúin!!!!
    Removi todas as chaves primárias do schema inteiro !!!!
    O ERRO ainda persiste para o CREATE TABLE e ALTER TABLE.

    Alguém sabe como elimino este erro sem “DROPAR” todo schema?

    Tenho vontade de dropar o schema de tanta agonia!!!!

  9. Diego Chaves said,

    Outubro 2, 2009 @ 13:42

    Estou agora fazendo um banco para um e-commerce e encontrei este texto,

    mas ha aqui algumas coisas vale a pena comentar, para vcs não cairem em erros e tbm ficarem limitados

    Ambas as tabelas do tipo InnoDB;
    SIM, É VERDADE, MAS NÃO É SOMENTE ESTE TIPO DE TABELA QUE FAZ RELACIONAMENTOS.

    Na tabela que faz a referência, deve haver um indíce que corresponde a chave estrangeira;
    NÃO TÃO SIMPLES ASSIM, O INDICE (INDEX) EM MYSQL CRIA UMA CHAMADA NO HD QUE FAZ REFERENCIA A COLUNA NA TABELA, ENTÃO NÃO NECESSARIAMENTE DEVE HAVER UM INDEX PARA A CHAVE ESTRANGEIRA, PODE-SE CRIAR CHAVE ESTRANGEIRA SEM CRIAÇÃO DE INDICE (INDEX), MAS SIM NOMEA-LA, LEMBRANDO QUE DUAS CHAVES ESTRANGEIRAS NÃO DEVEM TER O MESMO NOME, E REFERENCIA-LA A TABELA E A COLUNA ASSIM: constraint fk_cliente foreign key (idcliente) references tb_cliente (idcliente)

    Na tabela referenciada, deve haver um indíce que corresponde a chave primária;
    RESPONDIDO ACIMA, NÃO HA NECESSIDADE DE INDICE!!!!!!!!!!!!!!!

    Não são suportados para este tipo de relacionamento, campos text e blob;
    Os campos devem ter o mesmo tipo (em todas as características);

    FAZ-SE CHAVES SEGUNDARIAS QUE SE RELACIONAM AO A CHAVE PRIMARIA DE OUTRA TABELA, SE DIFERENTE PODE-SE CAIR EM REDUNDANCIA

  10. Diego Chaves said,

    Outubro 2, 2009 @ 13:44

    desculpem-me, leia-se DATABASE em TABELA na frase abaixo:

    SIM, É VERDADE, MAS NÃO É SOMENTE ESTE TIPO DE TABELA QUE FAZ RELACIONAMENTOS.

  11. Leonaro Santiago said,

    Outubro 12, 2009 @ 00:15

    Eu tinha o mesmo problema que vc, somente construindo tabelas MyISAM, e na hora de fazer algo mais sofisticado, quebrei a cabeça com este erro 150, até havia criado as constraints, e tudo mais o meu erro era os unsigned; Obrigado pela dica!

  12. oJ said,

    Abril 18, 2010 @ 13:40

    Ótima dica! valeu!

  13. Helton said,

    Abril 26, 2010 @ 16:26

    Pode ter certeza que ajudou

  14. André Banderas said,

    Maio 4, 2010 @ 10:55

    Valeu mesmo, esse checklist que você publicou me ajudou bastante…

  15. Raphael Cardoso said,

    Agosto 1, 2010 @ 23:09

    Muito boa a sua dica. Eu estava tentando realcionar duas tabelas com campos varchar só que elas estavam diferentes.

    Obrigado pela dica.
    Abraço

RSS feed for comments on this post · URI do TrackBack

Deixe seu comentário