Comment trouver toutes les tables qui ont des clés étrangères qui font référence à table.column particulière et ont des valeurs pour ces clés étrangères?

272

J'ai une table dont la clé primaire est référencée dans plusieurs autres tables comme clé étrangère. Par exemple:

  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`)
  )

Maintenant, je ne sais pas combien de tables il y a dans la base de données qui contiennent des clés étrangères dans X comme les tables Y et Z. Y a-t-il une requête SQL que je peux utiliser pour retourner:

  1. Une liste des tables qui ont des clés étrangères dans X
  2. ET lesquelles de ces tables ont réellement des valeurs dans la clé étrangère
Mel
la source

Réponses:

384

Voici:

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

Si vous avez plusieurs bases de données avec des noms de tables / colonnes similaires, vous pouvez également souhaiter limiter votre requête à une base de données particulière:

SELECT *
FROM
  KEY_COLUMN_USAGE
WHERE
  REFERENCED_TABLE_NAME = 'X'
  AND REFERENCED_COLUMN_NAME = 'X_id'
  AND TABLE_SCHEMA = 'your_database_name';
Alex N.
la source
7
SELECT TABLE_NAME mieux que SELECT *
zloctb
Pour quel type de base de données est-ce utile? MySql?
Cirelli94
2
@ Cirelli94 La question est balisée comme une question MySQL.
mikeschuld
61

Manuel de référence MySQL 5.5: "Contraintes InnoDB et 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
la source
21

Cette solution affichera non seulement toutes les relations mais aussi le nom de la contrainte, ce qui est nécessaire dans certains cas (par exemple, 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 dans une base de données spécifique, ajoutez ce qui suit:

AND table_schema = 'database_name';
Panayotis
la source
15

Vous pouvez trouver toutes les informations liées au schéma dans le information_schema tableau .

Vous voudrez peut-être vérifier le tableau REFERENTIAL_CONSTRAINTSet KEY_COLUMN_USAGE. Le premier vous indique quelles tables sont référencées par d'autres; ce dernier vous dira comment leurs champs sont liés.

Seb
la source
5

Liste de toutes les clés étrangères dans une base de données, y compris la description

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

restriction à une colonne spécifique dans une table table

AND i1.table_name = 'target_tb_name' AND i1.column_name = 'target_col_name'
bortunac
la source
3

J'ai écrit un petit bash onliner que vous pouvez écrire dans un script pour obtenir une sortie conviviale:

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/,/./'

Ainsi, l'exécution: mysql_references_to transaccion(où transaccion est un nom de table aléatoire) donne une sortie comme celle-ci:

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
la source
-4

Le plus simple:
1. Ouvrez phpMyAdmin
2. Dans le clic gauche sur le nom de la base de données
3. Dans le coin supérieur droit, trouvez l'onglet "Designer"

Toutes les contraintes y seront affichées.

Mantas D
la source