Wie sehe ich alle Fremdschlüssel für eine Tabelle oder Spalte?

Wie erhalte ich in MySQL eine Liste aller Fremdschlüsselbeschränkungen, die auf eine bestimmte Tabelle verweisen? eine bestimmte Spalte? Dies ist dasselbe wie diese Oracle-Frage , aber für MySQL.

413

11 Antworten

Für eine Tabelle:

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
hinzugefügt
@Acute: Sind Sie sicher, dass Sie nach der richtigen Tabelle fragen? Wenn die Abfrage von Node funktioniert, dann fragen Sie wahrscheinlich nach der anderen Richtung (dh Schlüssel FROM MYTABLE, nicht Schlüssel TO MYTABLE). Dies erwartet, dass Sie '<table>' mit dem Tabellennamen und ohne '<' und '>' ?
hinzugefügt der Autor Vinko Vrsalovic, Quelle
Warum wird so viel verlangt? Warum machen Sie es nicht so einfach wie das Auswählen von Zeilen?
hinzugefügt der Autor Lealo, Quelle
Einverstanden, ich bekomme immer nur einen leeren Satz hier! Andys Antwort funktionierte am besten für mich.
hinzugefügt der Autor omarjebari, Quelle
@DeepakRam Dies funktioniert perfekt für mich mit einem privilegierten Benutzer, der nicht der Root-Benutzer ist.
hinzugefügt der Autor Matthew Read, Quelle
Das hat perfekt für mich funktioniert. Ich habe die meisten Privilegien, aber nicht root. Du bist ein Lebensretter.
hinzugefügt der Autor jDub9, Quelle
Dies gibt mir immer einen leeren Satz, während die von Node vorgeschlagene Abfrage in Ordnung ist
hinzugefügt der Autor Acute, Quelle
Scheint so, als hätte ich die Abfrage missverstanden, weil ich nach Schlüsseln gesucht habe, die auf die <table> verweisen :) (ja, ich habe den Tabellennamen anstelle von "<table>" XD geschrieben)
hinzugefügt der Autor Acute, Quelle
Wenn Sie sich nicht sicher sind, dass Ihr Tabellenname eindeutig ist, sollten Sie Ihre Abfrage wahrscheinlich auch auf eine bestimmte Datenbank beschränken. Ändern Sie die WHERE-Klausel wie folgt: where REFERENCED_TABLE_SCHEMA = 'mydatabase' und REFERENCED_TABLE_NAME = 'MYTABLE'
hinzugefügt der Autor user12345, Quelle
Dies funktioniert nicht bei Nicht-Root-Benutzern, obwohl der Benutzer über alle Berechtigungen für die Datenbank verfügt
hinzugefügt der Autor Deepak Ram, Quelle

EDIT: Wie in den Kommentaren darauf hingewiesen, ist dies nicht die richtige Antwort auf die Frage OP, aber es ist nützlich, diesen Befehl zu kennen. Diese Frage tauchte bei Google auf, wonach ich suchte, und dachte mir, ich würde diese Antwort den anderen überlassen.

SHOW CREATE TABLE ``;

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

Ich brauchte diesen Weg, weil ich sehen wollte, wie der FK funktionierte, anstatt nur zu sehen, ob er existierte oder nicht.

194
hinzugefügt
Wie @Barmar sagt, das ist völlig falsch; Es zeigt die Fremdschlüssel an, die zu der angegebenen Tabelle gehören, zeigt jedoch keine Fremdschlüssel an, die TO auf die Tabelle zeigen, wonach die Frage gefragt wird. Keine Ahnung, wie das 50 Upvotes bekommen hat; Ich nehme an, die Leute sind hier gelandet, als sie wirklich nach der Antwort auf die gegenteilige Frage gesucht haben, ihre Antwort hier sowieso gefunden haben und sich nicht die ursprüngliche Frage (oder auch nur ihren Titel) vor der Abstimmung angehört haben.
hinzugefügt der Autor Mark Amery, Quelle
Dies zeigt alle Einschränkungen in , nicht alle Einschränkungen, die auf verweisen.
hinzugefügt der Autor Barmar, Quelle
Thisi zeigt tatsächlich alle Einschränkungen, die existieren, phpmyadmin wird Ihnen nur den zeigen, der auf Ihren Tisch zeigt. scheint gut genug, um Duplikate mit einem ORM-Tool zu vermeiden
hinzugefügt der Autor william.eyidi, Quelle
@ MarkAmery: das ist das erste Ergebnis von Anzeige Fremdschlüssel MySQL in Google, möglicherweise deshalb;)
hinzugefügt der Autor Jigar, Quelle
Das ist, was ich gesucht habe, also danke für das Posten, obwohl es die Frage von OP nicht beantwortet hat. Es tut nie weh zu wissen, wie man in einer Beziehung in beide Richtungen schaut!
hinzugefügt der Autor Charles Wood, Quelle

