Pergunta

I foram lentamente aprendendo SQL nas últimas semanas. Eu peguei tudo da álgebra relacional e as noções básicas de como relacional bancos de dados funciona. O que estou tentando fazer agora é aprender como ele é implementado.

Um tropeço eu me deparei com isso, é as chaves estrangeiras no MySQL. Eu não consigo encontrar muito sobre o outro do que eles existem no InnoDB esquema de armazenamento que MySQL tem.

O que é um exemplo simples de chaves estrangeiras implementadas no MySQL?

O Aqui parte de um esquema que eu escrevi que não parece estar a trabalhar se você prefere ressaltar minha falha que me um exemplo de trabalho show.

CREATE TABLE `posts` (
`pID` bigint(20) NOT NULL auto_increment,
`content` text NOT NULL,
`time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`uID` bigint(20) NOT NULL,
`wikiptr` bigint(20) default NULL,
`cID` bigint(20) NOT NULL,
PRIMARY KEY  (`pID`),
Foreign Key(`cID`) references categories,
Foreign Key(`uID`) references users
) ENGINE=InnoDB;
Foi útil?

Solução

Assumindo suas categorias e usuários tabela já existir e conter Cid e uID, respectivamente, como chaves primárias, isso deve funcionar:

CREATE TABLE `posts` (
`pID` bigint(20) NOT NULL auto_increment,
`content` text NOT NULL,
`time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`uID` bigint(20) NOT NULL,
`wikiptr` bigint(20) default NULL,
`cID` bigint(20) NOT NULL,
PRIMARY KEY  (`pID`),
Foreign Key(`cID`) references categories(`cID`),
Foreign Key(`uID`) references users(`uID`)
) ENGINE=InnoDB;

O nome da coluna é exigido na cláusula references.

Outras dicas

Editado: Robert e Vinko estado que você precisa declarar o nome da coluna referenciada na restrição de chave estrangeira. Isso é necessário em InnoDB, embora em SQL padrão que você está autorizado a omitir o nome da coluna referenciada se é o mesmo nome na tabela pai.

Uma idiossincrasia que eu encontrei no MySQL é que a declaração de chave estrangeira irá falhar silenciosamente em várias circunstâncias:

  • A instalação do MySQL não inclui o motor InnoDB
  • O seu arquivo de configuração do MySQL não permitir que o motor InnoDB
  • Você não declarar a sua mesa com o motor = tabela InnoDB modificador
  • A coluna de chave estrangeira não é exatamente o mesmo tipo de dados como a coluna de chave primária da tabela referenciada

Infelizmente, o MySQL não dá nenhuma mensagem de que ele não foi capaz de criar a restrição de chave estrangeira. Ele simplesmente ignora o pedido, e cria a tabela sem a chave estrangeira (se você mostrar CRIAR mensagens tabela, você pode ver nenhuma declaração de chave estrangeira). Eu sempre pensei que esta é uma característica ruim do MySQL!

Tip: o argumento inteiro para tipos de dados de número inteiro (por exemplo BIGINT (20)) não é necessário. Não tem nada a ver com o tamanho de armazenamento ou o intervalo da coluna. BIGINT é sempre o mesmo tamanho, independentemente do argumento você lhe dá. O número refere-se à forma como dígitos muitos MySQL pad vontade da coluna se você usar o modificador de coluna ZEROFILL.

Este tem algum código mostrando como criar chaves estrangeiras por si só, e em CREATE TABLE.

Aqui está um dos exemplos mais simples do que:

CREATE TABLE parent (
    id INT NOT NULL,
    PRIMARY KEY (id)
) ENGINE=INNODB;

CREATE TABLE child (
    id INT, 
    parent_id INT,
    INDEX par_ind (parent_id),
    FOREIGN KEY (parent_id) REFERENCES parent(id)
    ON DELETE CASCADE
) ENGINE=INNODB;

Eu concordo com Robert. Está faltando o nome da coluna na cláusula de referências (e você deve estar recebendo o erro 150). Vou acrescentar que você pode verificar como as tabelas foi criado em realidade com:

SHOW CREATE TABLE posts;

As respostas anteriores lidar com a restrição de chave estrangeira. Enquanto a restrição de chave estrangeira é definitivamente útil para manter a integridade referencial, o conceito de "chave estrangeira" em si é fundamental para o modelo relacional de dados, independentemente de você usar a restrição ou não.

Sempre que você faz um equijoin , você está igualando uma chave estrangeira para alguma coisa, normalmente a chave faz referência. Exemplo:

select *
from 
   Students
inner join
   StudentCourses
on Students.StudentId = StudentCourses.StudentId

StudentCourses.StudentId é uma chave estrangeira referenciando Students.StudentId.

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