MySQL एक विदेशी प्रमुख बाधा में आवश्यक इंडेक्स को ड्रॉप नहीं कर सकता है


155

मुझे एक कॉलम जोड़ने के लिए अपने मौजूदा डेटाबेस को बदलना होगा। नतीजतन मैं उस नए कॉलम को शामिल करने के लिए UNIQUE फ़ील्ड को भी अपडेट करना चाहता हूं। मैं वर्तमान सूचकांक को हटाने की कोशिश कर रहा हूं, लेकिन त्रुटि मिलती रही हैMySQL Cannot drop index needed in a foreign key constraint

CREATE TABLE mytable_a (
ID          TINYINT NOT NULL AUTO_INCREMENT PRIMARY KEY,
Name        VARCHAR(255) NOT NULL,
UNIQUE(Name)
) ENGINE=InnoDB;

CREATE TABLE mytable_b (
ID          TINYINT NOT NULL AUTO_INCREMENT PRIMARY KEY,
Name        VARCHAR(255) NOT NULL,
UNIQUE(Name)
) ENGINE=InnoDB;

CREATE TABLE mytable_c (
ID          TINYINT NOT NULL AUTO_INCREMENT PRIMARY KEY,
Name        VARCHAR(255) NOT NULL,
UNIQUE(Name)
) ENGINE=InnoDB;


CREATE TABLE `mytable` (
  `ID` int(11) NOT NULL AUTO_INCREMENT,
  `AID` tinyint(5) NOT NULL,
  `BID` tinyint(5) NOT NULL,
  `CID` tinyint(5) NOT NULL,
  PRIMARY KEY (`ID`),
  UNIQUE KEY `AID` (`AID`,`BID`,`CID`),
  KEY `BID` (`BID`),
  KEY `CID` (`CID`),
  CONSTRAINT `mytable_ibfk_1` FOREIGN KEY (`AID`) REFERENCES `mytable_a` (`ID`) ON DELETE CASCADE,
  CONSTRAINT `mytable_ibfk_2` FOREIGN KEY (`BID`) REFERENCES `mytable_b` (`ID`) ON DELETE CASCADE,
  CONSTRAINT `mytable_ibfk_3` FOREIGN KEY (`CID`) REFERENCES `mytable_c` (`ID`) ON DELETE CASCADE
) ENGINE=InnoDB;




mysql> ALTER TABLE mytable DROP INDEX AID;
ERROR 1553 (HY000): Cannot drop index 'AID': needed in a foreign key constraint

मान लिया जाये कि UNIQUE KEY AIDmytable पर?
माइक पर्सल

जवाबों:


228

आपको विदेशी कुंजी छोड़नी होगी। MySQL में विदेशी कुंजियाँ स्वचालित रूप से तालिका पर एक सूचकांक बनाती हैं ( विषय पर एक SO प्रश्न था )।

ALTER TABLE mytable DROP FOREIGN KEY mytable_ibfk_1 ; 

12
आप इंडेक्स छोड़ने के बाद इसे वापस जोड़ना चाह सकते हैं: अलर्ट टेबल mytableकनेक्ट mytable_ibfk_1फ़ॉरेस्ट कुंजी ( AID) संदर्भ mytable_a( ID) DELETE CASCADE पर;
laffuste

8
यह बहुत अच्छा है, लेकिन अगर मेरी FOREIGN KEYबाधा गुमनाम थी तो मैं क्या कर सकता हूं ?
पीहट

@ नीचे दिए गए मेरे जवाब की जांच करें stackoverflow.com/a/54145440/2305119
थिंज

1
नोट: विदेशी कुंजी स्पष्ट नहीं हो सकती है। तालिका और स्तंभ से संबंधित सभी विदेशी कुंजियों को खोजने के लिए, आप इस क्वेरी का उपयोग कर सकते हैं: dba.stackexchange.com/questions/102371/…
charlax

84

चरण 1

सूची विदेशी कुंजी (ध्यान दें कि सूचकांक नाम से अलग है)

SHOW CREATE TABLE  <Table Name>

परिणाम आपको विदेशी कुंजी नाम दिखाएगा।

प्रारूप:

CONSTRAINT `FOREIGN_KEY_NAME` FOREIGN KEY (`FOREIGN_KEY_COLUMN`) REFERENCES `FOREIGN_KEY_TABLE` (`id`),

चरण 2

ड्रॉप (विदेशी / प्राथमिक / कुंजी) कुंजी

ALTER TABLE <Table Name> DROP FOREIGN KEY <Foreign key name>

चरण 3

सूचकांक को गिरा दें।


18

अगर आपका मतलब है कि आप ऐसा कर सकते हैं:

CREATE TABLE mytable_d (
ID          TINYINT NOT NULL AUTO_INCREMENT PRIMARY KEY,
Name        VARCHAR(255) NOT NULL,
UNIQUE(Name)
) ENGINE=InnoDB;


