Adicionar chave estrangeira à tabela existente

324

Eu quero adicionar uma chave estrangeira a uma tabela chamada "katalog".

ALTER TABLE katalog 
ADD CONSTRAINT `fk_katalog_sprache` 
FOREIGN KEY (`Sprache`)
REFERENCES `Sprache` (`ID`)
ON DELETE SET NULL
ON UPDATE SET NULL;

Quando tento fazer isso, recebo esta mensagem de erro:

Error Code: 1005. Can't create table 'mytable.#sql-7fb1_7d3a' (errno: 150)

Erro no status INNODB:

120405 14:02:57 Erro na restrição de chave estrangeira da tabela mytable. # Sql-7fb1_7d3a:

FOREIGN KEY (`Sprache`)
REFERENCES `Sprache` (`ID`)
ON DELETE SET NULL
ON UPDATE SET NULL:
Cannot resolve table name close to:
(`ID`)
ON DELETE SET NULL
ON UPDATE SET NULL

Quando uso essa consulta, ela funciona, mas com a ação "ao excluir" incorreta:

ALTER TABLE `katalog` 
ADD FOREIGN KEY (`Sprache` ) REFERENCES `sprache` (`ID` )

Ambas as tabelas são InnoDB e os dois campos são "INT (11) não nulos". Estou usando o MySQL 5.1.61. Tentando disparar essa consulta ALTER com o MySQL Workbench (mais recente) em um MacBook Pro.

Tabela Criar instruções:

CREATE TABLE `katalog` (
`ID` int(11) unsigned NOT NULL AUTO_INCREMENT,
`Name` varchar(50) COLLATE utf8_unicode_ci NOT NULL,
`AnzahlSeiten` int(4) unsigned NOT NULL,
`Sprache` int(11) NOT NULL,
PRIMARY KEY (`ID`),
UNIQUE KEY `katalogname_uq` (`Name`)
 ) ENGINE=InnoDB AUTO_INCREMENT=12 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci ROW_FORMAT=DYNAMIC$$

