一致するジョークがない場合にのみ、カテゴリを削除できます:
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;
カテゴリにジョークがある場合、結合はそれらを見つけるため、外部結合はnull以外の結果を返します。 WHERE句の条件により、null以外の結果が削除されるため、全体的な削除はゼロ行に一致します。
同様に、カテゴリが存在する場合にのみ、カテゴリにジョークを挿入できます。
INSERT INTO jokes (category_id, joke_text)
SELECT c.id, '$joke_text'
FROM categories AS c WHERE c.id = $category_id;
そのようなカテゴリがない場合、SELECTはゼロ行を返し、INSERTは何もしません。
これらの両方のケースで、カテゴリテーブルに共有ロック(Sロック)が作成されます。
Sロックのデモンストレーション:
1つのセッションで実行します:
mysql> INSERT INTO bar (i) SELECT SLEEP(600) FROM foo;
2番目のセッションで実行します:
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
これにより、テーブルfooにISロックが作成され、読み取り元のテーブルであるfooの1行にSロックが作成されることがわかります。
SELECT...FOR UPDATE
などのハイブリッド読み取り/書き込み操作でも同じことが起こります。 、INSERT...SELECT
、CREATE TABLE...SELECT
、書き込み操作のソースとして必要なときに、読み取られている行が変更されないようにブロックします。
IS-lockは、テーブルに対するDDL操作を防ぐテーブルレベルのロックであるため、DROP TABLE
を発行する人は誰もいません。 またはALTER TABLE
このトランザクションはテーブルの一部のコンテンツに依存しています。