onderwerp + dieperliggende onderwerpen verwijderen
Mijn database heb ik kortweg zo opgebouwd:
Onderwerpen
id |parent_id|
1 |0
2 |0
3 |1
4 |3
In bovenstaand voorbeeld zijn 1 & 2 onderwerpen welke in het menu worden getoond, en 3 in het submenu van 1, en 4 in het submenu van 3.
Het is een duidelijk methode om mee te werken en alles lukt, behalve het verwijderen van onderwerpen inclusief alle dieperliggende pagina's. Natuurlijk kan je met een while iedere keer controleren of er dieperliggende pagina's zijn en verwijderen, maar dan moet je per laag een while doen en dat is natuurlijk niet rendabel. Graag zou ik een pure mysql oplossing vinden waarmij bovenstaand onderwerp 1, en daarmee ook 3 en 4 verwijderd kunnen worden.
Alvast bedankt!
Onderwerpen
id |parent_id|
1 |0
2 |0
3 |1
4 |3
In bovenstaand voorbeeld zijn 1 & 2 onderwerpen welke in het menu worden getoond, en 3 in het submenu van 1, en 4 in het submenu van 3.
Het is een duidelijk methode om mee te werken en alles lukt, behalve het verwijderen van onderwerpen inclusief alle dieperliggende pagina's. Natuurlijk kan je met een while iedere keer controleren of er dieperliggende pagina's zijn en verwijderen, maar dan moet je per laag een while doen en dat is natuurlijk niet rendabel. Graag zou ik een pure mysql oplossing vinden waarmij bovenstaand onderwerp 1, en daarmee ook 3 en 4 verwijderd kunnen worden.
Alvast bedankt!
Kwestie van het aanbrengen van de juiste FK's en bijbehorende acties (CASCADE) in je tabel. Als je dan een parent verwijderd, zullen automatisch alle childs verwijderd worden.
Dank voor je reactie, ik zal het even uitzoeken
Hmm ben nieuw bij dit, heb het volgende geprobeerd:
ALTER TABLE pages
ADD FOREIGN KEY (parent_id)
REFERENCES pages (id)
ON DELETE CASCADE
maar dit werkt niet, enig idee wat ik verkeerd doe?
Edit: Sorry voor het bumpen
ALTER TABLE pages
ADD FOREIGN KEY (parent_id)
REFERENCES pages (id)
ON DELETE CASCADE
maar dit werkt niet, enig idee wat ik verkeerd doe?
Edit: Sorry voor het bumpen
Gewijzigd op 01/01/1970 01:00:00 door Scrptr
is je tabeltype wel een innoDB?
Nee, en dat krijg ik ook niet voor elkaar, hij staat op MyISAM
InnoDB is de enige engine waarmee je foreign keys kunt gebruiken, dus daar ben je op aangewezen. Waarschijnlijk zul je de tabel opnieuw aan moeten maken en moeten vullen, want switchen van MyISAM naar InnoDB is niet zomaar mogelijk...
Ik heb slechts de keuze uit:
MyISAM, MEMORY, ARCHIVE en MRG_MyISAM
MyISAM, MEMORY, ARCHIVE en MRG_MyISAM
Tja, dan heb je dus niet de mogelijkheid om met foreign keys te werken en heb je dus helaas weinig aan je database. De data die je erin zet is nu namelijk niet meer te vertrouwen aangezien de fk relaties niet bestaan...
Vraag eens bij je host of ze die engine kunnen activeren of zoek een host die wel een goede database ondersteuning biedt.
Vraag eens bij je host of ze die engine kunnen activeren of zoek een host die wel een goede database ondersteuning biedt.
het is met usbwebserver, maar ik ga een alternatief zoeken.
WAMP is een goed alternatief waarbij je zeker wel van InnoDB gebruik kunt maken.
Overigens kun je dit wellicht met usbwebserver ook wel voor elkaar krijgen door in de instellingen van MySQL te duiken. Ik weet alleen niet hoeveel vrijheid je hebt om hier aanpassingen in te maken.
Overigens kun je dit wellicht met usbwebserver ook wel voor elkaar krijgen door in de instellingen van MySQL te duiken. Ik weet alleen niet hoeveel vrijheid je hebt om hier aanpassingen in te maken.
Je kunt voor het verwijderen van dieperliggende onderwerpen een recursieve functie gebruiken:
Code (php)
1
2
3
4
5
6
7
2
3
4
5
6
7
<?php
function delete($id) {
// SELECT id FROM table WHERE idparent = $id
foreach ($result as $id) {
delete($id);
}
?>
function delete($id) {
// SELECT id FROM table WHERE idparent = $id
foreach ($result as $id) {
delete($id);
}
?>
@Tommy: liever los je het natuurlijk niet op deze manier op. De database is prima in staat om dat uit zichzelf te doen, daar hoeft helemaal geen PHP aan te pas te komen.
Naast dat je code een stuk korter wordt, is de kans op fouten ook een stuk kleiner. Wie zegt namelijk dat alle queries die jij uitvoert in je recursieve PHP functie ook daadwerkelijk lukken? Er hoeft er maar 1 te mislukken en je zit alweer met corrupte data in je database!
Kortom, laat dit gewoon lekker over aan de database...
Naast dat je code een stuk korter wordt, is de kans op fouten ook een stuk kleiner. Wie zegt namelijk dat alle queries die jij uitvoert in je recursieve PHP functie ook daadwerkelijk lukken? Er hoeft er maar 1 te mislukken en je zit alweer met corrupte data in je database!
Kortom, laat dit gewoon lekker over aan de database...
Je kunt idd ook zo'n functie maken met MySQL (of wat anders..)
'Tommy:
Nee, je wilt hier ook in SQL geen functie voor schrijven...Je kunt idd ook zo'n functie maken met MySQL (of wat anders..)
Zorg gewoon dat je de juiste foreign key constraints aanbrengt en de bijbehorende acties goed instelt. Als je dan 1 (parent) record verwijderd zullen alle afhankelijke records ook verwijderd worden. It's as simple as that!
Bedankt voor jullie reacties,
@Tommy: je phpvoorbeeld zal niet werken aangezien een dieperliggend onderwerp zelf ook nog een dieper liggend onderwerp heeft. En het is de bedoeling dat ook die verwijderd worden.
@Tommy: je phpvoorbeeld zal niet werken aangezien een dieperliggend onderwerp zelf ook nog een dieper liggend onderwerp heeft. En het is de bedoeling dat ook die verwijderd worden.
Tommy's PHP voorbeeld zal wel werken, voor elk dieper liggend onderwerp wordt immers dezelfde functie uitgevoerd waarbij dus weer gekeken of er dieper liggende onderwerpen zijn.
De redenen waarom het toch niet slim is om het op deze manier aan te passen, heb ik in voorgaande posts al gegeven.
De redenen waarom het toch niet slim is om het op deze manier aan te passen, heb ik in voorgaande posts al gegeven.
Foreign keys.
.. anders moet je maar SQL doen.
.. anders moet je maar SQL doen.
@Gerben: met die query kom je in de knoop zodra je nog een niveau dieper gaat. Die records zullen dan niet verwijderd worden waardoor je records zonder parent over houdt en je dus met corrupte data zit!
Kortom, FK's ;-)
Kortom, FK's ;-)
Misschien heb ik nog een andere omweg:
Zoiets misschien?
Code (php)
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
<?
$id = 343; //bijv
mysql_query("UPDATE category SET parent_id = '-1' WHERE parent_id='".$id."'");
mysql_query("DELETE FROM category WHERE id = '".$id."'");
while($row = mysql_fetch_assoc("SELECT * FROM category WHERE parent_id='-1'")){
// Update waarbij alle childs van parent_id = $row['id'] worden gezet naar -1
// Delete deze $row['id'];
}
?>
$id = 343; //bijv
mysql_query("UPDATE category SET parent_id = '-1' WHERE parent_id='".$id."'");
mysql_query("DELETE FROM category WHERE id = '".$id."'");
while($row = mysql_fetch_assoc("SELECT * FROM category WHERE parent_id='-1'")){
// Update waarbij alle childs van parent_id = $row['id'] worden gezet naar -1
// Delete deze $row['id'];
}
?>
Zoiets misschien?
Gewijzigd op 01/01/1970 01:00:00 door Scrptr
Dan blijf je nog steeds met hetzelfde probleem zitten. Je hebt nooit de zekerheid dat alle queries lukken en als je al DELETE queries hebt uitgevoerd op het moment dat er 1 mislukt, heb je corrupte data in je database.
Dan zou je dus al met transacties moeten gaan werken, maar waarom zoveel moeite doen terwijl het met foreign keys een fluitje van een cent is? Die dingen zijn niet voor niets uitgevonden!
Dan zou je dus al met transacties moeten gaan werken, maar waarom zoveel moeite doen terwijl het met foreign keys een fluitje van een cent is? Die dingen zijn niet voor niets uitgevonden!




