MySQL: Não é possível criar a tabela (número do erro: 150)


156

Estou tentando importar um arquivo .sql e sua falha na criação de tabelas.

Aqui está a consulta que falha:

CREATE TABLE `data` (
`id` int(10) unsigned NOT NULL,
`name` varchar(100) NOT NULL,
`value` varchar(15) NOT NULL,
UNIQUE KEY `id` (`id`,`name`),
CONSTRAINT `data_ibfk_1` FOREIGN KEY (`id`) REFERENCES `keywords` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=latin1;    

Exportei o .sql do mesmo banco de dados, deixei cair todas as tabelas e agora estou tentando importá-lo, por que está falhando?

MySQL: Não é possível criar a tabela './dbname/data.frm' (errno: 150)


1
Para essencialmente todas as causas desse erro, aqui está um recurso exaustivo para o que causa o erro 150 (e erro 121 / outros erros de chave estrangeira) no MySQL.
John Smith

21
Descobri que as colunas devem ser idênticas (até o sinalizador não assinado deve corresponder).
quer tocar hoje? Justin Skiles:

3
@JohnSmith ... onde?
Charles Wood

3
Eu sugiro a leitura deste post que as listas 10 possíveis causas: verysimple.com/2006/10/22/...
Mark Amery

@CharlesWood: " John Smith ... visto em 6 de abril de 13 às 19:29 ", isso é cerca de três meses antes do seu comentário. Eu tenho medo, que um mistério de "onde" não seja revelado até o fim deste mundo tedioso! :>
Trejder

Respostas:


167

Da documentação das restrições MySQL - FOREIGN KEY :

Se você recriar uma tabela que foi eliminada, ela deverá ter uma definição que esteja em conformidade com as restrições de chave estrangeira que a referenciam. Ele deve ter os nomes e tipos de coluna corretos, e deve ter índices nas chaves referenciadas, conforme declarado anteriormente. Se isso não for satisfeito, o MySQL retornará o Erro 1005 e se referirá ao Erro 150 na mensagem de erro, o que significa que uma restrição de chave estrangeira não foi formada corretamente. Da mesma forma, se uma ALTER TABLE falhar devido ao Erro 150, isso significa que uma definição de chave estrangeira seria incorretamente formada para a tabela alterada.


1
Duas colunas de uma tabela podem fazer referência a uma coluna de outra tabela, onde está o PK?
Eugene #

1
@ Eugene: Cada uma das duas colunas pode ter um relacionamento de chave estrangeira com o PK em outra tabela - não as duas colunas como um único relacionamento de chave estrangeira.
OMG Ponies

1
@OMGPonies: Obrigado por responder a esta pergunta! .. Eu estava procurando ... Também fiz uma pergunta aqui stackoverflow.com/questions/13487010/… .... Embora eu tenha boas respostas, mas quero estar em conformidade Whether its possible to write Nested Query for my problem? ..Eu pediria que você por favor me responda também!
Grijesh Chauhan

19
Meu erro foi a tabela mestre com o mecanismo MyISAM e a tabela filho InnoDB. O script create.sql atual estava usando o InnoDB para todas as tabelas, mas eu tinha uma instalação muito antiga onde o primeiro script usava o MyISAM.
whome

2
@Whome - Sim, correu para o mesmo problema aqui.
Aroth # 28/13

96

Erro 150 significa que você tem um problema com sua chave estrangeira. Possivelmente a chave na tabela estrangeira não é exatamente o mesmo tipo?


15
Obrigado :) para mim, os tipos de dados são INT mas não assinado, enquanto o outro não é
Anh Nguyen

6
Costumo atravessar BIGINTvs INTao usar geradores de esquema.
Xeoncross

Corri para o mesmo problema quando a chave estrangeira não é o valor INT. A coluna deve ser ÚNICA quando a chave estrangeira se refere a ela.
PhatHV

62

