मैं किसी तालिका या स्तंभ की सभी विदेशी कुंजियाँ कैसे देख सकता हूँ?


567

MySQL में, मैं किसी विशेष तालिका की ओर इशारा करते हुए सभी विदेशी प्रमुख बाधाओं की एक सूची कैसे प्राप्त करूं? एक विशेष कॉलम यह ओरेकल के प्रश्न के समान ही है , लेकिन MySQL के लिए।

जवाबों:


764

एक मेज के लिए:

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

एक कॉलम के लिए:

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

मूल रूप से, हमने REFERENCED_TABLE_NAME को REFERENCED_COLUMN_NAME के ​​साथ उस खंड में बदल दिया है।


26
यह हमेशा मुझे एक खाली सेट देता है, जबकि नीचे नोड द्वारा प्रस्तावित क्वेरी ठीक काम करती है
एक्यूट

7
@ उत्तर: क्या आप सुनिश्चित हैं कि आप सही तालिका के बारे में पूछ रहे हैं? यदि नोड की क्वेरी काम करती है, तो आप संभावित रूप से अन्य दिशा के बारे में पूछ रहे हैं। ?
विंको वर्सालोविच

3
ऐसा लगता है कि मैंने आपको गलत समझा, क्योंकि मैं <तालिका> :) से संदर्भित कुंजियों के लिए क्वेरी कर रहा था: (हां, मैंने "<तालिका>" XD) के बजाय तालिका का नाम लिखा है
एक्यूट

4
जब तक आप सुनिश्चित नहीं होते कि आपकी तालिका का नाम अद्वितीय है, तब तक आप संभवतः अपनी क्वेरी को किसी विशेष डेटाबेस तक ही सीमित रखना चाहेंगे। इसमें क्लॉज़ को कहाँ बदलें:where REFERENCED_TABLE_SCHEMA = 'mydatabase' and REFERENCED_TABLE_NAME = 'mytable'
user12345

गैर रूट उपयोगकर्ता के मामले में यह अभ्यस्त काम नहीं करेगा, हालांकि उपयोगकर्ता के पास डेटाबेस के लिए सभी अनुमतियाँ हैं
दीपक राम

275

संपादित करें: जैसा कि टिप्पणियों में बताया गया है, यह ओपीएस प्रश्न का सही उत्तर नहीं है, लेकिन इस आदेश को जानना उपयोगी है। यह प्रश्न Google में दिखाया गया था कि मैं क्या देख रहा था, और लगा कि मैं दूसरों को खोजने के लिए इस उत्तर को छोड़ दूंगा।

SHOW CREATE TABLE `<yourtable>`;

मुझे यह जवाब यहां मिला: MySQL: टेबल कमांड पर अड़चनें दिखाना

मुझे इस तरह की आवश्यकता थी क्योंकि मैं यह देखना चाहता था कि एफके कैसे कार्य करता है, बजाय इसके कि वह मौजूद है या नहीं।


37
यह सभी बाधाओं को दर्शाता है, सभी बाधाओं को <yourtable>नहीं जो इंगित करता है <yourtable>
बरमार

18
जैसा @Barmar कहता है, यह पूरी तरह से गलत है; यह निर्दिष्ट तालिका से संबंधित विदेशी कुंजी दिखाई देगा, लेकिन उनका कहना है विदेशी कुंजी नहीं दिखाया जाएगा करने के लिए टेबल, जो है क्या प्रश्न के लिए पूछता है। पता नहीं कैसे यह 50 upvotes मिला; मुझे लगता है कि लोग यहां समाप्त हो गए जब वास्तव में वे विपरीत प्रश्न के उत्तर की तलाश कर रहे थे, वैसे भी उनका जवाब यहां मिला, और upvoting से पहले मूल प्रश्न (या यहां तक ​​कि इसके शीर्षक) को पढ़ने से परेशान नहीं किया।
मार्क अमेरी

2
@ मर्केमी: यह display foreign keys mysqlगूगल का पहला परिणाम है , इसीलिए ऐसा हो सकता है;)
जिगर

1
यह वास्तव में सभी बाधाओं को दर्शाता है जो मौजूद हैं, phpmyadmin केवल आपको अपनी तालिका की ओर इशारा करते हुए दिखाएगा। एक ORM उपकरण के साथ डुप्लिकेट से बचने के लिए पर्याप्त अच्छा लगता है
william.eyidi

3
यह वही है जिसकी मैं तलाश कर रहा था, इसलिए इसे पोस्ट करने के लिए धन्यवाद, हालांकि इसने ओपी के सवाल का जवाब नहीं दिया। एक रिश्ते में दोनों दिशाओं में देखने के तरीके को जानने के लिए कभी भी दर्द नहीं होता है!
चार्ल्स वुड

75

यदि आप InnoDB का उपयोग करते हैं और FK को परिभाषित करते हैं, तो आप information_schema डेटाबेस को क्वेरी कर सकते हैं जैसे:

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
वास्तव में, यह गलत दिशा को इंगित करता है। वह क्वेरी सभी विदेशी कुंजियों को दर्शाती है, जो 'mytable' की ओर इशारा करती हैं, न कि सभी विदेशी कुंजियों को 'mytable' की ओर इशारा करती हैं।
क्रिश्चियन ओउर्ड

