Pergunta

Estou fazendo um pequeno banco de dados com MySQL Workbench.Tenho uma tabela principal, chamada "Immobili", que possui uma Chave Primária composta por quatro colunas:(Comune, Via, Cívico, Imóvel).

Agora, tenho também outras três tabelas, que possuem a mesma chave primária (Comune, Via, Civico, Immobile), mas estes campos também estão referenciados à tabela Immobili.

Primeira pergunta:Posso criar uma chave primária que também seja uma chave estrangeira?

Segunda questão:Quando tento exportar as alterações aparece:Executando script SQL no servidor

# ERROR: Error 1005: Can't create table 'dbimmobili.condoni' (errno: 150)

CREATE  TABLE IF NOT EXISTS `dbimmobili`.`Condoni` (

  `ComuneImmobile` VARCHAR(50) NOT NULL ,
  `ViaImmobile` VARCHAR(50) NOT NULL ,
  `CivicoImmobile` VARCHAR(5) NOT NULL ,
  `InternoImmobile` VARCHAR(3) NOT NULL ,
  `ProtocolloNumero` VARCHAR(15) NULL ,
  `DataRichiestaSanatoria` DATE NULL ,
  `DataSanatoria` DATE NULL ,
  `SullePartiEsclusive` TINYINT(1) NULL ,
  `SullePartiComuni` TINYINT(1) NULL ,
  `OblazioneInEuro` DOUBLE NULL ,
  `TecnicoOblazione` VARCHAR(45) NULL ,
  `TelefonoTecnico` VARCHAR(15) NULL ,
  INDEX `ComuneImmobile` (`ComuneImmobile` ASC) ,
  INDEX `ViaImmobile` (`ViaImmobile` ASC) ,
  INDEX `CivicoImmobile` (`CivicoImmobile` ASC) ,
  INDEX `InternoImmobile` (`InternoImmobile` ASC) ,

  PRIMARY KEY (`ComuneImmobile`, `ViaImmobile`, `CivicoImmobile`, `InternoImmobile`) ,

  CONSTRAINT `ComuneImmobile`
    FOREIGN KEY (`ComuneImmobile` )
    REFERENCES `dbimmobili`.`Immobile` (`ComuneImmobile` )
    ON DELETE CASCADE
    ON UPDATE CASCADE,

  CONSTRAINT `ViaImmobile`
    FOREIGN KEY (`ViaImmobile` )
    REFERENCES `dbimmobili`.`Immobile` (`ViaImmobile` )
    ON DELETE CASCADE
    ON UPDATE CASCADE,

  CONSTRAINT `CivicoImmobile`
    FOREIGN KEY (`CivicoImmobile` )
    REFERENCES `dbimmobili`.`Immobile` (`CivicoImmobile` )
    ON DELETE CASCADE
    ON UPDATE CASCADE,

  CONSTRAINT `InternoImmobile`
    FOREIGN KEY (`InternoImmobile` )
    REFERENCES `dbimmobili`.`Immobile` (`InternoImmobile` )
    ON DELETE CASCADE
    ON UPDATE CASCADE
) ENGINE = InnoDB

Mostrando o status do motor:

Erro na restrição de chave estrangeira da tabela dbimmobili/valutazionimercato:

Não é possível encontrar um índice na tabela referenciada em que as colunas referenciadas apareçam como as primeiras colunas, ou as colunas digitam na tabela e a tabela referenciada não corresponde à restrição.Observe que o tipo de armazenamento interno de enumeração e conjunto alterado nas tabelas criadas com> = innodb-4.1.12, e essas colunas em tabelas antigas não podem ser referenciadas por essas colunas em novas tabelas.

Onde estou fazendo errado?

Foi útil?

Solução

Ao criar uma restrição de chave estrangeira, o MySQL requer um índice utilizável na tabela de referência e também na tabela referenciada. O índice na tabela de referência é criado automaticamente se não existir, mas o da tabela referenciado precisa ser criado manualmente (Fonte). O seu parece estar faltando.

Caso de teste:

CREATE TABLE tbl_a (
    id int PRIMARY KEY,
    some_other_id int,
    value int
) ENGINE=INNODB;
Query OK, 0 rows affected (0.10 sec)

CREATE TABLE tbl_b (
    id int PRIMARY KEY,
    a_id int,
    FOREIGN KEY (a_id) REFERENCES tbl_a (some_other_id)
) ENGINE=INNODB;
ERROR 1005 (HY000): Can't create table 'e.tbl_b' (errno: 150)

Mas se adicionarmos um índice em some_other_id:

CREATE INDEX ix_some_id ON tbl_a (some_other_id);
Query OK, 0 rows affected (0.11 sec)
Records: 0  Duplicates: 0  Warnings: 0

CREATE TABLE tbl_b (
    id int PRIMARY KEY,
    a_id int,
    FOREIGN KEY (a_id) REFERENCES tbl_a (some_other_id)
) ENGINE=INNODB;
Query OK, 0 rows affected (0.06 sec)

Isso geralmente não é um problema na maioria das situações, uma vez que o campo referenciado geralmente é a chave primária da tabela referenciada e a chave primária é indexada automaticamente.

Outras dicas

Verifique se as chaves estrangeiras têm exatamente o mesmo tipo do campo que você tem nesta tabela. Por exemplo, ambos devem ser inteiros (10) ou Varchar (8), mesmo o número de caracteres.

Sei que este é um post antigo, mas está no Google, então estou adicionando o que descobri para o meu problema. Se você tiver uma mistura de tipos de tabela (por exemplo, Myisam e Innodb), também receberá esse erro. Nesse caso, o InnoDB é o tipo de tabela padrão, mas uma tabela precisava de pesquisa completa do FullText para que fosse migrado para Myisam. Nesta situação, você não pode criar uma chave estrangeira na tabela Innodb que referencia a tabela Myisam.

Se sua chave for um char/varchar ou algo desse tipo, outro problema possível é um agrupamento diferente. Verifique se o charset é o mesmo.

Eu tive esse erro e descobri o motivo do erro no meu caso.Ainda estou respondendo a esta postagem antiga porque ela está bem posicionada no Google.

As variáveis ​​de ambas as colunas que eu queria vincular eram números inteiros, mas um dos ints estava marcado como 'unsigned'.Simplesmente desmarcar isso corrigiu meu erro.

Eu estava recebendo um mesmo erro. Descobri a solução que eu havia criado a chave primária na tabela principal como Bigint não assinada e estava declarando -a como uma chave estrangeira na segunda tabela como apenas Bigint.

Quando declarei minha chave estrangeira como Bigint não é a segunda tabela, tudo funcionou bem, mesmo não precisava de índices para serem criados.

Por isso, foi uma incompatibilidade de dados de dados entre a chave primária e a chave estrangeira :)

Eu tive exatamente o mesmo problema, mas a solução para o meu problema era totalmente diferente. Eu tinha, em outro lugar no banco de dados, uma chave estrangeira com o mesmo nome. Isso causou o erro 1005.

Renomear minha chave estrangeira para algo mais específico para essa situação resolveu o problema.

  1. Verifique se as duas tabelas estão usando o mesmo tipo de motor.
  2. Verifique se os campos que você está indexando têm o mesmo tipo e comprimento.

No meu caso, o erro foi devido ao referencing A tabela é MyISAM enquanto referring a mesa era InnoDB.

Converted motor de mesa de MyISAM to InnoDB Resolve o problema para mim.

ALTER TABLE table_name ENGINE=InnoDB;

Ainda não tenho reputação de votar a sugestão de Steve, mas isso resolveu meu problema.

No meu caso, recebi esse erro porque a tabela duas em que foi criado usando diferentes mecanismos de banco de dados-um era Innodb e o outro Myisam.

Você pode alterar o tipo de banco de dados usando: alter tabela t Engine = myisam;

@Vejo http://dev.mysql.com/doc/refman/5.1/en/storage-engine-setting.html

Dê atenção a Charset e Agarrar Parâmetros quando você cria uma tabela. Em termos de chave estrangeira Problemas algo assim:

CREATE TABLE yourTableName (
....
....
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

No meu caso, eu não poderia criar a tabela com referências de chave estrangeira. Primeiro, recebi o código de erro 1005, que praticamente não diz nada. Então Eu adicionei colar e, finalmente, a mensagem de erro reclamando do charset.

Error Code: 1253. COLLATION 'utf8_unicode_ci' is not valid for CHARACTER SET 'latin1'

Após essa correção, meu problema foi resolvido.

Não é o seu caso específico, mas vale a pena notar para mais ninguém que esse erro possa ocorrer se você tentar fazer referência a alguns campos em uma tabela que não são toda a chave primária dessa tabela. Obviamente, isso não é permitido.

Se alguém tiver esse erro com os relacionamentos de FK/PK aparentemente bem formados e você usou a ferramenta visual, tente excluir as colunas FK ofensivas e adicioná-las novamente na ferramenta. Eu estava recebendo esse erro continuamente até redefinir as conexões que esclareciam os problemas.

Quando A existem 2 colunas para as teclas primárias, elas compõem uma chave primária composta, portanto, você deve garantir que na tabela que esteja sendo referenciada, também existem 2 colunas do mesmo tipo de dados.

Para mim, eu estava tentando combinar um campo indexado regular em uma tabela infantil, com uma chave primária na tabela pai e, por padrão Que o campo da tabela infantil também não seja assinado (a menos que esses campos possam conter INTs negativos, verifique se os dois são assinados).

O MySQL é notoriamente irritadiço, especialmente no que diz respeito a chaves e gatilhos estrangeiros. Estou agora no processo de ajuste fino, um desses bancos de dados e encontrei esse problema. Não é auto -evidente ou intuitivo, então aqui vai:

Além de verificar se as duas colunas que você deseja fazer referência no relacionamento tiverem o mesmo tipo de dados, você também deve garantir que a coluna da tabela que você está referenciando seja um índice. Se você estiver usando o MySQL Workbench, selecione a guia "Indexos" ao lado de "colunas" e verifique se a coluna referenciada pela chave estrangeira é um índice. Caso contrário, crie um, nomeie algo significativo e dê o tipo "índice".

Uma boa prática é limpar as tabelas envolvidas nos relacionamentos para garantir que as tentativas anteriores não criassem índices que você não deseja ou precisa.

Espero que ajude, alguns erros do MySQL são enlouquecedores de rastrear.

Primeira pergunta:Posso criar uma chave primária que também seja uma chave estrangeira?

Sim.Na verdade, para o ambiente de trabalho MySQL, adquiri o hábito de usar apenas chaves primárias para chaves estrangeiras.Realmente reduz os erros aleatórios recebidos, como o err:150 declarado na pergunta.

#ERRO:Erro 1005:Não é possível criar a tabela 'dbimmobili.condoni' (errno:150)

Isso tem algo a ver com índices ou, mais especificamente, como o ambiente de trabalho MySQL interpreta e trabalha com eles.Realmente fica confuso se você mudar muito no modelo (por exemplochaves estrangeiras, índices, ordens de col) tudo na mesma operação de engenharia direta, especialmente se já houver um banco de dados do outro lado.Por exemplo, não acho que índices criados automaticamente sejam excluídos automaticamente após a exclusão de uma chave estrangeira.

Aqui está o que fiz para corrigir o erro que você recebeu.Observe que parece complicado, mas comparado à quantidade de tempo que passei usando outros métodos, não é.

1.Torne todas as chaves estrangeiras chaves primárias na tabela de pesquisa (o 1 em 1 para muitos).

No meu caso, isso envolveu alterar o id como pk para nome de usuário em tbl_users, para nome de usuário AND empresa em tbl_companies e para nome de usuário AND empresa AND contato em tbl_company_contacts.É um aplicativo para múltiplos usuários inserirem vários contatos da empresa, permitindo sobreposição e ocultação de contatos de outros usuários.

2.Exclua todos os relacionamentos do diagrama e todos os índices da tabela que não sejam chaves primárias.

Isso corrige a maioria dos problemas de índice que são realmente causados ​​por um ambiente de trabalho MySQL com bugs.

3.Se você estiver fazendo isso do início ao fim, descarte o esquema no servidor para que o ambiente de trabalho mysql não fique confuso sobre os índices existentes e falte no modelo (o problema é causado pelo relacionamento do índice e da chave estrangeira, não apenas pelo índice).

Isso reduz muitas das decisões que o banco de dados, o servidor e o ambiente de trabalho Mysql precisam tomar.Essas decisões sobre como projetar algo são complicadas e inteligentes, mas imperfeitas.

4.Agora, considero isso de volta à estaca zero (geralmente depois de projetar muito rapidamente, sem um processo escalonado).Ainda tenho todas as mesas, mas nesta fase elas estão limpas.Agora você apenas:

Primeiro, projete o engenheiro apenas para garantir que as tabelas (sem relacionamentos) funcionem conforme o esperado.

Siga a cadeia de relacionamento através das chaves primárias, começando na tabela superior (no meu caso, tbl_users para tbl_companies).Após cada relacionamento, sempre encaminhe o engenheiro para ter certeza de que corre, salve o modelo e feche, depois faça engenharia reversa do modelo para ter certeza de que leva.Isso permite isolar rapidamente os problemas à medida que surgem, no meu caso, o índice restante usado por chaves estrangeiras excluídas antigas (aconteceu 2 a 3 vezes).

E tadda, de volta onde você precisava estar.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top