Como vejo todas as chaves estrangeiras para uma tabela ou coluna?

No MySQL, como faço para obter uma lista de todas as restrições de chaves estrangeiras apontando para uma tabela específica? uma coluna particular? Essa é a mesma coisa que esta pergunta sobre o Oracle , mas para o MySQL.

413

11 Respostas

Por uma tabela:

SELECT 
  TABLE_NAME,COLUMN_NAME,CONSTRAINT_NAME, REFERENCED_TABLE_NAME,REFERENCED_COLUMN_NAME
FROM
  INFORMATION_SCHEMA.KEY_COLUMN_USAGE
WHERE
  REFERENCED_TABLE_SCHEMA = '' AND
  REFERENCED_TABLE_NAME = '<table>';

For a Column:

SELECT 
  TABLE_NAME,COLUMN_NAME,CONSTRAINT_NAME, REFERENCED_TABLE_NAME,REFERENCED_COLUMN_NAME
FROM
  INFORMATION_SCHEMA.KEY_COLUMN_USAGE
WHERE
  REFERENCED_TABLE_SCHEMA = '' AND
  REFERENCED_COLUMN_NAME = '';

Basically, we changed REFERENCED_TABLE_NAME with REFERENCED_COLUMN_NAME in the where clause.

569
adicionado
@Acute: Tem certeza de que está perguntando sobre a mesa correta? Se a consulta do Node funcionar, então você provavelmente está perguntando sobre a outra direção (ou seja, chaves FROM minha tabela, não chaves para mytable). Esperando que você escreveu '<table>' com o nome da tabela e sem '<' e '>' ?
adicionado o autor Vinko Vrsalovic, fonte
Por que é tão necessário? Por que não tornar tão fácil como você seleciona linhas?
adicionado o autor Lealo, fonte
Concordo, eu só recebo um set vazio aqui! A resposta de Andy funcionou melhor para mim.
adicionado o autor omarjebari, fonte
@DeepakRam Isso funciona perfeitamente para mim com um usuário privilegiado que não é o usuário root.
adicionado o autor Matthew Read, fonte
Isso funcionou perfeito para mim. Eu tenho mais privilégios, mas não root. Você é um salva-vidas.
adicionado o autor jDub9, fonte
isso sempre me dá um conjunto vazio, enquanto a consulta proposta pelo Node abaixo funciona bem
adicionado o autor Acute, fonte
Parece que eu entendi mal sua consulta, porque eu estava consultando chaves referenciando do <table> :) (sim, eu escrevi o nome da tabela em vez de "<table>" XD)
adicionado o autor Acute, fonte
A menos que você tenha certeza de que o nome da sua tabela é único, provavelmente desejará restringir sua consulta a um banco de dados específico também. Altere a cláusula where para esta: onde REFERENCED_TABLE_SCHEMA = 'mydatabase' e REFERENCED_TABLE_NAME = 'mytable'
adicionado o autor user12345, fonte
Isso não funcionará no caso de usuário não raiz, mesmo que o usuário tenha todas as permissões para o banco de dados
adicionado o autor Deepak Ram, fonte

EDIT: Como apontado nos comentários, esta não é a resposta correta para a pergunta de OPs, mas é útil saber este comando. Esta pergunta apareceu no Google para o que eu estava procurando, e pensei em deixar essa resposta para os outros encontrarem.

SHOW CREATE TABLE ``;

I found this answer here: MySQL : show constraints on tables command

Eu precisava desse jeito porque queria ver como o FK funcionava, em vez de apenas ver se existia ou não.

194
adicionado
Como diz Barmar, isso é totalmente errado; mostrará as chaves estrangeiras que pertencem à tabela especificada, mas não mostrará chaves estrangeiras que apontam PARA a tabela, que é o que a pergunta pede. Não faço ideia de como isso conseguiu 50 votos positivos; Eu acho que as pessoas acabaram aqui quando realmente estavam procurando a resposta para a questão oposta, encontraram sua resposta aqui de qualquer maneira, e não se incomodaram em ler a pergunta original (ou mesmo seu título) antes de votar.
adicionado o autor Mark Amery, fonte
Isso mostra todas as restrições em , não todas as restrições que apontam para .
adicionado o autor Barmar, fonte
thisi na verdade mostra todas as restrições que existem, o phpmyadmin mostrará apenas o que aponta para a sua tabela. parece bom o suficiente para evitar duplicatas com uma ferramenta ORM
adicionado o autor william.eyidi, fonte
@MarkAmery: este é o primeiro resultado de exibir chaves estrangeiras MySQL no google, pode ser por isso que;)
adicionado o autor Jigar, fonte
Isso é o que eu estava procurando, então obrigado por postar, mesmo que não tenha respondido à pergunta do OP. Nunca é demais saber como olhar nos dois sentidos em um relacionamento!
adicionado o autor Charles Wood, fonte