CREATE TABLE `sprache` (
`ID` int(11) NOT NULL AUTO_INCREMENT,
 `Bezeichnung` varchar(45) NOT NULL,
 PRIMARY KEY (`ID`),
 UNIQUE KEY `Bezeichnung_UNIQUE` (`Bezeichnung`),
KEY `ix_sprache_id` (`ID`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8
frgtv10
fonte
1
Como você não publicou a saída de SHOW CREATE TABLE, só posso perguntar - o nome da coluna é realmente ID, em maiúsculas?
NB
Bem, é mais fácil identificar agora - katalogtem int(11) unsigned. sprachenão possui a usignedpeça, portanto, duas colunas não são iguais.
NB
Você quer dizer que os dois campos Primários devem ser do mesmo tipo de dados?
Frgtv10
2
Esse é o problema do seu design: primeiro, você está referenciando duas auto_incrementcolunas, o que é ruim. Além disso, o manual MySQL diz: Corresponding columns in the foreign key and the referenced key must have similar internal data types inside InnoDB so that they can be compared without a type conversion. The size and sign of integer types must be the same. The length of string types need not be the same. For nonbinary (character) string columns, the character set and collation must be the same.. Portanto, sim, tipo de dados semelhante e o mesmo sinal.
NB
2
Não estou fazendo referência a dois campos de incremento automático. katalog.Sprache (não automático) -> sprache.ID (auto)
frgtv10

Respostas:

560

Para adicionar uma chave estrangeira (grade_id) a uma tabela existente (usuários), siga as seguintes etapas:

ALTER TABLE users ADD grade_id SMALLINT UNSIGNED NOT NULL DEFAULT 0;
ALTER TABLE users ADD CONSTRAINT fk_grade_id FOREIGN KEY (grade_id) REFERENCES grades(id);
iltaf khalid
fonte
12
Os motivos me ajudam a entender e lembrar. Isso ocorre porque você não pode adicionar uma chave estrangeira a um campo não assinado, correto?
precisa saber é o seguinte
8
@PixMach, a resposta é não. Você pode ter números inteiros assinados como chaves estrangeiras. Como NB observou na pergunta, o tipo e o sinal dos campos precisam corresponder. Portanto, se sua chave primária na tabela de pesquisa for UNSIGNED, o campo de chave estrangeira também deverá ser UNSIGNED. Se o campo da chave primária for ASSINADO, o campo da chave estrangeira também deverá ser assinado. Pense desta maneira: qualquer que seja a coluna da tabela definida como em SHOW CREATE TABLE, ela precisa ter a mesma definição na outra tabela.
Ben Keene
1
Note-se que isso também poderia ser feito com uma única consulta (pode ser melhor em caso de falha etc)
Stijn de Witt
6
Eu tive que executar "SET FOREIGN_KEY_CHECKS = 0;" antes de executar o comando ADD CONSTRAINT, ou o SQL reclamaria "Não é possível adicionar ou atualizar uma linha filho: uma restrição de chave estrangeira falha".
Erin Geyer
2
Você não basta executar "SET FOREIGN_KEY_CHECKS = 0;" se você receber o erro "uma restrição de chave estrangeira falhar", obviamente você tem dados incorretos que devem ser corrigidos ou então você terá problemas maiores posteriormente.
MazeChaZer
72

Basta usar esta consulta, tentei de acordo com o meu cenário e funciona bem

ALTER TABLE katalog ADD FOREIGN KEY (`Sprache`) REFERENCES Sprache(`ID`);
SagarPPanchal
fonte
25

Passos simples ...

ALTER TABLE t_name1 ADD FOREIGN KEY (column_name) REFERENCES t_name2(column_name)
Amjath Khan
fonte
15

verifique este link. Ele me ajudou com o errno 150: http://verysimple.com/2006/10/22/mysql-error-number-1005-cant-create-table-mydbsql-328_45frm-errno-150/

No topo da minha cabeça, duas coisas me vêm à mente.

  • O seu índice de chave estrangeira é um nome exclusivo em todo o banco de dados (nº 3 da lista)?
  • Você está tentando definir a tabela PK como NULL na atualização (# 5 na lista)?

Eu estou supondo que o problema está com o conjunto NULL na atualização (se meu cérebro não estiver invertido hoje, como costuma ser ...).

Editar: perdi os comentários em sua postagem original. As colunas int não assinadas / não assinadas talvez tenham resolvido seu caso. Espero que meu link ajude alguém no futuro a pensar.

ZZ-bb
fonte
13
FOREIGN KEY (`Sprache`)
REFERENCES `Sprache` (`ID`)
ON DELETE SET NULL
ON UPDATE SET NULL;

Mas sua mesa possui:

CREATE TABLE `katalog` (
`Sprache` int(11) NOT NULL,

Ele não pode definir a coluna Sprache para NULL porque ele é definido como NOT NULL.

Conta
fonte
5

O MySQL executará esta consulta:

ALTER TABLE `db`.`table1`
ADD COLUMN `col_table2_fk` INT UNSIGNED NULL,
ADD INDEX `col_table2_fk_idx` (`col_table2_fk` ASC),
ADD CONSTRAINT `col_table2_fk1`
FOREIGN KEY (`col_table2_fk`)
REFERENCES `db`.`table2` (`table2_id`)
ON DELETE NO ACTION
ON UPDATE NO ACTION;

Felicidades!

akelec
fonte
5

Como consertar Error Code: 1005. Can't create table 'mytable.#sql-7fb1_7d3a' (errno: 150) in mysql.

  1. altere sua tabela e adicione um índice a ela ..

    ALTER TABLE users ADD INDEX index_name (index_column)
  2. Agora adicione a restrição

    ALTER TABLE foreign_key_table
    ADD CONSTRAINT foreign_key_name FOREIGN KEY (foreign_key_column)
    REFERENCES primary_key_table (primary_key_column) ON DELETE NO ACTION
    ON UPDATE CASCADE;

Observe que se você não adicionar um índice, ele não funcionará.

Depois de lutar por cerca de 6 horas, tive a solução que espero que isso salve uma alma.

Kwed
fonte
4

Ao adicionar uma restrição de chave estrangeira a uma tabela usando ALTER TABLE, lembre-se de criar os índices necessários primeiro.

  1. Criar índice
  2. Alterar a tabela
Maksym Polshcha
fonte
Eu criei o índice para ambos. Quando tento executar, recebo a mesma mensagem de erro de antes. Quando eu assumem a parte "na exclusão na atualização" ele funciona, mas com o errado "na exclusão" ação;)
frgtv10
@ frgtv10 o mais provável é que os dados da tabela entrem em conflito com "ao excluir".
Maksym Polshcha
3

tente tudo em uma consulta

  ALTER TABLE users ADD grade_id SMALLINT UNSIGNED NOT NULL DEFAULT 0,
      ADD CONSTRAINT fk_grade_id FOREIGN KEY (grade_id) REFERENCES grades(id);
manoj
fonte
0

isso acontece basicamente porque suas tabelas estão em dois conjuntos de caracteres diferentes. como exemplo, uma tabela criada em charset = utf-8 e outras tabelas são criadas em CHARSET = latin1, para que você possa adicionar uma chave obrigatória a essas tabelas. Se você usar o mesmo conjunto de caracteres nas duas tabelas, poderá adicionar chaves estrangeiras. O erro 1005 restrição de chave estrangeira formada incorretamente pode resolver a partir deste

Pumudu Fernando
fonte
0

eu passei pelo mesmo problema. No meu caso, a tabela já possui dados e havia chave nessa tabela que não estava presente na tabela de referência. Então eu tive que excluir essas linhas que desrespeitam as restrições e tudo funcionou.

Henrique
fonte
0

etapa 1: execute este script

SET FOREIGN_KEY_CHECKS=0;

etapa 2: adicionar coluna

ALTER TABLE mileage_unit ADD COLUMN COMPANY_ID BIGINT(20) NOT NULL

Etapa 3: adicionar chave estrangeira à coluna adicionada

ALTER TABLE mileage_unit
ADD FOREIGN KEY (COMPANY_ID) REFERENCES company_mst(COMPANY_ID);

etapa 4: execute este script

SET FOREIGN_KEY_CHECKS=1;
rushikesh satpute
fonte
-1
 ALTER TABLE TABLENAME ADD FOREIGN KEY (Column Name) REFERENCES TableName(column name)

Exemplo:-

ALTER TABLE Department ADD FOREIGN KEY (EmployeeId) REFERENCES Employee(EmployeeId)
Harshitha Nagabhushana
fonte
1
Por favor, adicione um pouco de explicação ao seu código de tal forma que outros possam aprender com ele
Nico Haase