restrição de chave estrangeira mysql erro formado incorretamente

173

Eu tenho duas tabelas, table1é a tabela pai com uma coluna IDe table2com uma coluna IDFromTable1(não o nome real), quando eu colocar uma FK em IDFromTable1que IDem table1que eu recebo o erro Foreign key constraint is incorrectly formed error. Gostaria de excluir o registro da tabela 2 se o table1registro for excluído. Obrigado por qualquer ajuda

ALTER TABLE `table2`  
   ADD CONSTRAINT `FK1` 
      FOREIGN KEY (`IDFromTable1`) REFERENCES `table1` (`ID`) 
      ON UPDATE CASCADE 
      ON DELETE CASCADE;

Deixe-me saber se alguma outra informação é necessária. Eu sou novo no mysql

user516883
fonte
4
Qual mecanismo você está usando para suas mesas? Qual é o tipo de table2.IDFromTable1e table1.ID?
Romain
5
Além disso, verifique se os conjuntos de caracteres para as duas tabelas são os mesmos.
Carsten
Os dois mecanismos de tabelas são innoDB. não sabe onde encontrar conjuntos de caracteres e os dois são do tipo char. O ID é a chave primária na tabela1
user516883 08/12
2
Forneça definições de tabela para tabela1 e tabela2. Como você recebeu esse erro? Você usa uma ferramenta para criar a chave estrangeira? Parece que não é um erro nativo do MySQL.
Devart
@ user516883 - Você precisa de ajuda para obter definições de tabela? No HeidiSQL, você pode simplesmente clicar na guia CREATE code .
Álvaro González

Respostas:

422

Encontrei esse mesmo problema com o HeidiSQL. O erro que você recebe é muito enigmático. Meu problema acabou sendo que a coluna de chave estrangeira e a coluna de referência não eram do mesmo tipo ou comprimento.

A coluna de chave estrangeira era SMALLINT(5) UNSIGNEDe a coluna referenciada era INT(10) UNSIGNED. Depois que eu fiz os dois do mesmo tipo exato, a criação da chave estrangeira funcionou perfeitamente.

Jake Wilson
fonte
58
Ou pode ser que a coluna referenciada não é uma chave primária
Nawfal
9
Problema meio semelhante para mim - a tabela referenciada ainda não existia. Ops.
Amalgovinus
5
Eu experimentei totalmente o que Jake fez, mas encontrei outro problema FK (tipo diferente) no HeidiSQL. O FK nos varchars precisa ter o mesmo agrupamento. Espero que ajude outra pessoa no futuro!
precisa saber é o seguinte
10
No meu caso, foi por causa de diferentes codificações e agrupamentos.
Khatri
1
@nawfal - Eu acredito que não precisa necessariamente ser uma chave primária, mas DEVE ter um índice. As chaves primárias são automaticamente indexadas.
Itai
48

Eu tive o mesmo problema quando a tabela pai foi criada usando o MyISAMmecanismo. É um erro bobo, que corrigi com:

ALTER TABLE parent_table ENGINE=InnoDB;
Denis Malinovsky
fonte
Muito obrigado, eu estava ficando louco com isso. Alguma idéia de por que o banco de dados trocaria repentinamente o mecanismo por tabelas?
Robert Franklin
28

verifique se as colunas são idênticas (do mesmo tipo) e se a coluna de referência não for primary_key, verifique se é INDEXED.

Santosh
fonte
Até aconteceu comigo que, não havia erro, mas a chave estrangeira não foi adicionada (1 era e 1 não era realmente), mas depois de adicionar simples KEY referencing_column(referencing_column) ANTES da definição de ambas as chaves estrangeiras, elas foram adicionadas com êxito :)
jave.web
2
Chaves não sendo indexadas foram o meu problema.
Neil Masters
1
Eu tive esse problema e o problema era que eu tinha uma chave primária de coluna dupla e você não pode usar a segunda coluna da chave primária como uma chave estrangeira. Então, eu apenas adicionei o próprio índice para a 2ª coluna da chave primária e funcionou.
Firze 5/07/19
21

