sql >> Databasteknik >  >> RDS >> Mysql

InnoDB infogar endast post om refererat id finns (utan UTLÄNDSKA NYCKLAR)

Du kan bara TA BORT en kategori om det inte finns något matchande skämt:

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;

Om det finns några skämt för kategorin kommer sammanfogningen att hitta dem, och därför kommer den yttre sammanfogningen att returnera ett resultat som inte är noll. Villkoret i WHERE-satsen eliminerar resultat som inte är null, så den totala borttagningen matchar noll rader.

På samma sätt kan du bara INFOGA ett skämt i en kategori om kategorin finns:

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

Om det inte finns någon sådan kategori, returnerar SELECT noll rader, och INSERT är en no-op.

Båda dessa fall skapar ett delat lås (S-lås) i kategoritabellen.

Demonstration av ett S-lås:

I en session kör jag:

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

Under andra sessionen kör jag:

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

Du kan se att detta skapar ett IS-lås på tabellen foo, och ett S-lås på en rad av foo, tabellen jag läser från.

Samma sak händer för alla hybrida läs-/skrivoperationer som SELECT...FOR UPDATE , INSERT...SELECT , CREATE TABLE...SELECT , för att blockera raderna som läses från att ändras medan de behövs som en källa för skrivoperationen.

IS-låset är ett lås på tabellnivå som förhindrar DDL-operationer på bordet, så ingen utfärdar DROP TABLE eller ALTER TABLE medan denna transaktion är beroende av något innehåll i tabellen.




  1. Hur kontrollerar man befintlig post innan man infogar post för varje användare i samma tabell?

  2. Vilken Visual Studio behöver jag för MySQL?

  3. Laravel 5.5 Error Bastabell eller vy finns redan:1050 Tabell "användare" finns redan

  4. Anpassad BESTÄLLNING EFTER Förklaring