web-dev-qa-db-fra.com

Comment voir toutes les clés étrangères d'une table ou d'une colonne?

Dans MySQL, comment obtenir une liste de toutes les contraintes de clé étrangère pointant vers une table particulière? une colonne particulière? C'est la même chose que cette question Oracle , mais pour MySQL.

474
Christian Oudard

Pour une table:

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

Pour une colonne:

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

En gros, nous avons modifié REFERENCED_TABLE_NAME avec REFERENCED_COLUMN_NAME dans la clause where.

643
Vinko Vrsalovic

EDIT: Comme indiqué dans les commentaires, ce n'est pas la bonne réponse à la question des OP, mais il est utile de connaître cette commande Cette question est apparue dans Google pour ce que je cherchais, et a figuré que je laisserais cette réponse aux autres trouver.

SHOW CREATE TABLE `<yourtable>`;

J'ai trouvé cette réponse ici: MySQL: afficher les contraintes sur les tables de commande

J'avais besoin de cette façon parce que je voulais voir comment le FK fonctionnait plutôt que de voir s'il existait ou non.

220
CenterOrbit

Si vous utilisez InnoDB et des FK définis, vous pouvez interroger la base de données information_schema par exemple:

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

Poster une ancienne réponse pour ajouter des informations utiles.

J'ai eu un problème similaire, mais je voulais aussi voir CONSTRAINT_TYPE avec les noms de table et de colonne REFERENCED. Alors,

  1. Pour voir tous les FK dans votre table:

    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. Pour voir toutes les tables et les FK de votre schéma:

    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. Pour voir tous les FK dans votre base de données:

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

Rappelles toi!

Ceci utilise le moteur de stockage InnoDB. Si vous semblez ne pas avoir de clé étrangère à afficher après l'ajout, c'est probablement parce que vos tables utilisent MyISAM. 

Vérifier:

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

Pour réparer, utilisez ceci:

ALTER TABLE `<yourtable>` ENGINE=InnoDB;
41
Andy

Si vous utilisez InnoDB et des FK définis, vous pouvez également interroger la base de données information_schema, par exemple:

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

pour les clés étrangères 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>'

pour les clés étrangères à <table>

Vous pouvez également obtenir les variables UPDATE_RULE et DELETE_RULE si vous le souhaitez.

21
ChrisV

Cette solution affichera non seulement toutes les relations, mais également le nom de la contrainte, requis dans certains cas (par exemple, une contrainte de suppression):

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;

Si vous souhaitez vérifier les tables d'une base de données spécifique, ajoutez le nom du schéma à la fin de la requête:

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

De même, pour un nom de colonne spécifique, ajoutez

et nom_table = 'nom_table

à la fin de la requête.

Inspiré par cet article ici

8
Panayotis

Un moyen rapide de répertorier vos FK (références de clé étrangère) à l'aide du 

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;

Cette requête suppose que les contraintes et toutes les tables référencées et référencées sont dans le même schéma.

Ajoutez votre propre commentaire.

Source: le manuel officiel de MySQL.

3
Daniel Rodas

L'utilisation de REFERENCED_TABLE_NAME ne fonctionne pas toujours et peut être une valeur NULL. La requête suivante peut fonctionner à la place:

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

Pour trouver toutes les tables contenant une clé étrangère particulière telle que employee_id

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

La solution que j'ai proposée est fragile; il repose sur la convention de nommage de Django pour les clés étrangères.

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

Ensuite, dans la coquille,

grep 'refs_tablename_id' mysql_output
2
Christian Oudard

Si vous souhaitez également obtenir le nom de la colonne de clé étrangère:

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
omarjebari