आप किसी श्रेणी को केवल तभी हटा सकते हैं जब कोई मेल खाने वाला मजाक न हो:
DELETE c FROM categories AS c
LEFT OUTER JOIN jokes AS j ON c.id=j.category_id
WHERE c.id = $category_id AND j.category_id IS NULL;
यदि श्रेणी के लिए कोई चुटकुले हैं, तो शामिल होने से उन्हें मिल जाएगा, और इसलिए बाहरी जुड़ाव एक गैर-शून्य परिणाम लौटाएगा। WHERE क्लॉज की स्थिति गैर-शून्य परिणामों को समाप्त कर देती है, इसलिए समग्र विलोपन शून्य पंक्तियों से मेल खाएगा।
इसी तरह, आप एक चुटकुला को किसी श्रेणी में तभी सम्मिलित कर सकते हैं जब वह श्रेणी मौजूद हो:
INSERT INTO jokes (category_id, joke_text)
SELECT c.id, '$joke_text'
FROM categories AS c WHERE c.id = $category_id;
यदि ऐसी कोई श्रेणी नहीं है, तो चयन शून्य पंक्तियों को लौटाता है, और INSERT एक नो-ऑप है।
ये दोनों मामले श्रेणी तालिका पर एक साझा लॉक (एस-लॉक) बनाते हैं।
एस-लॉक का प्रदर्शन:
एक सत्र में मैं दौड़ता हूं:
mysql> INSERT INTO bar (i) SELECT SLEEP(600) FROM foo;
दूसरे सत्र में मैं दौड़ता हूं:
mysql> SHOW ENGINE INNODB STATUS\G
. . .
---TRANSACTION 3849, ACTIVE 1 sec
mysql tables in use 2, locked 2
2 lock struct(s), heap size 376, 1 row lock(s)
MySQL thread id 18, OS thread handle 0x7faefe7d1700, query id 203 192.168.56.1 root User sleep
insert into bar (i) select sleep(600) from foo
TABLE LOCK table `test`.`foo` trx id 3849 lock mode IS
RECORD LOCKS space id 22 page no 3 n bits 72 index `GEN_CLUST_INDEX` of table `test`.`foo` trx id 3849 lock mode S
आप देख सकते हैं कि यह टेबल फू पर एक आईएस-लॉक और फू की एक पंक्ति पर एक एस-लॉक बनाता है, जिस टेबल से मैं पढ़ रहा हूं।
ऐसा ही किसी भी हाइब्रिड रीड/राइट ऑपरेशंस जैसे SELECT...FOR UPDATE
. के लिए होता है , INSERT...SELECT
, CREATE TABLE...SELECT
, पढ़ी जा रही पंक्तियों को संशोधित होने से रोकने के लिए, जबकि उन्हें लिखने के संचालन के लिए स्रोत के रूप में आवश्यक है।
IS-lock एक टेबल-लेवल लॉक है जो टेबल पर DDL संचालन को रोकता है, इसलिए कोई भी DROP TABLE
जारी नहीं करता है। या ALTER TABLE
जबकि यह लेन-देन तालिका में कुछ सामग्री पर निर्भर करता है।