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


Respuestas:


764

Para una mesa:

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 una columna:

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

Básicamente, cambiamos REFERENCED_TABLE_NAME con REFERENCED_COLUMN_NAME en la cláusula where.


26
esto siempre me da un conjunto vacío, mientras que la consulta propuesta por Node a continuación funciona bien
Agudo

77
@Acute: ¿Estás seguro de que estás preguntando por la tabla correcta? Si la consulta de Node funciona, es probable que esté preguntando sobre la otra dirección (es decir, las teclas FROM mytable, no las teclas TO mytable). Esto espera que haya escrito '<table>' con el nombre de la tabla y sin '<' y '>' ?
Vinko Vrsalovic

3
Parece que no entendí su consulta, porque estaba buscando claves que hicieran referencia a <table> :) (sí, escribí el nombre de la tabla en lugar de "<table>" XD)
Agudo

44
A menos que esté seguro de que el nombre de su tabla es único, probablemente también desee restringir su consulta a una base de datos en particular. Cambie la cláusula where a esto:where REFERENCED_TABLE_SCHEMA = 'mydatabase' and REFERENCED_TABLE_NAME = 'mytable'
user12345

Esto no funcionará en el caso de usuarios no root, aunque el usuario tenga todos los permisos para la base de datos
Deepak Ram

275

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

SHOW CREATE TABLE `<yourtable>`;

Encontré esta respuesta aquí: MySQL: mostrar restricciones en el comando de tablas

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


37
Esto muestra todas las restricciones <yourtable>, no todas las restricciones que apuntan <yourtable>.
Barmar

18
Como dice @Barmar, esto está completamente mal; se mostrará las claves externas que pertenecen a la tabla especificada, pero no mostrará las claves externas apuntando A la mesa, que es lo que la pregunta se refiere. No tengo idea de cómo esto obtuvo 50 votos a favor; 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 votar.
Mark Amery

2
@ MarkAmery: este es el primer resultado display foreign keys mysqlen google, puede ser por eso;)
Jigar

1
thisi en realidad muestra todas las restricciones que existen, phpmyadmin solo le mostrará la que apunta a su tabla. parece lo suficientemente bueno como para evitar duplicados con una herramienta ORM
william.eyidi

3
Esto es lo que estaba buscando, así que gracias por publicarlo a pesar de que no respondió la pregunta de OP. ¡Nunca está de más saber cómo mirar en ambas direcciones en una relación!
Charles Wood

75

Si utiliza InnoDB y FK definidos, puede consultar la base de datos 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';

15
en realidad, eso señala la dirección equivocada. esa consulta muestra todas las claves foráneas apuntando desde 'mytable', no todas las claves foráneas apuntando hacia 'mytable'.
Christian Oudard

1
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.
Kohányi Róbert

Puede obtener claves foráneas en ambas direcciones desde la tabla REFERENTIAL_CONSTRAINTS. He agregado otra respuesta con la consulta.
ChrisV

45

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

Tuve un problema similar, pero también quería ver CONSTRAINT_TYPE junto con la tabla REFERENCIADA y los nombres de columna. Entonces,

  1. Para ver todos los FK en su tabla:

    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 las tablas y FK en su 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 los FK en su base de datos:

    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á utilizando el motor de almacenamiento InnoDB. Si parece que no puede mostrar ninguna clave foránea después de agregarla, probablemente sea porque sus tablas están usando MyISAM.

Verificar:

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

Para solucionarlo, use esto:

ALTER TABLE `<yourtable>` ENGINE=InnoDB;

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

2
gran respuesta. ¿Tienes alguna solución para MyISAM?
Beau Bouchard

2
MyISAM no admite claves foráneas, desafortunadamente. dev.mysql.com/doc/refman/5.7/en/myisam-storage-engine.html
Andy

24

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

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

para claves foráneas de <table>, o

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

para claves foráneas para <table>

También puede obtener UPDATE_RULE y DELETE_RULE si lo desea.


2
Personalmente, prefiero esta respuesta, ya que el uso de la tabla REFERENTIAL_CONSTRAINTS le proporciona la regla de actualización y cascada. +1
Luke Madhanga

¡Al descubrir una tabla, no debe olvidar que las claves externas se pueden establecer de AMBAS formas!
Codificador

11

Esta solución no solo mostrará todas las relaciones, sino también el nombre de restricción, que se requiere en algunos casos (p. Ej., Caída de contraint):

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 las tablas en una base de datos específica, al final de la consulta agregue el nombre del 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';

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

y table_name = 'table_name

al final de la consulta.

Inspirado en esta publicación aquí


7

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

4

Una forma rápida de enumerar sus FK (referencias de clave externa) utilizando 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 asume que las restricciones y todas las tablas referenciadas y de referencia están en el mismo esquema.

Agrega tu propio comentario.

Fuente: el manual oficial de mysql.


3

La solución que se me ocurrió es frágil; se basa en 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

Entonces, en el caparazón,

grep 'refs_tablename_id' mysql_output

2

Para buscar todas las tablas que contienen una clave foránea particular , comoemployee_id

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

2

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;

Gracias gran solución! También necesitaba el nombre de la columna, para agregarlo: 'k.COLUMN_NAME'
Andreas
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.