Se você usar o InnoDB e os FKs definidos, poderá consultar o banco de dados information_schema, por exemplo:

SELECT * FROM information_schema.TABLE_CONSTRAINTS 
WHERE information_schema.TABLE_CONSTRAINTS.CONSTRAINT_TYPE = 'FOREIGN KEY' 
AND information_schema.TABLE_CONSTRAINTS.TABLE_SCHEMA = 'myschema'
AND information_schema.TABLE_CONSTRAINTS.TABLE_NAME = 'mytable';
58
adicionado
na verdade, isso aponta na direção errada. essa consulta mostra todas as chaves estrangeiras apontando FROM 'mytable', nem todas as chaves estrangeiras apontando para 'mytable'.
adicionado o autor Christian Oudard, fonte
Você pode obter chaves estrangeiras em ambas as direções da tabela REFERENTIAL_CONSTRAINTS - adicionei outra resposta à consulta.
adicionado o autor ChrisV, fonte
Este funciona melhor no meu caso. Preciso soltar todas as restrições de chave estrangeira (e somente as) de uma tabela para poder alterar o mecanismo MynoAM ou NDB do InnoDB.
adicionado o autor Kohányi Róbert, fonte

Postar em uma resposta antiga para adicionar algumas informações úteis.

Eu tive um problema semelhante, mas também queria ver o CONSTRAINT_TYPE junto com os nomes da tabela e da coluna REFERENCED. Assim,

  1. To see all FKs in your table:

    USE '';
    
    SELECT i.TABLE_NAME, i.CONSTRAINT_TYPE, i.CONSTRAINT_NAME, k.REFERENCED_TABLE_NAME, k.REFERENCED_COLUMN_NAME 
    FROM information_schema.TABLE_CONSTRAINTS i 
    LEFT JOIN information_schema.KEY_COLUMN_USAGE k ON i.CONSTRAINT_NAME = k.CONSTRAINT_NAME 
    WHERE i.CONSTRAINT_TYPE = 'FOREIGN KEY' 
    AND i.TABLE_SCHEMA = DATABASE()
    AND i.TABLE_NAME = '';
    
  2. To see all the tables and FKs in your schema:

    USE '';
    
    SELECT i.TABLE_NAME, i.CONSTRAINT_TYPE, i.CONSTRAINT_NAME, k.REFERENCED_TABLE_NAME, k.REFERENCED_COLUMN_NAME 
    FROM information_schema.TABLE_CONSTRAINTS i 
    LEFT JOIN information_schema.KEY_COLUMN_USAGE k ON i.CONSTRAINT_NAME = k.CONSTRAINT_NAME 
    WHERE i.CONSTRAINT_TYPE = 'FOREIGN KEY' 
    AND i.TABLE_SCHEMA = DATABASE();
    
  3. To see all the FKs in your database:

    SELECT i.TABLE_SCHEMA, i.TABLE_NAME, i.CONSTRAINT_TYPE, i.CONSTRAINT_NAME, k.REFERENCED_TABLE_NAME, k.REFERENCED_COLUMN_NAME 
    FROM information_schema.TABLE_CONSTRAINTS i 
    LEFT JOIN information_schema.KEY_COLUMN_USAGE k ON i.CONSTRAINT_NAME = k.CONSTRAINT_NAME 
    WHERE i.CONSTRAINT_TYPE = 'FOREIGN KEY';
    

Lembre-se!

Isso está usando o mecanismo de armazenamento InnoDB. Se você não consegue obter quaisquer chaves estrangeiras para aparecer depois de adicioná-las, provavelmente é porque suas tabelas estão usando o MyISAM.

Checar:

SELECT * TABLE_NAME, ENGINE FROM information_schema.TABLES WHERE TABLE_SCHEMA = '';

Para corrigir, use isto:

ALTER TABLE `` ENGINE=InnoDB;
32
adicionado
O MyISAM não suporta chaves estrangeiras, infelizmente. dev.mysql.com/doc/refman/5.7/ pt/myisam-storage-engine.html
adicionado o autor Andy, fonte
Ótima resposta. Você tem alguma solução para o MyISAM?
adicionado o autor Beau Bouchard, fonte
Essas consultas são executadas muito mais rapidamente (de 2 segundos a 0,0015 segundos) se você especificar k.TABLE_SCHEMA = DATABASE() e k.TABLE_NAME = '<table>' na cláusula WHERE, conforme documentado aqui dev.mysql.com/doc/refman/5.5/en/…
adicionado o autor guigouz, fonte

