¿Cómo encontrar todas las tablas que tienen claves foráneas que hacen referencia a table.column en particular y tienen valores para esas claves foráneas?


272

Tengo una tabla cuya clave principal se hace referencia en varias otras tablas como una clave externa. Por ejemplo:

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

Ahora, no sé cuántas tablas hay en la base de datos que contienen claves foráneas en X como las tablas Y y Z. ¿Hay alguna consulta SQL que pueda usar para devolver:

  1. Una lista de tablas que tienen claves foráneas en X
  2. Y cuáles de esas tablas realmente tienen valores en la clave externa

Respuestas:


384

Aqui tienes:

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

Si tiene varias bases de datos con tablas / nombres de columnas similares, también puede limitar su consulta a una base de datos particular:

SELECT *
FROM
  KEY_COLUMN_USAGE
WHERE
  REFERENCED_TABLE_NAME = 'X'
  AND REFERENCED_COLUMN_NAME = 'X_id'
  AND TABLE_SCHEMA = 'your_database_name';

77
SELECCIONE TABLE_NAME más mejor que SELECCIONAR *
zloctb

¿Para qué tipo de DB es útil? MySql?
Cirelli94

2
@ Cirelli94 La pregunta está etiquetada como una pregunta de MySQL.
mikeschuld

61

Manual de referencia de MySQL 5.5: "Restricciones de InnoDB y 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;

21

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

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, agregue lo siguiente:

AND table_schema = 'database_name';

15

Puede encontrar toda la información relacionada con el esquema en el nombre sabio information_schema tabla .

Es posible que desee consultar la tabla REFERENTIAL_CONSTRAINTSy KEY_COLUMN_USAGE. El primero le dice a qué tablas hacen referencia otros; este último le dirá cómo se relacionan sus campos.


5

Listado de todas las claves foráneas en una base de datos, incluida la descripción

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

restringiendo a una columna específica en una tabla

AND i1.table_name = 'target_tb_name' AND i1.column_name = 'target_col_name'

3

Escribí un pequeño bash onliner que puedes escribir en un script para obtener una salida amigable:

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

Entonces la ejecución: mysql_references_to transaccion(donde transaccion es un nombre de tabla aleatorio) da una salida como esta:

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

-4

Más fácil:
1. Abra phpMyAdmin
2. A la izquierda, haga clic en el nombre de la base de datos
3. En la esquina superior derecha, busque la pestaña "Diseñador"

Todas las restricciones se mostrarán allí.

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.