A sintaxe para definir chaves estrangeiras é muito indulgente, mas para qualquer pessoa que tropeçar nisso, o fato de que as chaves estrangeiras devem ser "do mesmo tipo" se aplica até ao agrupamento, não apenas ao tipo de dados e comprimento e assinatura de bits.

Não que você misture agrupamento em seu modelo (você faria?), Mas, se o fizer, verifique se os campos de chave primária e externa são do mesmo tipo de agrupamento no phpmyadmin ou Heidi SQL ou o que você usar.

Espero que isso poupe as quatro horas de tentativa e erro que isso me custou.

user2297047
fonte
1
Obrigado! Acontece que meu host online usa o mecanismo ISAM e, para desenvolvedores locais, eu uso o InnoDB. Quando fiz backup de uma mesa do host para o local ... boom.
19413 Ben
As versões recentes do MariaDB parecem usar utf8_mb4 como o conjunto de caracteres padrão (quando não definido explicitamente na configuração do servidor), assim COLLATE utf8mb4_unicode_cicomo meu problema (inesperado) (na máquina dev).
JonnyJD
13

Eu tive o mesmo problema, mas resolvi.

Apenas certifique-se de que a coluna 'ID' na 'tabela1' tenha índice ÚNICO !

E é claro que o tipo, o comprimento das colunas 'ID' e 'IDFromTable1' nessas duas tabelas devem ser iguais. Mas você já sabe disso.

Renat Gatin
fonte
Você fez meu dia.
kevenlolo
1
Feliz em ajudar! ;)
Renat Gatin
Incerto dos detalhes, mas eu tinha uma chave composta com esse erro que foi corrigido adicionando índices exclusivos individuais para as colunas.
Halvor Holsten Strand
A coluna referenciada deve ser indexada, não precisa ser única (embora esse seja o caso usual).
Barmar 25/02/19
10

Apenas para conclusão.

Esse erro também pode ser o caso se você tiver uma chave estrangeira com VARCHAR (..) e o conjunto de caracteres da tabela referenciada for diferente da tabela que a referencia.

por exemplo, VARCHAR (50) em uma tabela Latin1 é diferente do VARCHAR (50) em uma tabela UTF8.

S Doering
fonte
1
Até utf8_unicode_ci e utf8_general_ci estão causando o erro #
leuchtdiode
10

os textos de erro do mysql não ajudam muito, no meu caso, a coluna tinha uma restrição "não nula", portanto o "ao excluir conjunto nulo" não era permitido

Luca C.
fonte
7

se estiver tudo bem, basta adicionar ->unsigned();no final de foregin key.

se não funcionar, verifique o tipo de dados dos dois campos. eles devem ser os mesmos.

josef
fonte
5

Eu tive o mesmo problema, as duas colunas eram INT (11) NOT NULL, mas não consigo criar a chave estrangeira. Eu tive que desativar as verificações de chaves estrangeiras para executá-lo com sucesso:

SET FOREIGN_KEY_CHECKS=OFF;
ALTER TABLE ... ADD CONSTRAINT ...
SET FOREIGN_KEY_CHECKS=ON;

Espero que isso ajude alguém.

Takman
fonte
4
Na verdade, é FOREIGN_KEY_CHECKS
Xmanoux
Isso ajudou-me a passar mais, mas o meu problema foi o índice de primmary na coluna faltando
Bumerang
4

Mais uma causa provável para a exibição desse erro. A ordem em que eu estava criando tabelas estava errada. Eu estava tentando fazer referência a uma chave de uma tabela que ainda não foi criada.

Kaya Toast
fonte
4

(Último reenvio) Mesmo se o nome do campo e o tipo de dados forem iguais, mas o agrupamento não for o mesmo, também resultará nesse problema.

Por exemplo

    NOME TBL | TIPO DE DADOS | COLLAÇÃO        

    ActivityID | INT         latin1_general_ci     ActivityID | INT         utf8_general_ci

Tente transformá-lo em

    NOME TBL | TIPO DE DADOS | COLLAÇÃO        

    ActivityID | INT         latin1_general_ci     ActivityID | INT         latin1_general_ci

....

Isso funcionou para mim.

Jimwel Anobong
fonte
3

