Como encontrar todas as tabelas que possuem chaves estrangeiras que fazem referência a table.column específico e têm valores para essas chaves estrangeiras?

272

Eu tenho uma tabela cuja chave primária é referenciada em várias outras tabelas como uma chave estrangeira. Por exemplo:

  CREATE TABLE `X` (
    `X_id` int NOT NULL auto_increment,
    `name` varchar(255) NOT NULL,
    PRIMARY KEY  (`X_id`)
  )
  CREATE TABLE `Y` (
    `Y_id` int(11) NOT NULL auto_increment,
    `name` varchar(255) NOT NULL,
    `X_id` int DEFAULT NULL,
    PRIMARY KEY  (`Y_id`),
    CONSTRAINT `Y_X` FOREIGN KEY (`X_id`) REFERENCES `X` (`X_id`)
  )
  CREATE TABLE `Z` (
    `Z_id` int(11) NOT NULL auto_increment,
    `name` varchar(255) NOT NULL,
    `X_id` int DEFAULT NULL,
    PRIMARY KEY  (`Z_id`),
    CONSTRAINT `Z_X` FOREIGN KEY (`X_id`) REFERENCES `X` (`X_id`)
  )

Agora, não sei quantas tabelas existem no banco de dados que contêm chaves estrangeiras no X, como as tabelas Y e Z. Existe uma consulta SQL que eu possa usar para retornar:

  1. Uma lista de tabelas que possuem chaves estrangeiras no X
  2. E qual dessas tabelas realmente tem valores na chave estrangeira
Mel
fonte

Respostas:

384

Aqui está:

USE information_schema;
SELECT *
FROM
  KEY_COLUMN_USAGE
WHERE
  REFERENCED_TABLE_NAME = 'X'
  AND REFERENCED_COLUMN_NAME = 'X_id';

Se você tiver vários bancos de dados com nomes de tabelas / colunas semelhantes, também poderá limitar sua consulta a um banco de dados específico:

SELECT *
FROM
  KEY_COLUMN_USAGE
WHERE
  REFERENCED_TABLE_NAME = 'X'
  AND REFERENCED_COLUMN_NAME = 'X_id'
  AND TABLE_SCHEMA = 'your_database_name';
Alex N.
fonte
7
SELECT TABLE_NAME mais melhor que SELECT *
zloctb 16/06/2015
Para que tipo de banco de dados isso é útil? MySql?
Cirelli94
2
@ Cirelli94 A questão está marcada como uma questão do MySQL.
Mikechuld 01/03/19
61

Manual de Referência do MySQL 5.5: "Restrições InnoDB e FOREIGN KEY"

SELECT
  ke.REFERENCED_TABLE_SCHEMA parentSchema,
  ke.referenced_table_name parentTable,
  ke.REFERENCED_COLUMN_NAME parentColumnName,
  ke.TABLE_SCHEMA ChildSchema,
  ke.table_name childTable,
  ke.COLUMN_NAME ChildColumnName
FROM
  information_schema.KEY_COLUMN_USAGE ke
WHERE
  ke.referenced_table_name IS NOT NULL
  AND ke.REFERENCED_COLUMN_NAME = 'ci_id' ## Find Foreign Keys linked to this Primary Key
ORDER BY
  ke.referenced_table_name;
Ovidiu
fonte
21

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, restrição de 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, adicione o seguinte:

AND table_schema = 'database_name';
Panayotis
fonte
15

Você pode encontrar todas as informações relacionadas ao esquema na information_schematabela com nome inteligente .

Você pode querer verificar a tabela REFERENTIAL_CONSTRAINTSe KEY_COLUMN_USAGE. O primeiro diz quais tabelas são referenciadas por outras pessoas; o último dirá a você como seus campos estão relacionados.

Seb
fonte
5

Listando todas as chaves estrangeiras em um banco de dados, incluindo a descrição

    SELECT  
    i1.CONSTRAINT_NAME, i1.TABLE_NAME,i1.COLUMN_NAME,
    i1.REFERENCED_TABLE_SCHEMA,i1.REFERENCED_TABLE_NAME, i1.REFERENCED_COLUMN_NAME,
    i2.UPDATE_RULE, i2.DELETE_RULE 
    FROM   
    information_schema.KEY_COLUMN_USAGE AS i1  
    INNER JOIN 
    information_schema.REFERENTIAL_CONSTRAINTS AS i2 
    ON i1.CONSTRAINT_NAME = i2.CONSTRAINT_NAME 
    WHERE i1.REFERENCED_TABLE_NAME IS NOT NULL  
    AND  i1.TABLE_SCHEMA  ='db_name';

restringindo a uma coluna específica em uma tabela

AND i1.table_name = 'target_tb_name' AND i1.column_name = 'target_col_name'
Bortunac
fonte
3

Eu escrevi um pouco de bash onliner que você pode escrever em um script para obter uma saída amigável:

mysql_references_to:

mysql -uUSER -pPASS -A DB_NAME -se "USE information_schema; SELECT * FROM KEY_COLUMN_USAGE WHERE REFERENCED_TABLE_NAME = '$1' AND REFERENCED_COLUMN_NAME = 'id'\G" | sed 's/^[ \t]*//;s/[ \t]*$//' |egrep "\<TABLE_NAME|\<COLUMN_NAME" |sed 's/TABLE_NAME: /./g' |sed 's/COLUMN_NAME: //g' | paste -sd "," -| tr '.' '\n' |sed 's/,$//' |sed 's/,/./'

Portanto, a execução: mysql_references_to transaccion(onde transaccion é um nome de tabela aleatório) fornece uma saída como esta:

carrito_transaccion.transaccion_id
comanda_detalle.transaccion_id
comanda_detalle_devolucion.transaccion_positiva_id
comanda_detalle_devolucion.transaccion_negativa_id
comanda_transaccion.transaccion_id
cuenta_operacion.transaccion_id
...
jhvaras
fonte
-4

Mais fácil:
1. Abra o phpMyAdmin
2. À esquerda, clique no nome do banco de dados
3. No canto superior direito, encontre a guia "Designer"

Todas as restrições serão mostradas lá.

Mantas D
fonte