मेरे द्वारा बनाई गई MySQL v5.6 में तीन टेबल हैं:

CREATE TABLE tm (
    id INT AUTO_INCREMENT,
    PRIMARY KEY (id)
);
CREATE TABLE th (
    id INT AUTO_INCREMENT,
    PRIMARY KEY (id)
);
CREATE TABLE tr (
    id INT AUTO_INCREMENT,
    tm_id INT,
    th_id INT,
    PRIMARY KEY (id), 
    CONSTRAINT fk_1 FOREIGN KEY (tm_id) REFERENCES tm (id) ON DELETE CASCADE ON UPDATE CASCADE,
    CONSTRAINT fk_2 FOREIGN KEY (th_id) REFERENCES th (id) ON DELETE CASCADE ON UPDATE CASCADE
);


INSERT INTO tm (id) VALUES (101);
INSERT INTO tm (id) VALUES (102);
INSERT INTO th (id) VALUES (1);
INSERT INTO tr (tm_id, th_id) VALUES (101,1), (102,1);

तो अंत में मेरे पास निम्नलिखित डेटा के साथ तीन टेबल हैं:

th

| id |
|----|
|  1 |


tr

| id  | tm_id   | th_id |
|-----|---------|-------|
|  11 |     101 |     1 |
|  12 |     102 |     1 |


tm 

| id   |
|------|
|  101 |
|  102 |

और मैं जो करने की कोशिश कर रहा हूं वह उन सभी को एक SQL क्वेरी से हटाना है:

DELETE th, tr, tm
FROM th
LEFT JOIN tr ON tr.th_id = th.id
LEFT JOIN tm ON tr.tm_id = tm.id
WHERE th.id = 1;

परिणामस्वरूप th और tr टेबल खाली रहेंगे लेकिन tm के साथ id=102 रह जाएगा

+------+
|   id |
+------+
|  102 |
+------+

और मैं बेहतर क्वेरी की तलाश नहीं कर रहा हूं, लेकिन यह समझने की कोशिश कर रहा हूं कि tm.id=101 को क्यों हटा दिया गया लेकिन tm.id=102 टेबल में छोड़ दिया गया?

1
bgr11n 6 नवम्बर 2020, 19:48

1 उत्तर

सबसे बढ़िया उत्तर

यह InnoDB स्टोरेज इंजन का परिणाम है जिसका उपयोग (डिफ़ॉल्ट के रूप में) टेबल और विदेशी कुंजी बाधाओं को बनाने के लिए किया जाता है।

विदेशी कुंजियों के बिना डेमो देखें और नतीजा यह है कि सभी टेबल की सभी पंक्तियां हैं हटा दिया गया।

यदि आप MyISAM स्टोरेज इंजन के साथ टेबल बनाते हैं तो आपको विदेशी कुंजी बाधाओं के साथ भी वही परिणाम मिलेगा।
डेमो देखें।

लेकिन InnoDB स्टोरेज इंजन और विदेशी कुंजी बाधाओं के लिए, जैसा कि 13.2.2 DELETE स्टेटमेंट:

यदि आप एक बहु-तालिका DELETE कथन का उपयोग करते हैं जिसमें InnoDB तालिकाएं शामिल हैं, जिसके लिए विदेशी कुंजी बाधाएं हैं, तो MySQL अनुकूलक तालिकाओं को उनके माता-पिता/बाल संबंधों से भिन्न क्रम में संसाधित कर सकता है। इस मामले में, कथन विफल हो जाता है और वापस आ जाता है। इसके बजाय, आपको एक ही टेबल से डिलीट करना चाहिए और ON DELETE क्षमताओं पर भरोसा करना चाहिए जो InnoDB अन्य तालिकाओं को तदनुसार संशोधित करने के लिए प्रदान करता है।

तो आपको जो मिलता है वह tm के id = 102 को हटाने के लिए रोलबैक का परिणाम हो सकता है, क्योंकि संसाधित तालिकाओं का क्रम ऐसा है कि यह एक विदेशी कुंजी बाधा का उल्लंघन करेगा।
डेमो देखें।

1
forpas 6 नवम्बर 2020, 18:29