¿Cómo veo todas las claves externas a una tabla o columna?

En MySQL, ¿cómo obtengo una lista de todas las restricciones de clave externa que apuntan a una tabla en particular? una columna en particular? Esto es lo mismo que esta pregunta de Oracle , pero para MySQL.

413

11 Respuestas

Para una tabla:

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
agregado
@Acute: ¿Estás seguro de que estás preguntando sobre la tabla correcta? Si la consulta de Node funciona, entonces es probable que pregunte acerca de la otra dirección (es decir, claves FROM mytable, no keys TO mytable.) Esto esperaba que escribiera '<table>' con el nombre de la tabla y sin '<' y '>' ?
agregado el autor Vinko Vrsalovic, fuente
¿Por qué se requiere tanto? ¿Por qué no hacerlo tan fácil como la forma de seleccionar las filas?
agregado el autor Lealo, fuente
De acuerdo, ¡solo recibo un juego vacío aquí! La respuesta de Andy funcionó mejor para mí.
agregado el autor omarjebari, fuente
@DeepakRam Esto funciona perfectamente para mí con un usuario privilegiado que no es el usuario raíz.
agregado el autor Matthew Read, fuente
Esto funcionó perfecto para mí. Tengo la mayoría de los privilegios, pero no la raíz. Eres un salvavidas.
agregado el autor jDub9, fuente
esto siempre me da un conjunto vacío, mientras que la consulta propuesta por Node a continuación funciona bien
agregado el autor Acute, fuente
Parece que no entendí tu consulta, porque estaba preguntando por referencias de teclas FROM <table> :) (sí, escribí el nombre de la tabla en lugar de "<table>" XD)
agregado el autor Acute, fuente
A menos que esté seguro de que su nombre de tabla es único, probablemente también desee restringir su consulta a una base de datos en particular. Cambie la cláusula where a esto: donde REFERENCED_TABLE_SCHEMA = 'mydatabase' y REFERENCED_TABLE_NAME = 'mytable'
agregado el autor user12345, fuente
Esto no funcionará en el caso de usuario no root a pesar de que el usuario tiene todos los permisos para la base de datos
agregado el autor Deepak Ram, fuente

EDITAR: Como se señaló en los comentarios, esta no es la respuesta correcta a la pregunta de OP, pero es útil conocer este comando. Esta pregunta apareció en Google por lo que estaba buscando, y pensé que dejaría esta respuesta para que los demás la encuentren.

SHOW CREATE TABLE ``;

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

Lo necesitaba de esta manera porque quería ver cómo funcionaba el FK, en lugar de ver si existía o no.

194
agregado
Como dice @Barmar, esto es completamente incorrecto; mostrará las claves foráneas que pertenecen a la tabla especificada, pero no mostrará las claves foráneas que señalan A la tabla, que es lo que solicita la pregunta. No tengo idea de cómo esto consiguió 50 votos ascendentes; Supongo que las personas terminaron aquí cuando realmente estaban buscando la respuesta a la pregunta opuesta, encontraron su respuesta aquí de todos modos, y no se molestaron en leer la pregunta original (o incluso su título) antes de la votación ascendente.
agregado el autor Mark Amery, fuente
Esto muestra todas las restricciones en , no todas las restricciones que apuntan a .
agregado el autor Barmar, fuente
esto realmente muestra todas las restricciones que existen, phpmyadmin solo le mostrará el que apunta a su tabla. parece lo suficientemente bueno para evitar duplicados con una herramienta ORM
agregado el autor william.eyidi, fuente
@MarkAmery: este es el primer resultado de mostrar claves externas MySQL en google, puede ser por eso;)
agregado el autor Jigar, fuente
Esto es lo que estaba buscando, así que gracias por publicarlo aunque no respondió la pregunta de OP. ¡Nunca duele saber cómo mirar en ambas direcciones en una relación!
agregado el autor Charles Wood, fuente

Si usa InnoDB y FK definidos, puede consultar la base de datos de information_schema, por ejemplo:

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
agregado
en realidad, eso apunta en la dirección equivocada. esa consulta muestra todas las claves foráneas que apuntan desde 'mytable', no todas las teclas foráneas que apuntan a 'mytable'.
agregado el autor Christian Oudard, fuente
Puede obtener claves externas en ambas direcciones desde la tabla REFERENTIAL_CONSTRAINTS. He agregado otra respuesta con la consulta.
agregado el autor ChrisV, fuente
Este funciona mejor en mi caso. Necesito eliminar cada restricción de clave externa (y solo aquellas) de una tabla para poder cambiar el motor InnoDB MyISAM o NDB.
agregado el autor Kohányi Róbert, fuente

Publicar en una respuesta anterior para agregar información útil.

Tuve un problema similar, pero también quería ver CONSTRAINT_TYPE junto con los nombres de columnas y tablas REFERENCED. Asi que,

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

¡Recuerda!

Esto está usando el motor de almacenamiento InnoDB. Si parece que no puede obtener ninguna clave externa para mostrar después de agregarlas, es probable que se deba a que sus tablas están usando MyISAM.

Verificar:

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

Para solucionarlo, usa esto:

ALTER TABLE `` ENGINE=InnoDB;
32
agregado
MyISAM no es compatible con claves externas, desafortunadamente. dev.mysql.com/doc/refman/5.7/ es/myisam-storage-engine.html
agregado el autor Andy, fuente
gran respuesta. ¿Tienes alguna solución para MyISAM?
agregado el autor Beau Bouchard, fuente
Esas consultas se ejecutan mucho más rápido (de 2 segundos a 0.0015 segundos) si especifica k.TABLE_SCHEMA = DATABASE() y k.TABLE_NAME = '<table>' en la cláusula WHERE, como se documenta aquí dev.mysql.com/doc/refman/5.5/en/…
agregado el autor guigouz, fuente

Como alternativa a la respuesta de Node, si usa InnoDB y FK definidos, puede consultar la base de datos de information_schema, por ejemplo:

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
agregado
Personalmente prefiero esta respuesta, ya que el uso de la tabla REFERENTIAL_CONSTRAINTS te proporciona la regla de actualización y cascada. +1
agregado el autor Luke Madhanga, fuente
¡Hacer un descubrimiento sobre una tabla no debería olvidar que las claves externas se pueden establecer AMBAS!
agregado el autor Encoder, fuente

Esta solución no solo mostrará todas las relaciones, sino también el nombre de la restricción, que en algunos casos se requiere (por ejemplo, aplicar un goteo):

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 desea verificar tablas en una base de datos específica, al final de la consulta agregue el nombre de la tabla:

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

Del mismo modo, para un nombre de columna específico, agregue

y table_name = 'table_name

al final de la consulta.

Inspired by this post here

7
agregado

Una forma rápida de listar sus FK (referencias de clave externa) usando el

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 supone que las restricciones y todas las tablas referenciadas y referenciadas están en el mismo esquema.

Agrega tu propio comentario.

Fuente: el manual oficial de mysql.

2
agregado

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
agregado

La solución que se me ocurrió es frágil; depende de la convención de nomenclatura de django para claves externas.

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

Luego, en el caparazón,

grep 'refs_tablename_id' mysql_output
1
agregado

El uso de REFERENCED_TABLE_NAME no siempre funciona y puede ser un valor NULL. La siguiente consulta puede funcionar en su lugar:

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

Si también desea obtener el nombre de la columna de clave externa:

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
agregado