1
यह मेरे मामले में बेहतर काम करता है। मुझे इनोबीडी इंजन माईसैम या एनडीबी को बदलने में सक्षम होने के लिए एक मेज से हर विदेशी कुंजी बाधा (और केवल उन) को छोड़ने की आवश्यकता है।
कोहनी रॉबर्ट

आप REFERENTIAL_CONSTRAINTS तालिका से दोनों दिशाओं में विदेशी कुंजी प्राप्त कर सकते हैं - मैंने क्वेरी के साथ एक और उत्तर जोड़ा है।
क्रिस

45

कुछ उपयोगी जानकारी जोड़ने के लिए एक पुराने उत्तर पर पोस्ट करना।

मुझे भी ऐसी ही समस्या थी, लेकिन मैं REFERENCED तालिका और स्तंभ नामों के साथ CONSTRAINT_TYPE भी देखना चाहता था। इसलिए,

  1. अपनी तालिका में सभी FK देखने के लिए:

    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. अपने स्कीमा में सभी तालिकाओं और FK को देखने के लिए:

    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. अपने डेटाबेस में सभी FK देखने के लिए:

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

याद है!

यह InnoDB स्टोरेज इंजन का उपयोग कर रहा है। यदि आप उन्हें जोड़ने के बाद दिखाने के लिए कोई भी विदेशी कुंजी प्राप्त नहीं कर सकते, तो यह संभवत: इसलिए है क्योंकि आपकी तालिकाएँ MyISAM का उपयोग कर रही हैं।

जाँच करने के लिए:

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

इसे ठीक करने के लिए, इसका उपयोग करें:

ALTER TABLE `<yourtable>` ENGINE=InnoDB;

8
उन प्रश्नों को बहुत तेजी से (2 सेकंड से 0.0015 सेकेंड तक) यदि आप k.TABLE_SCHEMA = DATABASE () और k.TABLE_NAME = '<table>' को निर्दिष्ट करते हैं, तो WHERE क्लॉज पर, जैसा कि लगभग p.mysql.com/doc/refman
en/

2
बहुत बढ़िया जवाब। क्या आपके पास MyISAM का कोई समाधान है?
ब्यू बूचार्ड

2
MyISAM दुर्भाग्य से, विदेशी कुंजी का समर्थन नहीं करता है। dev.mysql.com/doc/refman/5.7/en/myisam-storage-engine.html
एंडी

24

नोड के उत्तर के विकल्प के रूप में, यदि आप InnoDB का उपयोग करते हैं और FK को परिभाषित करते हैं तो आप information_schema डेटाबेस को क्वेरी कर सकते हैं:

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

<तालिका>, या से विदेशी कुंजी के लिए

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

विदेशी कुंजी के लिए <तालिका>

आप चाहें तो UPDATE_RULE और DELETE_RULE भी प्राप्त कर सकते हैं।


2
मैं व्यक्तिगत रूप से इस जवाब को पसंद करता हूं क्योंकि REFERENTIAL_CONSTRAINTS तालिका का उपयोग करने से आपको अपडेट और कैस्केड नियम मिलता है। +1
ल्यूक माधंगा

एक मेज के बारे में खोज करते हुए आपको यह नहीं भूलना चाहिए कि विदेशी कुंजी को स्थापित किया जा सकता है!
एनकोडर

11

यह समाधान न केवल सभी संबंधों को प्रदर्शित करेगा, बल्कि बाधा नाम भी होगा, जो कुछ मामलों में आवश्यक है (जैसे ड्रॉप गर्भनिरोधक):

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;

यदि आप किसी विशिष्ट डेटाबेस में तालिकाओं की जांच करना चाहते हैं, तो क्वेरी के अंत में स्कीमा नाम जोड़ें:

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

इसी तरह, एक विशिष्ट कॉलम नाम के लिए, जोड़ें

और table_name = 'table_name

क्वेरी के अंत में।

यहाँ इस पोस्ट से प्रेरित है


7

REFERENCED_TABLE_NAME का उपयोग करना हमेशा काम नहीं करता है और एक पूर्ण मान हो सकता है। निम्नलिखित क्वेरी इसके बजाय काम कर सकती है:

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

4

अपने एफके (विदेशी कुंजी संदर्भ) को सूचीबद्ध करने का एक त्वरित तरीका

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;

यह क्वेरी मानती है कि बाधाएँ और सभी संदर्भित और संदर्भित तालिका एक ही स्कीमा में हैं।

अपनी टिप्पणी जोड़ें।

स्रोत: आधिकारिक mysql मैनुअल


3

मैं जिस समाधान के साथ आया वह नाजुक है; यह विदेशी कुंजियों के लिए django के नामकरण सम्मेलन पर निर्भर करता है।

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

फिर, शेल में,

grep 'refs_tablename_id' mysql_output

2

किसी विशेष विदेशी कुंजी वाले सभी तालिकाओं को खोजने के लिए जैसेemployee_id

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

2

यदि आप विदेशी कुंजी कॉलम का नाम भी प्राप्त करना चाहते हैं:

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;

महान समाधान धन्यवाद! मुझे कॉलम नाम की जरूरत थी, इसे जोड़ने के लिए: 'k.COLUMN_NAME'
एंड्रियास
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.