Você pode receber a mensagem de erro real executando SHOW ENGINE INNODB STATUS;e procurando LATEST FOREIGN KEY ERRORna saída.

Fonte: resposta de outro usuário em uma pergunta semelhante


7
Isso é realmente muito útil. Indica o erro exato.
Csongor Fagyal

obrigado. É uma pena que o MySQL Workbench não faça uso disso.
Scipilot

Impressionante. Isso é muito útil. Informa o erro exato. O meu era, por ter tornado a coluna NULLABLE, mas definido "no conjunto de exclusões nulo". Muito obrigado.
Abhishek Saini

Se você tem privilégios no seu servidor :(
Christopher Smit

30

Os tipos de dados devem corresponder exatamente. Se você estiver lidando com tipos varchar, as tabelas deverão usar o mesmo agrupamento.


4
Obrigado pelo pouco agrupamento.
arahant

25

Eu acho que todas essas respostas, enquanto corretas, são enganosas para a pergunta.

A resposta real é esta antes de iniciar uma restauração, se você estiver restaurando um arquivo de despejo com chaves estrangeiras:

SET FOREIGN_KEY_CHECKS=0;

porque, naturalmente, a restauração criará algumas restrições antes que a tabela externa exista.


Fazer isso não funcionou para mim, ainda dá o erro. Alguma ideia?
Joseph Astrahan

24

Em alguns casos, você pode encontrar essa mensagem de erro se houver mecanismos diferentes entre as tabelas relacionadas. Por exemplo, uma tabela pode estar usando o InnoDB enquanto a outra usa o MyISAM. Ambos precisam ser iguais


Obrigado - este foi o meu problema.
Scipilot #

Esse foi o meu problema. Obrigado
thed0ctor

Isso pode acontecer se você criou um arquivo sql da tabela innodb usando o mysqldump e eles foram exportados como talis do myisam.
Amado Martinez

11

Erro no. 150 significa uma falha de restrição de chave estrangeira. Você provavelmente está criando esta tabela antes da tabela da qual a chave estrangeira depende (tabela keywords). Crie essa tabela primeiro e deve funcionar bem.

Caso contrário, remova a instrução de chave estrangeira e adicione-a após a criação da tabela - você receberá uma mensagem de erro mais significativa sobre a falha de restrição específica.


10

Existem algumas coisas que podem causar o erro 150, portanto, para as pessoas que pesquisam neste tópico, aqui está o que eu acho que é uma lista quase exaustiva (fonte Causes of Errno 150 ):

Para o erro 150 ou o erro 121, basta digitar SHOW ENGINE INNODB STATUS, existe uma seção chamada "ÚLTIMO ERRO DE CHAVE ESTRANGEIRA". Com isso, será exibida uma mensagem de erro muito útil, que normalmente informa imediatamente qual é o problema. Você precisa de privilégios SUPER para executá-lo; portanto, se você não tiver isso, precisará apenas testar os seguintes cenários.

1) Os tipos de dados não correspondem: os tipos das colunas devem ser os mesmos

2) Colunas pai não indexadas (ou indexadas por ordem incorreta)

3) Os agrupamentos de colunas não correspondem

4) Usando SET NULL em uma coluna NOT NULL

5) Os agrupamentos de tabelas não correspondem: mesmo que os agrupamentos de colunas correspondam, em algumas versões do MySQL isso pode ser um problema.

6) A coluna pai não existe realmente na tabela pai. Verificar ortografia (e talvez um espaço no início ou no final da coluna)

7) Um dos índices em uma das colunas está incompleto ou a coluna é muito longa para um índice completo. Observe que o MySQL (a menos que você o ajuste) possui um comprimento máximo de chave de coluna única de 767 bytes (isso corresponde a uma coluna UTF varchar (255))

Caso você receba um erro 121, eis algumas causas:

1) O nome da restrição que você escolheu já está em uso

