Bir tablo veya sütundaki tüm yabancı anahtarları nasıl görebilirim?


Yanıtlar:


764

Tablo için:

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

Bir Sütun için:

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

Temel olarak, nerede yan tümcesinde REFERENCED_TABLE_NAME ile REFERENCED_COLUMN_NAME ile değiştirdik.


26
Bu, her zaman boş bir küme verirken, aşağıdaki Düğüm tarafından önerilen sorgu iyi çalışır
akut

7
@Acute: Doğru tabloyu sorduğunuzdan emin misiniz? Düğümün sorgusu işe yararsa, muhtemelen diğer yönü soruyorsunuzdur (örn., Dengesiz anahtarlar değil, dengesiz anahtarlar değil.) Bu, tablo adıyla ve '<' ve '>' olmadan '<table>' yazmanızı bekler. ?
Vinko Vrsalovic

3
Sorgunuzu yanlış anladığım anlaşılıyor, çünkü <table> :) 'dan referans alan anahtarları sorguluyordum (evet, "<table>" XD yerine tablo adı yazdım)
akut

4
Tablo adınızın benzersiz olduğundan emin değilseniz, sorgunuzu belirli bir veritabanıyla da kısıtlamak isteyeceksinizdir. where REFERENCED_TABLE_SCHEMA = 'mydatabase' and REFERENCED_TABLE_NAME = 'mytable'
Where

Kullanıcı veritabanına tüm izinlere sahip olsa bile, bu kök olmayan kullanıcı durumunda çalışmaz
Deepak Ram

275

EDIT: Yorumlarda belirtildiği gibi, bu OPs sorusuna doğru cevap değil, ama bu komutu bilmek yararlıdır. Bu soru Google'da aradığım şey için ortaya çıktı ve bu cevabı diğerlerinin bulması için bırakacağımı düşündüm.

SHOW CREATE TABLE `<yourtable>`;

Bu yanıtı burada buldum: MySQL: Tablolar komutunda kısıtlamaları göster

Bu şekilde ihtiyacım vardı çünkü FK'nin var olup olmadığını görmek yerine FK'nin nasıl çalıştığını görmek istedim.


37
Bu, işaret eden tüm kısıtlamaları <yourtable>değil, içindeki tüm kısıtlamaları gösterir <yourtable>.
Barmar

18
@Barmar'ın dediği gibi, bu tamamen yanlış; bu, belirli tabloya ait yabancı anahtarları gösterecektir, ancak işaret yabancı anahtarlar göstermeyecektir İÇİN soru sorar ne masa,. Bunun nasıl 50 oy aldığını bilmiyorum; Sanırım insanlar, tam tersi sorunun cevabını aradıklarında burada sona erdi, yine de cevaplarını burada buldular ve yükseltmeden önce orijinal soruyu (hatta başlığını) okuma zahmetine girmediler.
Mark Amery

2
@ MarkAmery: Bu display foreign keys mysqlGoogle'da ilk sonucudur , nedeni bu olabilir;)
Jigar

1
thisi aslında var olan tüm kısıtlamaları gösterir, phpmyadmin sadece masanıza işaret edenleri gösterir. ORM aracıyla kopyaları önlemek için yeterince iyi görünüyor
william.eyidi

3
Aradığım şey buydu, bu yüzden OP'nin sorusunu cevaplamamasına rağmen yayınladığınız için teşekkürler. Bir ilişkide her iki yöne nasıl bakacağınızı bilmek asla acımaz!
Charles Wood

75

InnoDB ve tanımlanmış FK'leri kullanıyorsanız, information_schema veritabanını sorgulayabilirsiniz, örneğin:

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
aslında bu yanlış yönü gösteriyor. bu sorgu 'mytable' ı gösteren tüm yabancı anahtarları gösterir, 'mytable' ı gösteren tüm yabancı anahtarları göstermez.
Christian Oudard

1
Bu benim durumumda daha iyi çalışıyor. InnoDB motoru MyISAM veya NDB değiştirebilmek için her yabancı anahtar kısıtlamasını (ve sadece bir tablodan) düşürmem gerekiyor.
Kohányi Róbert

