Mysql
 sql >> Database >  >> RDS >> Mysql

InnoDB inserisce il record solo se esiste un ID di riferimento (senza CHIAVI ESTERE)

Puoi CANCELLARE una categoria solo se non c'è uno scherzo corrispondente:

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;

Se sono presenti battute per la categoria, il join le troverà e pertanto il join esterno restituirà un risultato non nullo. La condizione nella clausola WHERE elimina i risultati non null, quindi l'eliminazione complessiva corrisponderà a zero righe.

Allo stesso modo, puoi INSERIRE una barzelletta in una categoria solo se la categoria esiste:

INSERT INTO jokes (category_id, joke_text)
SELECT c.id, '$joke_text'
FROM categories AS c WHERE c.id = $category_id;

Se non esiste una tale categoria, SELECT restituisce zero righe e INSERT è un no-op.

Entrambi questi casi creano un blocco condiviso (S-lock) nella tabella delle categorie.

Dimostrazione di un S-lock:

In una sessione eseguo:

mysql> INSERT INTO bar (i) SELECT SLEEP(600) FROM foo;

Nella seconda sessione eseguo:

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

Puoi vedere che questo crea un blocco IS sul tavolo foo e un blocco S su una riga di foo, il tavolo da cui sto leggendo.

La stessa cosa accade per qualsiasi operazione di lettura/scrittura ibrida come SELECT...FOR UPDATE , INSERT...SELECT , CREATE TABLE...SELECT , per impedire che le righe in lettura vengano modificate mentre sono necessarie come origine per l'operazione di scrittura.

L'IS-lock è un blocco a livello di tabella che impedisce le operazioni DDL sulla tabella, quindi nessuno emette DROP TABLE o ALTER TABLE mentre questa transazione dipende da alcuni contenuti nella tabella.