sql >> データベース >  >> RDS >> Mysql

InnoDBは、参照されるIDが存在する場合にのみレコードを挿入します(外部キーなし)

    一致するジョークがない場合にのみ、カテゴリを削除できます:

    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...SELECTCREATE TABLE...SELECT 、書き込み操作のソースとして必要なときに、読み取られている行が変更されないようにブロックします。

    IS-lockは、テーブルに対するDDL操作を防ぐテーブルレベルのロックであるため、DROP TABLEを発行する人は誰もいません。 またはALTER TABLE このトランザクションはテーブルの一部のコンテンツに依存しています。




    1. GROUPBYを使用して最後のエントリを取得します

    2. MySQL:特定のノードで葉を見つける方法

    3. PostgreSQLで類似した文字列をすばやく見つける

    4. 例を含むSQLJOINチュートリアル