2) Em alguns sistemas, se houver uma diferença entre maiúsculas e minúsculas nos seus extratos e nomes de tabelas. Isso pode incomodá-lo se você for de um servidor para outro que possua regras de tratamento de casos diferentes.


Em algumas versões, você recebe um erro 150 se a tabela não for innodb, mas em algumas versões ela falha silenciosamente.
juacala

Obrigado, isso foi ótimo: | ------------------------ | ÚLTIMO ERRO DE CHAVE ESTRANGEIRA | ------------------------ | Você definiu uma condição SET NULL através de algumas das | colunas são definidas como NOT NULL.
Sam Critchley

8

Às vezes o MySQL é simplesmente super estúpido - eu posso entender a causa da causa de chaves estrangeiras .. mas no meu caso, acabei de soltar o banco de dados inteiro e ainda recebo o erro ... por que? quer dizer, não há mais banco de dados ... e o usuário sql que estou usando não tem acesso a nenhum outro banco de dados no servidor ... quero dizer, o servidor está "vazio" para o usuário atual e ainda recebo esse erro? Desculpe, mas acho que o MySQL está mentindo para mim ... mas posso lidar com isso :) Basta adicionar essas duas linhas de SQL em torno da sua declaração fucky:

SET FOREIGN_KEY_CHECKS = 0;
# some code that gives you errno: 150
SET FOREIGN_KEY_CHECKS = 1;

Agora o sql deve ser executado ... Se você realmente tiver um problema de chave estrangeira, ele aparecerá na linha em que você habilitará as verificações novamente - isso falhará então .. mas meu servidor está quieto :)


Isso pode causar problemas se houver realmente diferenças entre a coluna e a coluna à qual ela está fazendo referência. Por exemplo. Digamos que a coluna referenciada seja um varchar (200) e o referenciador seja varchar (50), quando uma tentativa de cascata pode ocorrer um comportamento estranho. Não encontrei um problema em que o erro 150 seja emitido devido à incompatibilidade de dados.
21715 juacala

Interessante visão @juacala :) engraçado para mim é única, sempre que eu corri para este, a minha abordagem sempre fixa-lo ... até hoje, pelo menos: D Mas nós aprendizagem nunca parar, certo;)
jebbie

Isso realmente me ajudou com um script liquibase gerado. O script funcionou perfeitamente no MySQL> 5.5, mas falhou na versão 5.1.
delbertooo

4

Após percorrer as respostas acima e experimentar um pouco, esta é uma maneira eficaz de resolver erros de chave estrangeira no MySQL (1005 - erro 150).

Para que a chave estrangeira seja criada corretamente, tudo o que o MySQL pede é:

  • Todas as chaves referenciadas DEVEM ter índice PRIMARY ou UNIQUE.
  • Referenciar a coluna novamente DEVE ter um tipo de dados idêntico ao da coluna referenciada.

Satisfaça esses requisitos e tudo ficará bem.


4

Eu experimentei esse erro ao portar o aplicativo Windows para Linux. No Windows, os nomes de tabela de banco de dados não diferenciam maiúsculas de minúsculas e, no Linux, diferenciam maiúsculas de minúsculas, provavelmente por causa da diferença no sistema de arquivos. Portanto, na tabela do Windows Table1é o mesmo que table1, e em REFERENCESambos table1e Table1funciona. No Linux, quando o aplicativo era usado em table1vez de Table1quando ele criou a estrutura do banco de dados, vi o erro nº 150; quando eu fiz o caso correto de caracteres nas Table1referências, ele também começou a funcionar no Linux. Portanto, se nada mais ajudar, certifique- REFERENCESse de usar maiúsculas e minúsculas nos caracteres da tabela quando estiver no Linux.


Este também foi o meu caso! Movendo o script de uma versão que diferencia maiúsculas de minúsculas (OS X) para uma versão mysql que diferencia maiúsculas de minúsculas (Debian).
mircealungu

3

Mude os mecanismos de suas tabelas, apenas o innoDB suporta chaves estrangeiras


3

