2008-10-14 7 views

Respuesta

531

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 = '<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_COLUMN_NAME = '<column>'; 

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

+10

esto siempre me da un conjunto vacío, mientras que la consulta propuesta por el nodo a continuación funciona bien – Acute

+5

@Acute: ¿Estás seguro de que estás preguntando sobre la tabla correcta? Si la consulta de Node funciona, entonces es probable que pregunte sobre la otra dirección (es decir, las teclas FROM mytable, no las teclas TO mytable.) ¿Esto esperaba que escribiera '

' con el nombre de tabla y sin '<' and '>'? –

+3

Parece que no entendí tu consulta, porque estaba preguntando por referencias de claves DESDE el

:) (sí, escribí el nombre de la tabla en lugar de "
" XD) – Acute

56

Si utiliza InnoDB y definido de FK podrías consultar en la base de datos INFORMATION_SCHEMA ej .:

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

realidad, que 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'. –

+0

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. –

+0

Puede obtener claves externas en ambas direcciones desde la tabla REFERENTIAL_CONSTRAINTS. He agregado otra respuesta con la consulta. – ChrisV

1

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 la cáscara,

grep 'refs_tablename_id' mysql_output 
28

Publicando en una vieja respuesta para agregar algo de información útil.

Tuve un problema similar, pero también quería ver el CONSTRAINT_TYPE junto con los nombres de columna y tabla REFERENCED. Así,

  1. para ver todos FKs en la 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 FKs 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 FKs 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'; 
    

¡Recuerde!

Esto está utilizando 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.

Para comprobar:

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

Para el montaje, utilice esto:

ALTER TABLE `<yourtable>` ENGINE=InnoDB; 
+6

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

' en la cláusula WHERE, como se documenta aquí http://dev.mysql.com/ doc/refman/5.5/es/information-schema-optimization.html – guigouz

+1

excelente respuesta. ¿Tienes alguna solución para MyISAM? –

+1

MyISAM no es compatible con claves externas, desafortunadamente. http://dev.mysql.com/doc/refman/5.7/en/myisam-storage-engine.html – Andy

181

EDIT: Como se ha señalado en los comentarios, esta no es la respuesta correcta a la pregunta PO, pero es útil para 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 `<yourtable>`; 

que consideran que esta respuesta aquí: MySQL : show constraints on tables command

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

+29

Esto muestra todas las restricciones en '', no todas las restricciones que apuntan a ''. – Barmar

+11

Como dice @Barmar, esto es completamente incorrecto; mostrará las claves foráneas que pertenecen a la tabla especificada, pero no mostrará las teclas foráneas que señalan *** TO *** 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. –

+1

@MarkAmery: este es el primer resultado de 'mostrar claves externas mysql' en google, puede ser por eso;) – Jigar

2

Una forma rápida de una lista de sus FKs (referencias de clave externa) mediante 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 no asumen que las restricciones y todos los que hacen referencia a tablas de referencia y están en el mismo esquema.

Añade tu propio comentario.

Fuente: el manual oficial de mysql.

7

Esta solución no sólo mostrar todas las relaciones, sino también el nombre de restricción, que se requiere en algunos casos (por ejemplo, dejar caer 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 comprobar las tablas de una base de datos específica, en el final de la consulta añada 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ífica, añadir

y table_name = 'table_name

al final de la consulta.

Inspirado por este post here

17

Como una alternativa a la respuesta del nodo, si se utiliza InnoDB y definido FK se podía consultar el ejemplo de base de datos INFORMATION_SCHEMA:

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

de claves externas de <mesa>, o

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

de claves ajenas a <mesa>

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

+1

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

+0

Al hacer un descubrimiento acerca de una tabla, no debe olvidar que las claves externas se pueden establecer ¡AMBAS maneras! – Encoder

2

Para encontrar todas las tablas que contienen una determinada clave externa como employee_id

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

Usando REFERENCED_TABLE_NAME no siempre funciona y puede ser un valor NULL. La siguiente consulta puede trabajar en su lugar:

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

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; 
Cuestiones relacionadas