REFERENTIAL_CONSTRAINTS tablosundan her iki yönde yabancı anahtarlar alabilirsiniz - Sorguyla başka bir cevap ekledim.
ChrisV

45

Yararlı bilgiler eklemek için eski bir yanıtta yayın.

Benzer bir sorunum vardı, ancak REFERENCED tablo ve sütun adları ile birlikte CONSTRAINT_TYPE görmek istedim. Yani,

  1. Masanızdaki tüm FK'leri görmek için:

    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. Şemanızdaki tüm tabloları ve FK'leri görmek için:

    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. Veritabanınızdaki tüm FK'leri görmek için:

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

Hatırlamak!

Bu InnoDB depolama motorunu kullanıyor. Bunları ekledikten sonra göstermek için herhangi bir yabancı anahtar alamıyorsanız, büyük olasılıkla tablolarınız MyISAM kullanıyor olabilir.

Kontrol etmek:

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

Düzeltmek için şunu kullanın:

ALTER TABLE `<yourtable>` ENGINE=InnoDB;

8
WHERE yan tümcesinde k.TABLE_SCHEMA = DATABASE () ve k.TABLE_NAME = '<table>' belirtirseniz bu sorgular, burada belgelendiği gibi dev.mysql.com/doc/refman /5.5/en/...
guigouz

2
mükemmel cevap. MyISAM için çözümünüz var mı?
Beau Bouchard

2
MyISAM maalesef yabancı anahtarları desteklemiyor. dev.mysql.com/doc/refman/5.7/tr/myisam-storage-engine.html
Andy

24

Düğümün cevabına alternatif olarak, InnoDB ve tanımlanmış FK'leri kullanırsanız, information_schema veritabanını sorgulayabilirsiniz:

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

<table> 'dan gelen yabancı anahtarlar için veya

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

<table> tuşlarına yabancı anahtarlar için

İsterseniz UPDATE_RULE ve DELETE_RULE dosyalarını da edinebilirsiniz.


2
Ben şahsen REFERENTIAL_CONSTRAINTS tablosunu kullanarak güncelleme ve art arda kuralını verdiği için bu cevabı tercih ederim. +1
Luke Madhanga

Bir tablo hakkında keşif yaparken, yabancı anahtarların İYİ şekilde kurulabileceğini unutmamalısınız!
Enkoder

11

Bu çözüm sadece tüm ilişkileri değil, aynı zamanda bazı durumlarda gerekli olan kısıtlama adını da gösterecektir (örn. Bırakma kontratı):

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;

Belirli bir veritabanındaki tabloları kontrol etmek istiyorsanız, sorgunun sonuna şema adını ekleyin:

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

Benzer şekilde, belirli bir sütun adı için

ve tablo_adı = 'tablo_adı

sorgusunun sonunda.

Buradaki gönderiden esinlenerek


7

REFERENCED_TABLE_NAME kullanımı her zaman işe yaramaz ve NULL değer olabilir. Bunun yerine aşağıdaki sorgu çalışabilir:

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

4

Kullanarak FK'lerinizi (Yabancı Anahtar referansları) listelemenin hızlı bir yolu

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;

Bu sorgu, kısıtlamaların ve tüm başvurulan ve başvuru tablolarının aynı şemada olduğunu varsayar.

Kendi yorumunuzu ekleyin.

Kaynak: resmi mysql el kitabı.


3

Geldiğim çözüm kırılgandır; django'nun yabancı anahtarlar için adlandırma kuralına dayanıyor.

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

Sonra, kabuğun içinde,

grep 'refs_tablename_id' mysql_output

2

Belirli bir yabancı anahtar içeren tüm tabloları bulmak gibiemployee_id

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

2

Yabancı anahtar sütununun adını da almak istiyorsanız:

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;

Teşekkürler harika bir çözüm! Eklemek için sütun adına da ihtiyacım vardı: 'k.COLUMN_NAME'
Andreas
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.