Se a tabela PK for criada em um CHARSET e você criar a tabela FK em outro CHARSET ... então também poderá receber esse erro ... Eu também recebi esse erro, mas depois de alterar o charset para PK charset, ele foi executado sem erros

create table users
(
------------
-------------
)DEFAULT CHARSET=latin1;


create table Emp
(
---------
---------
---------
FOREIGN KEY (userid) REFERENCES users(id) on update cascade on delete cascade)ENGINE=InnoDB, DEFAULT CHARSET=latin1;

3

Este erro pode ocorrer se duas tabelas tiverem uma referência, por exemplo, uma tabela é Student e outra tabela é Education, e queremos que a tabela Education tenha uma referência de chave estrangeira da tabela Student. Nesse caso, o tipo de dados da coluna para as duas tabelas deve ser o mesmo, caso contrário, irá gerar um erro.


3

Na maioria dos casos, o problema é causado pela diferença de ENGINE. Se o pai é criado pelo InnoDB, as tabelas referenciadas que devem ser criadas pelo MyISAM e vice-versa


3

No meu caso. Eu tive problemas com o mecanismo e o conjunto de caracteres, porque meu servidor Hosting alterou as configurações e minhas novas tabelas eram MyISAM, mas minhas tabelas antigas são o InnoDB. Apenas eu mudei.


Isso foi certo para mim, porque eu estava alterando um banco de dados não criado por mim.
FonzTech 13/0618

3

geralmente, a incompatibilidade entre chave estrangeira e chave primária causa o erro: 150.

A chave estrangeira deve ter o mesmo tipo de dados que a chave primária . Além disso, se a chave primária não estiver assinada , a chave estrangeira também deverá ser não assinada .


3

Eu tive o mesmo problema. Foi relacionado à coluna da tabela Agrupamento e conjunto de caracteres . Verifique se o conjunto de caracteres e o agrupamento devem ser iguais para as duas colunas em duas tabelas. Se você deseja definir uma chave estrangeira nisso. Exemplo - Se você colocar a chave estrangeira na coluna userID da tabela userImage, referenciando a coluna userID da tabela users.Then Collation deve ser o mesmo utf8_general_ci e o conjunto de caracteres utf8 para as duas colunas das tabelas. Geralmente, quando você cria uma tabela, o mysql pega essas duas configurações nas configurações do servidor.


Por que eu não vi esse poist antes !? Passei uma hora descobrindo a causa raiz. Foi o conjunto de caracteres no meu caso. As tabelas referenciadas e de referência devem ter o mesmo conjunto de caracteres.
Sujit Joshi 26/09

2

Verifique se a coluna da chave primária e a coluna referenciada têm os mesmos tipos e atributos de dados (zerofill não assinado, binário, não assinado etc).


2

Um caso real é onde você usou uma ferramenta MySQL (Sequel Pro no meu caso) para renomear um banco de dados. Em seguida, criou um banco de dados com o mesmo nome.

Isso mantinha as restrições de chave estrangeira com o mesmo nome do banco de dados; portanto, o banco de dados renomeado (por exemplo, my_db_renamed) tinha restrições de chave estrangeira no banco de dados recém-criado (my_db)

Não tenho certeza se isso é um bug no Sequel Pro ou se algum caso de uso exige esse comportamento, mas isso me custou a maior parte da manhã: /


2

Eu tive o mesmo erro. No meu caso, o motivo do erro foi que eu tinha uma instrução ON DELETE SET NULL na restrição, enquanto o campo no qual eu coloquei a restrição em sua definição tinha uma instrução NOT NULL. Permitir NULL no campo resolveu o problema.


2

Eu enfrentei esse tipo de problema ao criar o banco de dados a partir do arquivo de texto.

mysql -uroot -padmin < E:\important\sampdb\createdb.sql
mysql -uroot -padmin sampdb < E:\important\sampdb\create_student.sql
mysql -uroot -padmin sampdb < E:\important\sampdb\create_absence.sql

