Mysql
 sql >> Base de Dados >  >> RDS >> Mysql

MySQL Criando tabelas com chaves estrangeiras dando errno:150


Eu tive o mesmo problema com ALTER TABLE ADD FOREIGN KEY .

Após uma hora, descobri que essas condições devem ser atendidas para não obter o erro 150:

  1. A tabela Pai deve existir antes de você definir uma chave estrangeira para referenciá-la. Você deve definir as tabelas na ordem correta:primeiro a tabela pai, depois a tabela filho. Se ambas as tabelas fizerem referência uma à outra, você deve criar uma tabela sem restrições FK, criar a segunda tabela e adicionar a restrição FK à primeira tabela com ALTER TABLE .

  2. As duas tabelas devem suportar restrições de chave estrangeira, ou seja, ENGINE=InnoDB . Outros mecanismos de armazenamento ignoram silenciosamente as definições de chave estrangeira, portanto, não retornam nenhum erro ou aviso, mas a restrição FK não é salva.

  3. As colunas referenciadas na tabela Pai devem ser as colunas mais à esquerda de uma chave. Melhor se a chave no Pai for PRIMARY KEY ou UNIQUE KEY .

  4. A definição FK deve fazer referência à(s) coluna(s) PK na mesma ordem que a definição PK. Por exemplo, se o FK REFERENCES Parent(a,b,c) então o PK do pai não deve ser definido nas colunas na ordem (a,c,b) .

  5. As colunas PK na tabela Pai devem ser do mesmo tipo de dados que as colunas FK na tabela Filho. Por exemplo, se uma coluna PK na tabela Pai for UNSIGNED , certifique-se de definir UNSIGNED para a coluna correspondente no campo Tabela filho.

    Exceção:o comprimento das strings pode ser diferente. Por exemplo, VARCHAR(10) pode referenciar VARCHAR(20) ou vice-versa.

  6. Qualquer coluna FK do tipo string deve ter o mesmo conjunto de caracteres e agrupamento que a(s) coluna(s) PK correspondente(s).

  7. Se já houver dados na tabela filho, cada valor na(s) coluna(s) FK deve corresponder a um valor na(s) coluna(s) PK da tabela pai. Verifique isso com uma consulta como:
    SELECT COUNT(*) FROM Child LEFT OUTER JOIN Parent ON Child.FK = Parent.PK 
    WHERE Parent.PK IS NULL;
    

    Isso deve retornar zero (0) valores não correspondentes. Obviamente, esta consulta é um exemplo genérico; você deve substituir seus nomes de tabela e nomes de coluna.

  8. Nem a tabela Pai nem a tabela Filho podem ser TEMPORARY tabela.

  9. Nem a tabela Pai nem a tabela Filho podem ser PARTITIONED tabela.

  10. Se você declarar um FK com o ON DELETE SET NULL opção, as colunas FK devem ser anuláveis.

  11. Se você declarar um nome de restrição para uma chave estrangeira, o nome da restrição deverá ser exclusivo em todo o esquema, não apenas na tabela na qual a restrição está definida. Duas tabelas não podem ter sua própria restrição com o mesmo nome.

  12. Se houver outros FKs em outras tabelas apontando para o mesmo campo para o qual você está tentando criar o novo FK e eles estiverem malformados (ou seja, agrupamento diferente), eles precisarão ser consistentes primeiro. Isso pode ser resultado de alterações anteriores em que SET FOREIGN_KEY_CHECKS = 0; foi utilizado com uma relação inconsistente definida por engano. Veja a resposta de @andrewdotn abaixo para obter instruções sobre como identificar esses FKs problemáticos.

Espero que isto ajude.