Wie finde ich alle Tabellen mit Fremdschlüsseln, die auf eine bestimmte table.column verweisen und Werte für diese Fremdschlüssel haben?

272

Ich habe eine Tabelle, deren Primärschlüssel in mehreren anderen Tabellen als Fremdschlüssel referenziert wird. Beispielsweise:

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

Jetzt weiß ich nicht, wie viele Tabellen in der Datenbank Fremdschlüssel in X enthalten, wie die Tabellen Y und Z. Gibt es eine SQL-Abfrage, mit der ich Folgendes zurückgeben kann:

  1. Eine Liste von Tabellen mit Fremdschlüsseln in X.
  2. UND welche dieser Tabellen haben tatsächlich Werte im Fremdschlüssel
Mel
quelle

Antworten:

384

Bitte schön:

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

Wenn Sie mehrere Datenbanken mit ähnlichen Tabellen- / Spaltennamen haben, möchten Sie Ihre Abfrage möglicherweise auch auf eine bestimmte Datenbank beschränken:

SELECT *
FROM
  KEY_COLUMN_USAGE
WHERE
  REFERENCED_TABLE_NAME = 'X'
  AND REFERENCED_COLUMN_NAME = 'X_id'
  AND TABLE_SCHEMA = 'your_database_name';
Alex N.
quelle
7
SELECT TABLE_NAME besser als SELECT *
zloctb
Für welche Art von Datenbank ist dies nützlich? MySql?
Cirelli94
2
@ Cirelli94 Die Frage ist als MySQL-Frage gekennzeichnet.
Mikeschuld
61

MySQL 5.5 Referenzhandbuch: "InnoDB- und FOREIGN KEY-Einschränkungen"

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
quelle
21

Diese Lösung zeigt nicht nur alle Relationen an, sondern auch den in einigen Fällen erforderlichen Einschränkungsnamen (z. B. Drop-Einschränkung):

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;

Wenn Sie Tabellen in einer bestimmten Datenbank überprüfen möchten, fügen Sie Folgendes hinzu:

AND table_schema = 'database_name';
Panayotis
quelle
15

Sie finden alle schemabezogenen Informationen in der weise benannten information_schemaTabelle.

Vielleicht möchten Sie die Tabelle REFERENTIAL_CONSTRAINTSund überprüfen KEY_COLUMN_USAGE. Ersteres sagt Ihnen, auf welche Tabellen andere verweisen. Letzteres zeigt Ihnen, wie ihre Felder zusammenhängen.

Seb
quelle
5

Auflistung aller Fremdschlüssel in einer Datenbank einschließlich Beschreibung

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

Beschränkung auf eine bestimmte Spalte in einer Tabellentabelle

AND i1.table_name = 'target_tb_name' AND i1.column_name = 'target_col_name'
Bortunac
quelle
3

Ich habe einen kleinen Bash-Onliner geschrieben , den Sie in ein Skript schreiben können, um eine benutzerfreundliche Ausgabe zu erhalten:

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

Die Ausführung: mysql_references_to transaccion(wobei transaccion ein zufälliger Tabellenname ist) ergibt eine Ausgabe wie folgt :

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
quelle
-4

Am einfachsten:
1. Öffnen Sie phpMyAdmin.
2. Klicken Sie mit der linken Maustaste auf den Datenbanknamen.
3. Suchen Sie in der oberen rechten Ecke die Registerkarte "Designer"

Dort werden alle Einschränkungen angezeigt.

Mantas D.
quelle