Como alternativa à resposta do Node, se você usar o InnoDB e os FKs definidos, poderá consultar o banco de dados information_schema, por exemplo:

SELECT CONSTRAINT_NAME, TABLE_NAME, REFERENCED_TABLE_NAME
FROM information_schema.REFERENTIAL_CONSTRAINTS
WHERE CONSTRAINT_SCHEMA = ''
AND TABLE_NAME = '<table>'

for foreign keys from <table>, or

SELECT CONSTRAINT_NAME, TABLE_NAME, REFERENCED_TABLE_NAME
FROM information_schema.REFERENTIAL_CONSTRAINTS
WHERE CONSTRAINT_SCHEMA = ''
AND REFERENCED_TABLE_NAME = '<table>'

for foreign keys to <table>

You can also get the UPDATE_RULE and DELETE_RULE if you want them.

17
adicionado
Eu pessoalmente prefiro esta resposta como usar a tabela REFERENTIAL_CONSTRAINTS dá-lhe a regra de atualização e cascata. +1
adicionado o autor Luke Madhanga, fonte
Fazendo a descoberta sobre uma mesa, você não deve esquecer que as chaves estrangeiras podem ser estabelecidas de ambas as formas!
adicionado o autor Encoder, fonte

Essa solução não exibirá apenas todas as relações, mas também o nome da restrição, que é necessário em alguns casos (por exemplo, contraint drop):

select
    concat(table_name, '.', column_name) as 'foreign key',
    concat(referenced_table_name, '.', referenced_column_name) as 'references',
    constraint_name as 'constraint name'
from
    information_schema.key_column_usage
where
    referenced_table_name is not null;

Se você quiser verificar as tabelas em um banco de dados específico, no final da consulta, adicione o nome da tabela:

select
    concat(table_name, '.', column_name) as 'foreign key',
    concat(referenced_table_name, '.', referenced_column_name) as 'references',
    constraint_name as 'constraint name'
from
    information_schema.key_column_usage
where
    referenced_table_name is not null
    and table_schema = 'database_name';

Da mesma forma, para um nome de coluna específico, adicione

e table_name = 'table_name

no final da consulta.

Inspired by this post here

7
adicionado

Uma maneira rápida de listar seus FKs (referências de chaves estrangeiras) usando o

KEY_COLUMN_USAGE view:

SELECT CONCAT( table_name, '.',
column_name, ' -> ',
referenced_table_name, '.',
referenced_column_name ) AS list_of_fks
FROM information_schema.KEY_COLUMN_USAGE
WHERE REFERENCED_TABLE_SCHEMA = (your schema name here)
AND REFERENCED_TABLE_NAME is not null
ORDER BY TABLE_NAME, COLUMN_NAME;

Essa consulta supõe que as restrições e todas as tabelas referenciadas e de referência estejam no mesmo esquema.

Adicione seu próprio comentário.

Fonte: o manual oficial do mysql.

2
adicionado

To find all tables containing a particular foreign key such as employee_id

SELECT DISTINCT TABLE_NAME 
FROM INFORMATION_SCHEMA.COLUMNS
WHERE COLUMN_NAME IN ('employee_id')
AND TABLE_SCHEMA='table_name';
2
adicionado

A solução que encontrei é frágil; Ele depende da convenção de nomenclatura do django para chaves estrangeiras.

USE information_schema;
tee mysql_output
SELECT * FROM TABLE_CONSTRAINTS WHERE CONSTRAINT_TYPE = 'FOREIGN KEY' AND TABLE_SCHEMA = 'database_name';
notee

Então, no shell,

grep 'refs_tablename_id' mysql_output
1
adicionado

O uso de REFERENCED_TABLE_NAME nem sempre funciona e pode ser um valor NULL. A consulta a seguir pode funcionar em vez disso:

select * from INFORMATION_SCHEMA.KEY_COLUMN_USAGE where TABLE_NAME = '<table>';
1
adicionado

Se você também quiser obter o nome da coluna de chave estrangeira:

SELECT i.TABLE_SCHEMA, i.TABLE_NAME, 
       i.CONSTRAINT_TYPE, i.CONSTRAINT_NAME, 
       k.COLUMN_NAME, k.REFERENCED_TABLE_NAME, k.REFERENCED_COLUMN_NAME 
  FROM information_schema.TABLE_CONSTRAINTS i 
  LEFT JOIN information_schema.KEY_COLUMN_USAGE k 
       ON i.CONSTRAINT_NAME = k.CONSTRAINT_NAME 
 WHERE i.TABLE_SCHEMA = '<table_NAME>' AND i.CONSTRAINT_TYPE = 'FOREIGN KEY' 
 ORDER BY i.TABLE_NAME;
0
adicionado