ON DELETE CASCADE
är ett sätt att ta bort en rad när en rad den refererar till tas bort. Det betyder:
- Du har en rad i tabell A
- Du har en rad i tabell B som refererar till en rad i tabell A
- Du tar bort raden i tabell A
- Databasen tar bort motsvarande rad i tabell B
Så du har föremål, och varje föremål tillhör en viss kategori. I din artikeltabell har du ett kategori_id (och åtgärda din stavning) som refererar till en rad i kategoritabellen. Så i din situation:
- Du har en kategori
- Du har ett objekt som refererar till en kategori
- Du tar bort en kategori
- Databasen tar bort alla objekt som motsvarar den kategorin
Det du frågar efter är ungefär tvärtom:
- Du har föremål
- Du tar bort det sista objektet i en viss kategori
- Databasen går och hittar den kategorin och tar bort den
Det finns inget sätt att göra detta med ON DELETE CASCADE
, av två skäl:
- Hur ska du skapa en tom kategori innan du infogar ditt första objekt i den? Databasen måste ta bort den omedelbart.
- Databasen skulle behöva göra mycket extra arbete för att skanna tabellen. Den "vet" inte att artikel #23082 var den sista artikeln i kategorin; det måste på något sätt vara att hålla reda på antalet objekt i kategorin för att göra det.
Allt detta härrör från det faktum att ON DELETE CASCADE
är ett sätt att upprätthålla referensintegritet . Det vill säga, det är ett sätt för databasen att ge dig en stark garanti att om du ser kategori #20393 på artikel #9847, när du går och letar efter kategori #20393 vet du att den finns . Det är inte en arbetsbesparande anordning. :) Det är därför de andra alternativen är ON DELETE SET NULL
och ON DELETE RESTRICT
:de garanterar också integritet, men istället för att radera tar de bort den felaktiga referensen eller förhindrar att den ursprungliga raderingen sker.
Så svaret är, du måste antingen skriva ett cron-jobb för att regelbundet rengöra tabellen eller använda någon form av ON DELETE-utlösare, om du är orolig för tomma kategorier.