mysql -uroot -padmin sampdb < E:\important\sampdb\insert_student.sql
mysql -uroot -padmin sampdb < E:\important\sampdb\insert_absence.sql

mysql -uroot -padmin sampdb < E:\important\sampdb\load_student.sql
mysql -uroot -padmin sampdb < E:\important\sampdb\load_absence.sql 

Acabei de escrever as linhas acima Create.bate executar o arquivo bat.

Meu erro está na ordem de execução da sequência nos meus arquivos sql. Eu tentei criar tabela com chave primária e também chave estrangeira. Enquanto estiver em execução, ele procurará a tabela de referência, mas as tabelas não estão lá. Portanto, ele retornará esse tipo de erro.

Se você estiver criando tabelas com chave estrangeira, verifique se as tabelas de referência estavam presentes ou não. E também verifique o nome das tabelas e campos de referência.


Em outras palavras, você tentou criar uma tabela com uma chave estrangeira apontando para outra tabela que ainda não existia. Crie as tabelas na ordem correta para resolver o problema.
Vincent

2

Eu tive um problema semelhante, mas o meu era porque eu estava adicionando um novo campo a uma tabela existente que tinha dados, e o novo campo referenciava outro campo da tabela pai e também tinha a definição de NOT NULL e sem nenhum valor padrão. - Eu descobri que as coisas não estavam funcionando porque

  1. Meu novo campo precisava preencher automaticamente os campos em branco com um valor da tabela pai em cada registro, antes que a restrição pudesse ser aplicada. Sempre que a restrição é aplicada, é necessário deixar intacta a integridade dos dados da tabela. Implementando a restrição (chave estrangeira), ainda assim, havia alguns registros de banco de dados que não tinham os valores da tabela pai, o que significa que os dados estão corrompidos, portanto o MySQL NUNCA EXECUUU A SUA RESTRIÇÃO

É importante lembrar que, em circunstâncias normais, se você planejou seu banco de dados com bastante antecedência e implementou restrições antes da inserção dos dados, esse cenário específico seria evitado

A abordagem mais fácil de evitar esse problema é

  • Salve os dados das tabelas do banco de dados
  • Truncar os dados da tabela (e artefatos da tabela, por exemplo, índices etc.)
  • Aplique as restrições
  • Importar seus dados

Espero que isso ajude alguém


1

Talvez isso ajude? A definição da coluna da chave primária deve ser exatamente a mesma da coluna da chave estrangeira.


1

Certifique-se de que todas as tabelas possam suportar chave estrangeira - mecanismo InnoDB


1

A coluna da tabela PARENT à qual você está se referindo na tabela filho deve ser exclusiva. Caso contrário, cause um erro no 150.


provavelmente valeria a pena adicionar um pouco mais detalhadamente - por exemplo, os nomes específicos de colunas e tabelas #
Jonathan Jonathan

1

Eu tive um problema semelhante ao despejar um banco de dados mysql do Django com uma única tabela. Consegui consertar o problema despejando o banco de dados em um arquivo de texto, movendo a tabela em questão para o final do arquivo usando o emacs e importando o arquivo sql dump modificado para a nova instância.

HTH Uwe


1

Corrigi o problema fazendo a variável aceitar null

ALTER TABLE `ajout_norme` 
CHANGE `type_norme_code` `type_norme_code` VARCHAR( 2 ) CHARACTER SET utf8 COLLATE utf8_general_ci NULL

1

Eu tive o mesmo problema ao executar uma série de comandos do MySQL. O meu ocorre durante a criação de uma tabela ao fazer referência a uma chave estrangeira a outra tabela que ainda não foi criada. É a sequência da existência da tabela antes da referência.

A solução: primeiro crie as tabelas pai antes de criar uma tabela filha que tenha uma chave estrangeira.


1

Crie a tabela sem chave estrangeira e defina a chave estrangeira separadamente.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.