Wenn Sie InnoDB und definierte FKs verwenden, können Sie die Datenbank information_schema abfragen:

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
hinzugefügt
Eigentlich deutet das auf die falsche Richtung hin. Diese Abfrage zeigt alle Fremdschlüssel an, die von "MeineTabelle" zeigen, und nicht alle Fremdschlüssel, die auf "MeineTabelle" zeigen.
hinzugefügt der Autor Christian Oudard, Quelle
Sie können Fremdschlüssel in beide Richtungen aus der REFERENTIAL_CONSTRAINTS-Tabelle abrufen - ich habe eine andere Antwort mit der Abfrage hinzugefügt.
hinzugefügt der Autor ChrisV, Quelle
Dieser funktioniert in meinem Fall besser. Ich muss jede Fremdschlüsseleinschränkung (und nur diese) aus einer Tabelle löschen, um die InnoDB-Engine MyISAM oder NDB ändern zu können.
hinzugefügt der Autor Kohányi Róbert, Quelle

Auf eine alte Antwort schreiben, um nützliche Informationen hinzuzufügen.

Ich hatte ein ähnliches Problem, aber ich wollte auch den CONSTRAINT_TYPE zusammen mit den REFERENCED Tabellen- und Spaltennamen sehen. Damit,

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

Erinnere dich!

Dies verwendet die InnoDB-Speicher-Engine. Wenn Sie scheinbar keine Fremdschlüssel nach dem Hinzufügen erhalten, liegt das wahrscheinlich daran, dass Ihre Tabellen MyISAM verwenden.

Überprüfen:

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

Um dies zu beheben, verwenden Sie Folgendes:

ALTER TABLE `` ENGINE=InnoDB;
32
hinzugefügt
MyISAM unterstützt leider keine Fremdschlüssel. dev.mysql.com/doc/refman/5.7/ de/myisam-storage-engine.html
hinzugefügt der Autor Andy, Quelle
gute Antwort. Haben Sie Lösungen für MyISAM?
hinzugefügt der Autor Beau Bouchard, Quelle
Diese Abfragen werden viel schneller ausgeführt (von 2 Sekunden bis 0,0015 Sekunden), wenn Sie k.TABLE_SCHEMA = DATABASE() und k.TABLE_NAME = '<table>' in der WHERE-Klausel angeben, wie hier dokumentiert. dev.mysql.com/doc/refman/5.5/en/…
hinzugefügt der Autor guigouz, Quelle

Als eine Alternative zur Antwort von Node könnten Sie, wenn Sie InnoDB und definierte FKs verwenden, die Datenbank information_schema abfragen:

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
hinzugefügt
Ich persönlich bevorzuge diese Antwort, da die Verwendung der Tabelle REFERENTIAL_CONSTRAINTS die Aktualisierungs- und Kaskadenregel enthält. +1
hinzugefügt der Autor Luke Madhanga, Quelle
Bei der Entdeckung einer Tabelle sollten Sie nicht vergessen, dass Fremdschlüssel auf BEIDEN Wegen eingerichtet werden können!
hinzugefügt der Autor Encoder, Quelle

Diese Lösung zeigt nicht nur alle Beziehungen an, sondern auch den Constraint-Namen, der in einigen Fällen erforderlich ist (z. B. drop 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;

Wenn Sie Tabellen in einer bestimmten Datenbank überprüfen möchten, fügen Sie am Ende der Abfrage den Tabellennamen hinzu:

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

Für einen bestimmten Spaltennamen fügen Sie hinzu

und Tabellenname = 'Tabellenname

am Ende der Abfrage.

Inspired by this post here

7
hinzugefügt

Eine schnelle Möglichkeit, Ihre FKs (Fremdschlüsselreferenzen) mit Hilfe der

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;

Diese Abfrage geht davon aus, dass sich die Integritätsbedingungen und alle referenzierten und referenzierenden Tabellen im selben Schema befinden.

Fügen Sie Ihren eigenen Kommentar hinzu.

Quelle: das offizielle mysql-Handbuch.

2
hinzugefügt

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
hinzugefügt

Die Lösung, die ich gefunden habe, ist zerbrechlich. Es beruht auf der Namenskonvention von Django für Fremdschlüssel.

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

Dann in der Schale,

grep 'refs_tablename_id' mysql_output
1
hinzugefügt

Die Verwendung von REFERENCED_TABLE_NAME funktioniert nicht immer und kann ein NULL-Wert sein. Die folgende Abfrage kann stattdessen funktionieren:

select * from INFORMATION_SCHEMA.KEY_COLUMN_USAGE where TABLE_NAME = '<table>';
1
hinzugefügt

Wenn Sie auch den Namen der Fremdschlüsselspalte erhalten möchten:

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
hinzugefügt