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


Respostas:


764

Para 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 = '<database>' AND
  REFERENCED_TABLE_NAME = '<table>';

Para uma coluna:

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

Basicamente, alteramos REFERENCED_TABLE_NAME por REFERENCED_COLUMN_NAME na cláusula where.


26
isso sempre me dá um conjunto vazio, enquanto a consulta proposta por Node abaixo funciona bem
— Aguda

7
@ Agute: Tem certeza de que está perguntando sobre a tabela correta? Se a consulta do Node funcionar, é provável que você esteja perguntando sobre a outra direção (ou seja, chaves FROM minha tabela, não chaves PARA minha tabela). Isso espera que você tenha escrito '<tabela>' com o nome da tabela e sem os símbolos <<e '>' ?
— Vinko Vrsalovic

3
Parece que eu entendi mal a sua consulta, porque estava consultando as chaves que referenciavam FROM <table> :) (sim, eu escrevi o nome da tabela em vez de "<table>" XD)
— Aguda

4
A menos que você tenha certeza de que o nome da tabela é único, provavelmente também desejará restringir sua consulta a um banco de dados específico. Altere a cláusula where para:where REFERENCED_TABLE_SCHEMA = 'mydatabase' and REFERENCED_TABLE_NAME = 'mytable'
— user12345

Isso não vai funcionar em caso de usuário não raiz mesmo que o usuário tem todas as permissões para o banco de dados
— Deepak Ram

275

EDIT: Como indicado nos comentários, esta não é a resposta correta para a pergunta do OP, mas é útil conhecer este comando. Essa pergunta apareceu no Google para o que eu estava procurando e achei que eu deixaria essa resposta para os outros encontrarem.

SHOW CREATE TABLE `<yourtable>`;

Encontrei esta resposta aqui: MySQL: show constraints on tables command

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


37
Isso mostra todas as restrições em <yourtable>, nem todas as restrições que apontam para <yourtable>.
— Barmar 21/04

18
Como o @Barmar diz, isso é totalmente errado; ele vai mostrar as chaves estrangeiras pertencentes a tabela especificada, mas não vai mostrar as chaves estrangeiras apontando PARA tabela, que é o que a questão pede. Não faço ideia de como isso conseguiu 50 votos positivos; Acho que as pessoas acabaram aqui quando realmente procuravam a resposta para a pergunta oposta, encontraram a resposta aqui de qualquer maneira e não se deram ao trabalho de ler a pergunta original (ou mesmo o título) antes de votar.
— Mark Amery

2
@MarkAmery: este é o primeiro resultado de display foreign keys mysqlno google, pode ser por isso;)
— Jigar

1
thisi realmente mostra todas as restrições existentes, o phpmyadmin mostrará apenas a que está apontando para a sua tabela. parece bom o suficiente para duplicatas evitar com uma ferramenta ORM
— william.eyidi

3
Era isso que eu estava procurando, então obrigado por postá-lo, mesmo que não tenha respondido à pergunta da OP. Nunca é demais saber como olhar nas duas direções em um relacionamento!
— Charles Wood

75

Se você usa o InnoDB e define FKs, pode 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';

15
na verdade, isso aponta na direção errada. essa consulta mostra todas as chaves estrangeiras apontando para 'mytable', nem todas as chaves estrangeiras apontando para 'mytable'.
— Christian Oudard 14/10/08

1
Este funciona melhor no meu caso. Eu preciso eliminar todas as restrições de chave estrangeira (e somente essas) de uma tabela para poder alterar o mecanismo InnoDB MyISAM ou NDB.
— Kohányi Róbert

Você pode obter chaves estrangeiras nas duas direções na tabela REFERENTIAL_CONSTRAINTS - adicionei outra resposta à consulta.
— ChrisV

45

Postagem 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 de tabela e coluna REFERENCED. Assim,

  1. Para ver todos os FKs na sua tabela:

    USE '<yourschema>';
    
    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 = '<yourtable>';
  2. Para ver todas as tabelas e FKs no seu esquema:

    USE '<yourschema>';
    
    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. Para ver todos os FKs no seu banco de dados:

    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';

Lembrar!

Isso está usando o mecanismo de armazenamento InnoDB. Se você não consegue exibir nenhuma chave estrangeira depois de adicioná-la, provavelmente é porque suas tabelas estão usando o MyISAM.

Checar:

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

Para corrigir, use o seguinte:

ALTER TABLE `<yourtable>` ENGINE=InnoDB;

8
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/…
— guigouz 21/01

2
Ótima resposta. Você tem alguma solução para o MyISAM?
— Beau Bouchard

2
O MyISAM não suporta chaves estrangeiras, infelizmente. dev.mysql.com/doc/refman/5.7/en/myisam-storage-engine.html
— Andy

24

Como alternativa à resposta do nó, se você usar o InnoDB e definir FKs, 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 = '<schema>'
AND TABLE_NAME = '<table>'

para chaves estrangeiras de <table> ou

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

para chaves estrangeiras em <table>

Você também pode obter o UPDATE_RULE e DELETE_RULE, se desejar.


2
Pessoalmente, prefiro essa resposta, pois o uso da tabela REFERENTIAL_CONSTRAINTS fornece a regra de atualização e cascata. +1
— Luke Madhanga

Ao descobrir sobre uma tabela, você não deve esquecer que as chaves estrangeiras podem ser estabelecidas de duas maneiras!
— Codificador

11

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

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ê deseja verificar as tabelas em um banco de dados específico, no final da consulta, adicione o nome do esquema:

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 nome_tabela = 'nome_tabela

no final da consulta.

Inspirado por este post aqui


7

O uso de REFERENCED_TABLE_NAME nem sempre funciona e pode ser um valor NULL. A seguinte consulta pode funcionar:

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

4

Uma maneira rápida de listar seus FKs (referências de chave estrangeira) 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;

Esta consulta assume que as restrições e todas as tabelas referenciadas e de referência estão no mesmo esquema.

Adicione seu próprio comentário.

Fonte: manual oficial do mysql.


3

A solução que encontrei é frágil; 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, na concha,

grep 'refs_tablename_id' mysql_output

2

Para encontrar todas as tabelas que contêm uma chave estrangeira específica , comoemployee_id

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

2

Se você também deseja obter o nome da coluna da 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;

Obrigado ótima solução! Eu também precisava do nome da coluna, para obtê-lo, adicione: 'k.COLUMN_NAME'
— Andreas
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.