ALTER TABLE mytable
ADD COLUMN DID tinyint(5) NOT NULL,
ADD CONSTRAINT mytable_ibfk_4 
      FOREIGN KEY (DID) 
        REFERENCES mytable_d (ID) ON DELETE CASCADE;

 > OK.

परन्तु फिर:

ALTER TABLE mytable
DROP KEY AID ;

त्रुटि देता है।


आप सूचकांक को छोड़ सकते हैं और एक ALTER TABLEबयान में एक नया बना सकते हैं :

ALTER TABLE mytable
DROP KEY AID ,
ADD UNIQUE KEY AID (AID, BID, CID, DID);

8

क्योंकि आपके पास एक विदेशी कुंजी फ़ील्ड पर एक इंडेक्स होना चाहिए, आप 'AID' फ़ील्ड पर एक साधारण इंडेक्स बना सकते हैं

CREATE INDEX aid_index ON mytable (AID);

और उसके बाद ही अद्वितीय सूचकांक 'एआईडी' छोड़ें

ALTER TABLE mytable DROP INDEX AID;

7

एक विदेशी कुंजी को हमेशा एक सूचकांक की आवश्यकता होती है। एक सूचकांक के बिना बाधा को लागू करने के लिए संदर्भित तालिका में प्रत्येक सम्मिलित या अद्यतन कुंजी के लिए संदर्भित तालिका पर एक पूर्ण तालिका स्कैन की आवश्यकता होगी। और यह एक अस्वीकार्य प्रदर्शन प्रभाव होगा। इसके निम्नलिखित 2 परिणाम हैं:

  • एक विदेशी कुंजी बनाते समय, डेटाबेस जांचता है कि क्या कोई सूचकांक मौजूद है। यदि कोई इंडेक्स नहीं बनाया जाएगा। डिफ़ॉल्ट रूप से, यह बाधा के रूप में एक ही नाम होगा।
  • जब केवल एक इंडेक्स होता है जिसे विदेशी कुंजी के लिए इस्तेमाल किया जा सकता है, तो इसे गिराया नहीं जा सकता। यदि आप वास्तव में इसे छोड़ना नहीं चाहते हैं, तो आपको या तो विदेशी कुंजी बाधा को छोड़ना होगा या इसके लिए दूसरा सूचकांक बनाना होगा।

1
आपके पास सिद्धांत है कि अन्य उत्तरों की कमी है।
डेनिस

1
इसलिए: यदि आपके पास एक कंपाउंड यूनिक इंडेक्स है (एक अद्वितीय बाधा में कई कॉलम), तो आप ए बी और बी के लिए एक इंडेक्स होने तक अद्वितीय एबी कुंजी को नहीं निकाल सकते। यदि आपको यह त्रुटि मिलती है, तो दूसरी तालिका कॉलम ए या के इंडेक्स का उपयोग कर रही है। B, और आपको AB को अद्वितीय रूप से हटाने से पहले जोड़ना होगा।
रॉबिन डी शेपर

@RobinDeSchepper अच्छी टिप्पणी। और जब कंपाउंड यूनिक इंडेक्स का उपयोग करते हैं, तो फ़ील्ड का क्रम अद्वितीय इंडेक्स के लिए महत्वपूर्ण नहीं होता है, लेकिन यह एक विदेशी कुंजी के लिए महत्वपूर्ण हो सकता है। ए, बी पर एक अद्वितीय सूचकांक का उपयोग ए पर एक विदेशी कुंजी द्वारा किया जा सकता है, लेकिन बी पर विदेशी कुंजी द्वारा नहीं
स्टीफन मोंडेलेर्स

2

मुझे लगता है कि यह सूचकांक छोड़ने का आसान तरीका है।

set FOREIGN_KEY_CHECKS=1;

ALTER TABLE mytable DROP INDEX AID;

set FOREIGN_KEY_CHECKS=0;

2
मुझे लगता है कि आपने चेक को सक्षम और अक्षम करने का आदान-प्रदान किया है। शीर्ष पर मैं उम्मीद करूंगा FOREIGN_KEY_CHEK=0और अंत में FOREIGN_KEY_CHEK=1
romor

0

मेरे मामले में मैंने विदेशी कुंजी को छोड़ दिया और मैं अभी भी सूचकांक को नहीं छोड़ सका। ऐसा इसलिए था क्योंकि अभी तक एक और तालिका थी जिसमें एक ही फ़ील्ड पर इस तालिका की एक विदेशी कुंजी थी। जब मैंने दूसरी मेज पर विदेशी कुंजी को गिराया उसके बाद मैं इस तालिका पर अनुक्रमित छोड़ सकता हूं।


0

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

$table->dropForeign(['currency_id']);
$table->dropColumn('currency_id');

अधिक विवरण:

https://laravel.com/docs/6.x/migrations#foreign-key-constraints

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.