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

InnoDB indsætter kun post, hvis der findes et refereret id (uden UDENLANDSKE NØGLER)

Du kan kun SLETTE en kategori, hvis der ikke er en matchende joke:

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;

Hvis der er nogle vittigheder for kategorien, vil joinforbindelsen finde dem, og derfor vil den ydre joinforbindelse returnere et resultat, der ikke er nul. Betingelsen i WHERE-sætningen eliminerer ikke-nul resultater, så den samlede sletning vil matche nul rækker.

Ligeledes kan du kun INDSÆTTE en joke til en kategori, hvis kategorien eksisterer:

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

Hvis der ikke er en sådan kategori, returnerer SELECT nul rækker, og INSERT er en no-op.

Begge disse tilfælde opretter en delt lås (S-lås) på kategoritabellen.

Demonstration af en S-lås:

I en session kører jeg:

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

I anden session kører jeg:

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, at dette skaber en IS-lås på tabellen foo, og en S-lås på den ene række af foo, den tabel jeg læser fra.

Det samme sker for alle hybride læse-/skriveoperationer såsom SELECT...FOR UPDATE , INSERT...SELECT , CREATE TABLE...SELECT , for at blokere rækkerne, der læses, fra at blive ændret, mens de er nødvendige som kilde til skriveoperationen.

IS-låsen er en lås på bordniveau, der forhindrer DDL-operationer på bordet, så ingen udsteder DROP TABLE eller ALTER TABLE mens denne transaktion afhænger af noget indhold i tabellen.




  1. Flytning af lat/længde-tekstkolonner til en kolonne af typen "punkt".

  2. En bestemt kolonne indsættes ikke, når en post gemmes

  3. Installer utf8-sortering i PostgreSQL

  4. SQLite opdatering