Verifique o mecanismo das tabelas, as duas tabelas precisam ser do mesmo mecanismo, o que me ajudou muito.

mariobigboy
fonte
Bom ponto! Estou lidando com um banco de dados Zen Cart no MySQL cujas tabelas estão todas no mecanismo MyISAM por padrão. Adicionei uma tabela usando o mecanismo InnoDB e tentei adicionar uma restrição de chave estrangeira da minha tabela ao principal Zen Cart. Ele falhou com este erro obscuro "formado incorretamente". Você pode ver o motor para cada tabela comSHOW TABLE STATUS LIKE 'table_name';
Neek
2

Eu tenho os mesmos problemas.

O problema é que a coluna de referência não é uma chave primária.

Faça dela uma chave primária e o problema será resolvido.

longluffy
fonte
Ele não precisa ser um PK, também pode ser ÚNICO, NÃO NULO.
Philipxy # 7/17
Na verdade ... no meu caso, simplesmente configurá-lo para um tipo de índice normal funcionou.
hendr1x
2

Embora as outras respostas sejam bastante úteis, eu também queria compartilhar minha experiência.

Eu enfrentei o problema quando excluí uma tabela que idjá estava sendo referenciada como chave estrangeira em outras tabelas ( com dados ) e tentei recriar / importar a tabela com algumas colunas adicionais.

A consulta para recreação (gerada no phpMyAdmin) tinha a seguinte aparência:

CREATE TABLE `the_table` (
  `id` int(11) NOT NULL,            /* No PRIMARY KEY index */  
  `name` varchar(255) NOT NULL,
  `name_fa` varchar(255) NOT NULL,
  `name_pa` varchar(255) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

... /* SOME DATA DUMP OPERATION */

ALTER TABLE `the_table`
  ADD PRIMARY KEY (`id`), /* PRIMARY KEY INDEX */
  ADD UNIQUE KEY `uk_acu_donor_name` (`name`);

Como você pode notar, o PRIMARY KEYíndice foi definido após a criação ( e inserção de dados ) que estava causando o problema.

Solução

A solução foi adicionar o PRIMARY KEYíndice na consulta de definição de tabela para a idqual estava sendo referenciada como chave estrangeira, além de removê-lo da ALTER TABLEparte em que os índices estavam sendo definidos:

CREATE TABLE `the_table` (
  `id` int(11) NOT NULL PRIMARY KEY,            /* <<== PRIMARY KEY INDEX ON CREATION */  
  `name` varchar(255) NOT NULL,
  `name_fa` varchar(255) NOT NULL,
  `name_pa` varchar(255) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
Ahmad Baktash Hayeri
fonte
Funcionou para mim. Eu estava preocupado que eu preciso reinstalar o software;)
Dewlance
2

Eu perdi por horas por isso!

PK em uma mesa estava utf8em outra era utf8_unicode_ci!

LukaszTaraszka
fonte
1

Tente executar o seguinte:

show create table Parent

// e verifique se o tipo para as duas tabelas é o mesmo, como myISAM ou innoDB, etc
// Outros aspectos a serem verificados com esta mensagem de erro: as colunas usadas como estrangeiras 
chaves devem ser indexadas, elas devem ser do mesmo tipo 
(se, por exemplo, um for do tipo smallint (5) e o outro do tipo smallint (6), 
não funcionará) e, se forem números inteiros, não deverão ser assinados.

// ou verifique se há conjuntos de caracteres
mostra variáveis ​​como "character_set_database";
mostre variáveis ​​como "collation_database";

// editado: tente algo como isto
ALTER TABLE tabela2
ADICIONAR CONSTRAINT fk_IdTable2
CHAVE ESTRANGEIRA (Tabela1_Id)
Referências Tabela1 (Tabela1_Id)
NA CASA DE ATUALIZAÇÃO 
EM EXCLUIR CASCADE;
Sudhir Bastakoti
fonte
9
Tente executar o SHOW ENGINE INNODB STATUS para obter mais detalhes sobre o erro
Sudhir Bastakoti
@SudhirBastakoti - +1! Isso fez por mim. Os detalhes são úteis. Consertou o problema rapidamente.
Paul Carlton
1

Eu tive o mesmo problema com o Symfony 2.8.

Eu não entendi no começo, porque não havia problemas semelhantes com o comprimento int de chaves estrangeiras etc.

Finalmente, tive que fazer o seguinte na pasta do projeto. (A reinicialização do servidor não ajudou!)

app/console doctrine:cache:clear-metadata app/console doctrine:cache:clear-query app/console doctrine:cache:clear-result

rogaa
fonte
1

obrigado S Doerin:

"Apenas para conclusão. Esse erro também pode ser o caso se você tiver uma chave estrangeira com VARCHAR (..) e o conjunto de caracteres da tabela referenciada for diferente da tabela que a referencia. Por exemplo, VARCHAR (50) em uma tabela Latin1 é diferente do VARCHAR (50) em uma tabela UTF8. "

Eu resolvi esse problema, alterando o tipo de caracteres da tabela. a criação tem latin1 e o correto é utf8.

adicione a próxima linha. PADRÃO PERSONALIZADO SET = utf8;

Bladimir Arias Sabogal
fonte
1

Eu tive problemas ao usar a tabela Alter para adicionar uma chave estrangeira entre duas tabelas e o que me ajudou foi garantir que cada coluna à qual eu estava tentando adicionar um relacionamento de chave estrangeira fosse indexada. Para fazer isso no PHP myAdmin: Vá para a tabela e clique na guia estrutura. Clique na opção de índice para indexar a coluna desejada, conforme mostrado na captura de tela:

insira a descrição da imagem aqui

Depois de indexar as duas colunas que estava tentando referenciar com minhas chaves estrangeiras, pude usar com êxito a tabela alter e criar o relacionamento de chave estrangeira. Você verá que as colunas são indexadas como na captura de tela abaixo:

insira a descrição da imagem aqui

observe como o zip_code aparece nas duas tabelas.

Chris Adams
fonte
1

Você precisa verificar se os dois são iguais em todas as suas propriedades, inclusive em "Agrupamento"

CrsCaballero
fonte
1

Eu estava usando o HeidiSQL e, para resolver esse problema, tive que criar um índice na tabela referenciada com todas as colunas sendo referenciadas.

adicionando índice à tabela Heidisql

Doug
fonte
O mesmo para mim no mysql: o InnoDB requer índices em chaves estrangeiras e chaves referenciadas para que as verificações de chaves estrangeiras possam ser rápidas e não exigir uma varredura de tabela.
hendr1x
1

Encontrei o mesmo problema agora. No meu caso, tudo o que eu precisava fazer era garantir que a tabela que eu estou referenciando na chave estrangeira deve ser criada antes da tabela atual (anteriormente no código). Portanto, se você estiver referenciando uma variável (x * 5), o sistema deve saber o que x é (x deve ser declarado nas linhas de código anteriores). Isso resolveu meu problema, espero que ajude outra pessoa.

Alexander Nenartovich
fonte
Eu tive o mesmo problema no MariaDB v10.3.18. Nós usamos o MySQL antes e ele avisa que uma chave estrangeira aponta para uma tabela inexistente.
MarthyM
0

Eu tive o mesmo problema com o Schema Builder de migração do Laravel 5.1 com o MariaDB 10.1.

O problema foi que eu digitei em unignedvez de unsigned( sfaltava a letra) ao definir a coluna.

Depois de corrigir o erro de digitação foi corrigido para mim.

Arda
fonte
0

Mesmo eu tive o mesmo problema com o mysql e liquibase. Portanto, este é o problema: A tabela da qual você deseja referenciar uma coluna de outra tabela é diferente no caso do tipo de dados ou em termos de tamanho do tipo de dados.

Error appears in below scenario:
Scenario 1:
Table A has column id, type=bigint
Table B column referenced_id type varchar(this column gets the value from the id column of Table A.)
Liquibase changeset for table B:

    <changeset id="XXXXXXXXXXX-1" author="xyz">
            <column name="referenced_id" **type="varchar"**>
        </column>
            </changeset>
    <changeSet id="XXXXXXXXXXX-2" author="xyz">
                <addForeignKeyConstraint constraintName="FK_table_A"
                    referencedTableName="A" **baseColumnNames="referenced_id**"
                    referencedColumnNames="id" baseTableName="B" />
    </changeSet>

Table A changeSet:

    <changeSet id="YYYYYYYYYY" author="xyz">
     <column **name="id"** **type="bigint"** autoIncrement="${autoIncrement}">
                    <constraints primaryKey="true" nullable="false"/>
                </column>
    </changeSet>

Solution: 
correct the type of table B to bigint because the referenced table has type bigint.

Scenrario 2:
The type might be correct but the size might not.
e.g. :
Table B : referenced column type="varchar 50"
Table A : base column type ="varchar 255"

Solution change the size of referenced column to that of base table's column size.
kathait cinza
fonte
0

Verifique se você especificou o nome da tabela no caso apropriado (se os nomes de tabela diferenciam maiúsculas de minúsculas no seu banco de dados). No meu caso eu tive que mudar

 CONSTRAINT `FK_PURCHASE_customer_id` FOREIGN KEY (`customer_id`) REFERENCES `customer` (`id`) ON UPDATE CASCADE ON DELETE CASCADE

para

 CONSTRAINT `FK_PURCHASE_customer_id` FOREIGN KEY (`customer_id`) REFERENCES `CUSTOMER` (`id`) ON UPDATE CASCADE ON DELETE CASCADE

observe o customeralterado para CUSTOMER.

izogfif
fonte
0

Ou você pode usar o DBDesigner4, que possui uma interface gráfica para criar seu banco de dados e vinculá-los usando o FK. Clique com o botão direito na sua tabela e selecione 'Copy Table SQL Create', que cria o código.

insira a descrição da imagem aqui

Dexter
fonte
0

É um assunto antigo, mas eu descobri algo. Ao construir um ambiente de trabalho MySQL, ele também obtém os relacionamentos da outra tabela. apenas deixe os pilares com os quais você se relaciona. Limpe outras colunas adicionadas automaticamente. Isso funciona para mim.

Muhammed Alper Uslu
fonte
0

Meu caso foi que eu cometi um erro de digitação na coluna referida:

MariaDB [blog]> alter table t_user add FOREIGN KEY ( country_code ) REFERENCES t_country ( coutry_code );
ERROR 1005 (HY000): Can't create table `blog`.`t_user` (errno: 150 "Foreign key constraint is incorrectly formed")

A mensagem de erro é bastante enigmática e eu tentei de tudo - verificando os tipos de colunas, agrupamentos, mecanismos etc.

Levei algum tempo para observar o erro de digitação e depois de corrigir tudo funcionou bem:

MariaDB [blog]> alter table t_user add FOREIGN KEY ( country_code ) REFERENCES t_country ( country_code );
Query OK, 2 rows affected (0.039 sec)              
Records: 2  Duplicates: 0  Warnings: 0
Delian Krustev
fonte
0

Eu enfrento esse problema, o erro veio quando você colocou a chave primária em diferentes tipos de dados como:

tabela 1:

 Schema::create('products', function (Blueprint $table) {
            $table->increments('id');
            $table->string('product_name');
        });

mesa 2:

Schema::create('brands', function (Blueprint $table) {
            $table->bigIncrements('id');
            $table->string('brand_name');
        });

o tipo de dados para o ID da segunda tabela deve ser incrementado

shaher11
fonte
0

O problema é muito simples de resolver

por exemplo: você tem duas tabelas com nomes de usuários e postagens e deseja criar chave estrangeira na tabela de postagens e usa o phpMyAdmin

1) na tabela de postagem, adicione uma nova coluna ( nome : use_id | tipo : como o ID na tabela do usuário | Comprimento : como o ID na tabela do usuário | Padrão : NULL | Atributos : sem sinal | Índice: INDEX)

2) na guia Estrutura, vá para a exibição de relação ( Nome da restrição : definido automaticamente pelo phpmyAdmin | nome da coluna : selecione user_id | tabela : usuários | chave : id, ...)

Foi simplesmente resolvido

javad mosavi Irã / urmia

Javad mosavi
fonte