sql >> Databasteknik >  >> RDS >> Mysql

Hur man använder DELETE ON CASCADE på många-till-en relation

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:

  1. Hur ska du skapa en tom kategori innan du infogar ditt första objekt i den? Databasen måste ta bort den omedelbart.
  2. 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.




  1. MySQL INTE I fråga

  2. Hur kan jag använda MySQL-tilldelningsoperatorn(:=) i en inbyggd fråga i viloläge?

  3. Vilka är praktiska skillnader mellan `REPLACE` och `INSERT ... ON DUPLICATE KEY UPDATE` i MySQL?

  4. Det går inte att ansluta MySQL-behållare till Tomcat-behållare i docker