[php] Children en ascendants uit een tree verwijderen *

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Op Fok kwamen we er niet uit, dus nu hier:

Ik ben een script aan het scrijven dat uit een database alles wist wat onder een categorie zit:

bijvoorbeeld dit:

categorie 1
....categorie2 (zit onder 1, dus subcat1)
......categorie3 (zit ook onder 2, dus subcat2)
......categorie4 (zit ook onder 2, dus subcat2)
........categorie5 (zit onder 4, dus subcat4)

Als je dan categorie 1 weggooit, moet hij 2,3,4 en 5 ook geweggooien.

Zo ziet mn table eruit:

Table categorie{
id
naam
subcat

Als subcat 0 is, dan is het een hoofdcategorie, anders zit hij onder de id die bij subcat staat (zie boven)

nu heb ik dit:
code:
1
2
3
4
5
6
7
<?
$test2=mysql_query("SELECT * FROM categorie WHERE subcat2=$ca");
while($test=mysql_fetch_array($test2)){
mysql_query("DELETE FROM categorie WHERE subcat2=$test[id]");
}
mysql_query("DELETE FROM categorie WHERE id=$ca]");
?>


Maar dit wist alleen de eerste 2 (dus 1 en 2) en laat 3,4 en 5 staan.

Hoe maak ik een loop die voordat hij een invoer wist, kijkt of er een categorie is die daar weer onder zit, en die daar weer onder zit, enz en ze dan allemaal wist?

Acties:
  • 0 Henk 'm!

  • Thomasje
  • Registratie: Augustus 2002
  • Laatst online: 29-05-2024

Thomasje

Semacode

Toevallig, ik heb laatst een scriptje gemaakt dat ongeveer het zelfde doet.

Ik heb het opgelost door er een functie van te maken. In die functie roept hij gewoon ook zichzelf weer aan en zo blijf je gaan tot het klaar is.

Ik hoop dat je het snapt en er verder mee komt

Acties:
  • 0 Henk 'm!

  • André
  • Registratie: Maart 2002
  • Laatst online: 12-09 14:32

André

Analytics dude

Maak een recursieve functie die checked of er childs zijn: zo ja dan zichzelf aanroepen met de child als argument om die vervolgens te checken op childs.... :)

Acties:
  • 0 Henk 'm!

  • crisp
  • Registratie: Februari 2000
  • Laatst online: 00:44

crisp

Devver

Pixelated

iew, PHP

naar de buren --> Programming & Webscripting

Intentionally left blank


Acties:
  • 0 Henk 'm!

  • Arjan A
  • Registratie: November 2000
  • Laatst online: 21-09 12:24

Arjan A

Cenosillicafoob

Je gaat eerst van 'boven naar beneden' als je alle categorieën opvraagt. De ID's sla je op en daarna ga je met een tweede loop de records verwijderen (de netste manier is van 'beneden naar boven' want dan heb je geen orphan in je database).
Als je het niet netjes wil doen, kan je gewoon één query maken die alle records met de opgeslagen ID's verwijdert.

Canon EOS | DJI M2P
Fotoblog · Mijn werk aan jouw muur


Acties:
  • 0 Henk 'm!

  • Arjan A
  • Registratie: November 2000
  • Laatst online: 21-09 12:24

Arjan A

Cenosillicafoob

Thomasje schreef op 15 oktober 2004 @ 17:20:
Toevallig, ik heb laatst een scriptje gemaakt dat ongeveer het zelfde doet.

Ik heb het opgelost door er een functie van te maken. In die functie roept hij gewoon ook zichzelf weer aan en zo blijf je gaan tot het klaar is.

Ik hoop dat je het snapt en er verder mee komt
Inderdaad, recursief te werk gaan is de enige werkbare manier in dit soort structuren.

Canon EOS | DJI M2P
Fotoblog · Mijn werk aan jouw muur


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Thomasje schreef op 15 oktober 2004 @ 17:20:
Toevallig, ik heb laatst een scriptje gemaakt dat ongeveer het zelfde doet.

Ik heb het opgelost door er een functie van te maken. In die functie roept hij gewoon ook zichzelf weer aan en zo blijf je gaan tot het klaar is.

Ik hoop dat je het snapt en er verder mee komt
Zou je een voorbeeld kunnen geven? Ik begrijp wat je bedoelt, maat niet hoe je het toe kunt passen

Acties:
  • 0 Henk 'm!

  • Thomasje
  • Registratie: Augustus 2002
  • Laatst online: 29-05-2024

Thomasje

Semacode

ik heb het zo gedaan. Het is niet zo'n hele nette code. En ik maar ook gebruik van een class om te connecten met de database.

PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
function DeleteMenu($id){
    $connect = new connect();
    $connect->query("DELETE FROM entypoCMS_Structure WHERE id='{$id}'");    
    DelMenuChild($id);  
}

function DelMenuChild($id){
    
    $connectONE = new connect();
    $connectONE->query("SELECT * FROM entypoCMS_Structure WHERE pid='$id' ORDER BY volgorde ASC;");
    $num = $connectONE->num();
    
    $connect = new connect();
    $connect->query("DELETE FROM entypoCMS_Structure WHERE pid='{$id}'");   

    while($row = $connectONE->read()) { 
        DelMenuChild($row[id]); 
    }
}


En zo roep je dan de eerste del aan:
PHP:
1
DeleteMenu($regs[2]);


Hier moet ej dan maar ff je eigen code in zetten maar ik hoop wel dat het zo duidelijk is.

Acties:
  • 0 Henk 'm!

  • André
  • Registratie: Maart 2002
  • Laatst online: 12-09 14:32

André

Analytics dude

Om het simpel uit te leggen:

code:
1
2
3
4
5
6
7
8
9
10
11
12
function DelChild(id)
{
  if (id heeft geen childs) { deleten }

  if (id heeft wel childs)
  { 
    for (0 tot alle childs)
    {
      DelChild(id.child);
    }
  }
}

Acties:
  • 0 Henk 'm!

  • Arjan A
  • Registratie: November 2000
  • Laatst online: 21-09 12:24

Arjan A

Cenosillicafoob

Verwijderd schreef op 15 oktober 2004 @ 17:23:
[...]


Zou je een voorbeeld kunnen geven? Ik begrijp wat je bedoelt, maat niet hoe je het toe kunt passen
FF snel in elkaar geflanst (dus niet getest, maar je zou ermee vooruit moeten kunnen):
PHP:
1
2
3
4
5
6
7
8
9
function checkChildren($ID){
    $query="SELECT ID FROM categorie WHERE subcat=$ID";
    $rs = mysql_query($query);
    while($row = @mysql_fetch_array($rs)){
        checkChildren($row["ID"]);
        $delete = "DELETE FROM categorie WHERE ID=$row["ID"]";
        mysql_query($delete);
    }
}

Canon EOS | DJI M2P
Fotoblog · Mijn werk aan jouw muur


Acties:
  • 0 Henk 'm!

  • Thomasje
  • Registratie: Augustus 2002
  • Laatst online: 29-05-2024

Thomasje

Semacode

André schreef op 15 oktober 2004 @ 17:27:
Om het simpel uit te leggen:

code:
1
2
3
4
5
6
7
8
9
10
11
12
function DelChild(id)
{
  if (id heeft geen childs) { deleten }

  if (id heeft wel childs)
  { 
    for (0 tot alle childs)
    {
      DelChild(id.child);
    }
  }
}
Dit is eigenlijk hetzelfde ;) maar misschien snapt hij het nou beter

Acties:
  • 0 Henk 'm!

  • Arjan A
  • Registratie: November 2000
  • Laatst online: 21-09 12:24

Arjan A

Cenosillicafoob

Thomasje schreef op 15 oktober 2004 @ 17:29:
[...]


Dit is eigenlijk hetzelfde ;) maar misschien snapt hij het nou beter
Volgens mij delete je dan alleen de children van het laagste niveau.

Canon EOS | DJI M2P
Fotoblog · Mijn werk aan jouw muur


Acties:
  • 0 Henk 'm!

  • Thomasje
  • Registratie: Augustus 2002
  • Laatst online: 29-05-2024

Thomasje

Semacode

Arjan A schreef op 15 oktober 2004 @ 17:30:
[...]


Volgens mij delete je dan alleen de children van het laagste niveau.
Ik had eerst ook zoiets maar ik ben toch op mijn huidige overgestapt omdat idd niet alles verwijderd werd. Die van mij nu werkt in ieder geval wel.

Ben aan mijn eigen cms begonnen dus vandaar.

Acties:
  • 0 Henk 'm!

  • Arjan A
  • Registratie: November 2000
  • Laatst online: 21-09 12:24

Arjan A

Cenosillicafoob

Thomasje schreef op 15 oktober 2004 @ 17:32:
[...]
Ben aan mijn eigen cms begonnen dus vandaar.
*herkent* :)

Canon EOS | DJI M2P
Fotoblog · Mijn werk aan jouw muur


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Arjan A schreef op 15 oktober 2004 @ 17:28:
[...]
FF snel in elkaar geflanst (dus niet getest, maar je zou ermee vooruit moeten kunnen):
Thanx, dit moet gaan werken.. Alleen moet ik nog weten wanneer dit aan te roepen.. Ik doe nu dit:
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
function checkChildren($ID2){ 
    $query="SELECT ID FROM categorie WHERE subcat2=$ID2"; 
    $rs = mysql_query($query); 
    while($row = mysql_fetch_array($rs)){ 
        checkChildren($row[id]); 
        $delete = "DELETE FROM categorie WHERE ID=$row[id]"; 
        echo$row[id];
        mysql_query($delete); 
    } 
}

$test2=mysql_query("SELECT * FROM categorie WHERE subcat2=$ca");
while($test=mysql_fetch_array($test2)){
 checkChildren($test[id]); }


maar dit werkt niet...

[ Voor 11% gewijzigd door Verwijderd op 15-10-2004 17:46 ]


Acties:
  • 0 Henk 'm!

  • Arjan A
  • Registratie: November 2000
  • Laatst online: 21-09 12:24

Arjan A

Cenosillicafoob

Verwijderd schreef op 15 oktober 2004 @ 17:43:
[...]


Thanx, dit moet gaan werken.. Alleen moet ik nog weten wanneer dit aan te roepen.. Ik doe nu dit:
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
function checkChildren($ID2){ 
    $query="SELECT ID FROM categorie WHERE subcat2=$ID2"; 
    $rs = mysql_query($query); 
    while($row = mysql_fetch_array($rs)){ 
        checkChildren($row[id]); 
        $delete = "DELETE FROM categorie WHERE ID=$row[id]"; 
        echo$row[id];
        mysql_query($delete); 
    } 
}

$test2=mysql_query("SELECT ID FROM categorie ");
while($test=mysql_fetch_array($test2)){
 checkChildren($ca); }


maar dit werkt niet...
Wat voor output geeft die echo?
Wellicht moet je
PHP:
1
$delete = "DELETE FROM categorie WHERE ID=$row[id]";

veranderen in
PHP:
1
$delete = "DELETE FROM categorie WHERE ID=".$row["ID"];

Ik vind $row["ID"] mooier en netter dan $row[ID], ik weet niet of case-sensitivity ook belangrijk is, want ik neem veldnamen altijd exact over.

Canon EOS | DJI M2P
Fotoblog · Mijn werk aan jouw muur


Acties:
  • 0 Henk 'm!

  • Thomasje
  • Registratie: Augustus 2002
  • Laatst online: 29-05-2024

Thomasje

Semacode

Je roept de functie nu niet aan. Je moet ook nog ergens in je script je functie aanroepen.

Nu roept hij alleen de functie weer aan als de functie al een keer is aangeroepen. Beetje vage zin maar ok

Acties:
  • 0 Henk 'm!

  • Arjan A
  • Registratie: November 2000
  • Laatst online: 21-09 12:24

Arjan A

Cenosillicafoob

PHP:
1
2
3
$test2=mysql_query("SELECT ID FROM categorie ");
while($test=mysql_fetch_array($test2)){
checkChildren($ca); }

Dit klopt ook niet helemaal, waar wordt $ca gevuld?

Canon EOS | DJI M2P
Fotoblog · Mijn werk aan jouw muur


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Arjan A schreef op 15 oktober 2004 @ 17:50:

Dit klopt ook niet helemaal, waar wordt $ca gevuld?
Ik heb het al:

PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
function checkChildren($ID2){ 
    $query="SELECT id FROM categorie WHERE subcat2=$ID2"; 
    $rs = mysql_query($query); 
    while($row = mysql_fetch_array($rs)){ 
        checkChildren($row[id]); 
        $delete = "DELETE FROM categorie WHERE id=$row[id]"; 
        echo$row[id];
        mysql_query($delete); 
    } 
}


 checkChildren($ca);


Dit wist al mijn childs... HET WERKT DUS! Ik had ipv id ID staan.... hoofdletters dus...
$ca word gevuld door een global..
Zo moet het wel lukken! heel erg bedankt iedereen!

[ Voor 3% gewijzigd door Verwijderd op 15-10-2004 17:54 ]


Acties:
  • 0 Henk 'm!

  • Thomasje
  • Registratie: Augustus 2002
  • Laatst online: 29-05-2024

Thomasje

Semacode

Echt dat je er wijs uit kan. Ik probeer altijd zo netjes mogelijk te maken. Nette code zorgt voor overzicht en dan kunnen anderen ook makkelijk meekijken. Ik heb dit ook al in een ander topic gezegt maar vind het wel belangrijk.

Ze hebben niet voor niets de comment uitgevonden

Acties:
  • 0 Henk 'm!

  • Soultaker
  • Registratie: September 2000
  • Laatst online: 22:43
Zo onoverzichtelijk is het toch niet? Er is in ieder geval consistent ingesprongen enzo. Ik heb hier veel ergere lappen code voorbij zien komen.

Acties:
  • 0 Henk 'm!

  • Thomasje
  • Registratie: Augustus 2002
  • Laatst online: 29-05-2024

Thomasje

Semacode

Soultaker schreef op 15 oktober 2004 @ 17:56:
Zo onoverzichtelijk is het toch niet? Er is in ieder geval consistent ingesprongen enzo. Ik heb hier veel ergere lappen code voorbij zien komen.
Beetje enters doet veel wonderen. Vind ik hetzelfde als bij een lap tekst. Het leest veel makkelijker als er enters in zitten dan een stuk achter elkaar

Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Thomasje schreef op 15 oktober 2004 @ 17:54:
Echt dat je er wijs uit kan. Ik probeer altijd zo netjes mogelijk te maken. Nette code zorgt voor overzicht en dan kunnen anderen ook makkelijk meekijken. Ik heb dit ook al in een ander topic gezegt maar vind het wel belangrijk.

Ze hebben niet voor niets de comment uitgevonden
Ik gebruik ook bijna altijd comments voor mezelf... even snel aangeven waar ik ben en wat het ongeveer doet. Ik probeer alles wel zo klein mogelijk te houden vaak. bijv niet:

if ($1==$2)
{
blah();
}

maar:

if($1==$2){blahh();}

Dan word het niet zo snel een enorme lap tekst... Mijn manier van werken, vele mensen zullen dit echter niet prettig vinden, maarja..

Acties:
  • 0 Henk 'm!

  • Arjan A
  • Registratie: November 2000
  • Laatst online: 21-09 12:24

Arjan A

Cenosillicafoob

Thomasje schreef op 15 oktober 2004 @ 18:00:
[...]


Beetje enters doet veel wonderen. Vind ik hetzelfde als bij een lap tekst. Het leest veel makkelijker als er enters in zitten dan een stuk achter elkaar
Ik gebruik ook wel enters voor de leesbaarheid, maar dit is zo'n basaal stukje code, daar ga je toch geen enters in stoppen :? Ik had dat ff snel ingetypt uit mijn hoofd, en had eigenlijk nog wel ergens een foutje verwacht.

Canon EOS | DJI M2P
Fotoblog · Mijn werk aan jouw muur


Acties:
  • 0 Henk 'm!

  • Thomasje
  • Registratie: Augustus 2002
  • Laatst online: 29-05-2024

Thomasje

Semacode

Arjan A schreef op 15 oktober 2004 @ 18:04:
[...]


Ik gebruik ook wel enters voor de leesbaarheid, maar dit is zo'n basaal stukje code, daar ga je toch geen enters in stoppen :? Ik had dat ff snel ingetypt uit mijn hoofd, en had eigenlijk nog wel ergens een foutje verwacht.
Sorry voor de belediging maar zo bedoelde ik het niet. Was gewoon een tip in zijn algemeen. Ik had het idee dat de topic starter heel onoverzichtelijk schrijft

Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Thomasje schreef op 15 oktober 2004 @ 18:06:
[...]


Sorry voor de belediging maar zo bedoelde ik het niet. Was gewoon een tip in zijn algemeen. Ik had het idee dat de topic starter heel onoverzichtelijk schrijft
Dat doe ik ook :-)
Misschien dat ik ooit nog netjes ga werken, maar ik vind mijn manier wel prettig

Acties:
  • 0 Henk 'm!

  • Thomasje
  • Registratie: Augustus 2002
  • Laatst online: 29-05-2024

Thomasje

Semacode

Verwijderd schreef op 15 oktober 2004 @ 18:08:
[...]


Dat doe ik ook :-)
Misschien dat ik ooit nog netjes ga werken, maar ik vind mijn manier wel prettig
Ja iedereen heeft zijn eigen manier van werken. Heb ik ook niks op tegen. Maar ik doe zelf de code netter maken omdat mensen die eens keer kunnen helpen het dan makkelijker snappen.

Het is helemaal niet lastig om het netjes te maken. Als je het eenmaal geleerd heb zal je niet zonder kunnen.

Acties:
  • 0 Henk 'm!

  • Thomasje
  • Registratie: Augustus 2002
  • Laatst online: 29-05-2024

Thomasje

Semacode

Verwijderd schreef op 15 oktober 2004 @ 18:03:
[...]


Ik gebruik ook bijna altijd comments voor mezelf... even snel aangeven waar ik ben en wat het ongeveer doet. Ik probeer alles wel zo klein mogelijk te houden vaak. bijv niet:

if ($1==$2)
{
blah();
}

maar:

if($1==$2){blahh();}

Dan word het niet zo snel een enorme lap tekst... Mijn manier van werken, vele mensen zullen dit echter niet prettig vinden, maarja..
Als je de lappen tekst kwijt wilt zou je ook aan include kunnen denken. Maak een bestand met functies en gooi die daar in en roep hem aan wanneer je hem ndoig hebt.

Acties:
  • 0 Henk 'm!

  • drm
  • Registratie: Februari 2001
  • Laatst online: 09-06 13:31

drm

f0pc0dert

Als je overigens een server wilt stressen, moet je in PHP zoveel mogelijk recursie gebruiken. Als er iets vertragend is, is dat het wel. Als je dat dus niet wilt, is het goed naar alternatieven te zoeken, en het beste mij bekende alternatief is iets wat wel het "Modified preorder traversal"-model wordt genoemd, maar de wat nettere naam is "Nested Sets"

Het zit ongeveer als volgt in elkaar: Je geeft in plaats van elke node zijn parent juist elke node zijn children (en ascendants (!)) aan. Dit wordt als volgt gedaan:
code:
1
2
3
4
5
6
7
8
9
10
11
12
           A
        [1   10]
           |
    ---------------
   |               |
   B               C
[2   3]         [4   9]
                   |
             -------------
            |             |
            D             E
         [5   6]       [7   8]

Wanneer je voor elke node een 'left' en een 'right' opgeeft (wat ik hierboven [tussen blokhaken heb gezet]) zie je dat elke node zijn children en ascendants van bijvoorbeeld 'A' bepaald worden door de voorwaarde:
A.left < left < A.right
of (pseudo)
code:
1
WHERE left BETWEEN (A.left, A.right)

Dit levert namelijk de records B, C, D, en E op. Aangezien je zo'n resultset gewoon iteratief kunt doorlopen is dit vele malen sneller dan een recursieve oplossing, zeker als het om grote aantallen gaat.

Verder kun je zien dat je met 1 enkele query de gehele boom binnen kunt halen, namelijk door te sorteren op left Je krijgt dan:
code:
1
2
3
4
5
6
7
   V
A [1,10]
B [2,3]
C [4,9]
D [5,6]
E [7,8]
   ^

Als je nu bij de nodes ook nog de depth (diepte) van de node opslaat, kun je aan de hand van die depth op de juiste manier inspringen bij weergave ervan:
code:
1
2
3
4
5
6
7
8
9
10
11
12
           A                      DEPTH 0
        [1   10]
           |
    ---------------
   |               |
   B               C
[2   3]         [4   9]           DEPTH 1
                   |
             -------------
            |             |
            D             E
         [5   6]       [7   8]    DEPTH 2

en die depth toepassen:

code:
1
2
3
4
5
A [1,10]       (DEPTH 0)
   B [2,3]     (DEPTH 1)
   C [4,9]     (DEPTH 1)
      D [5,6]  (DEPTH 2)
      E [7,8]  (DEPTH 2)

Nog een voordeel is dat je ook heel eenvoudig delen van de boom kunt selecteren, namelijk door te sorteren op left, de depth mee te selecteren en een BETWEEN clause op te geven, zoals bijvoorbeeld voor node C het geval kan zijn:
code:
1
2
3
C [4,9]     (DEPTH 1)
   D [5,6]  (DEPTH 2)
   E [7,8]  (DEPTH 2)
(gesorteerd op left, en de left BETWEEN (4,9))


Het enige wat een beetje moeite vereist is het in de gaten houden van de left's en right's van de nodes bij inserten, deleten, en verplaatsen van nodes.

Om een lang verhaal kort te maken: Leesmateriaal voor PHP'ers. Zie ook:
[rml][ MySQL] boomstuctuur - probleem bij nodes verplaatsen[/rml]
[rml]ACM in "[ PHP/MySQL] Teveel queries bij recursiev..."[/rml]

Ik kan me overigens voorstellen dat het wat lastig overkomt allemaal, maar het is echt de moeite waard om in de gaten te krijgen. Let overigens op dat het geen vervanging hoeft te zijn van het "verwijzen naar de parent node". Je kunt natuurlijk best van twee walletjes mee-eten door bij een node ok gewoon de verwijzing naar de parent op te slaan.

Music is the pleasure the human mind experiences from counting without being aware that it is counting
~ Gottfried Leibniz


Acties:
  • 0 Henk 'm!

  • Soultaker
  • Registratie: September 2000
  • Laatst online: 22:43
drm schreef op 15 oktober 2004 @ 18:27:
Als je overigens een server wilt stressen, moet je in PHP zoveel mogelijk recursie gebruiken. Als er iets vertragend is, is dat het wel.
Je moet dit soort dingen altijd in verhouding zien. MySQL queries (en database queries in het algemeen) zijn vele malen trager dan functie-aanroepen in PHP. In de gegeven code wordt in elke functie-aanroep een SQL-query uitgevoerd; die functie-aanroepen wegoptimaliseren levert dus nagenoeg niets op, als je nog steeds de queries moet doen. Dan kun je beter voor een toereikende, overzichtelijke oplossing kiezen.

Verder moet je je afvragen of het vaak voorkomt dat je categoriën verwijdert. Waarschijnlijk niet. In dat geval maakt het dus ook niet uit dat je implementatie relatief traag is.

Acties:
  • 0 Henk 'm!

  • Arjan A
  • Registratie: November 2000
  • Laatst online: 21-09 12:24

Arjan A

Cenosillicafoob

Soultaker schreef op 15 oktober 2004 @ 22:01:
[...]
Verder moet je je afvragen of het vaak voorkomt dat je categoriën verwijdert. Waarschijnlijk niet. In dat geval maakt het dus ook niet uit dat je implementatie relatief traag is.
In het geval van admin-achtige functies (zoals bijv. het verwijderen van categorieën) kan het me inderdaad weinig schelen hoeveel load er op een machine terechtkomt.
Vooral als je een tree wil weergeven is het van belang om zo zuinig mogelijk met je resources om te gaan.

Wat drm laat zien is een heel mooi stukje theorie (ik herken het van de HIO), maar niet altijd even praktisch inzetbaar. 't Is wel een mooie positie om het denkwerk te 'sturen'.

Even terug naar de praktijk: een boomstructuur kan je bijvoorbeeld heel makkelijk weergeven dmv javascript. Laad alle data met één query (kan soms lastig zijn als je met rechtenstructuren etc werkt), en laat dan client-side de boel structureren.
drm schreef op 15 oktober 2004 @ 18:27:[...] Let overigens op dat het geen vervanging hoeft te zijn van het "verwijzen naar de parent node". Je kunt natuurlijk best van twee walletjes mee-eten door bij een node ok gewoon de verwijzing naar de parent op te slaan.
Never underestimate the power of redundancy ;)

[ Voor 17% gewijzigd door Arjan A op 15-10-2004 22:25 ]

Canon EOS | DJI M2P
Fotoblog · Mijn werk aan jouw muur


Acties:
  • 0 Henk 'm!

  • Soultaker
  • Registratie: September 2000
  • Laatst online: 22:43
Arjan A schreef op 15 oktober 2004 @ 22:24:
Wat drm laat zien is een heel mooi stukje theorie (ik herken het van de HIO), maar niet altijd even praktisch inzetbaar. 't Is wel een mooie positie om het denkwerk te 'sturen'. Even terug naar de praktijk: een boomstructuur kan je bijvoorbeeld heel makkelijk weergeven dmv javascript. Laad alle data met één query (kan soms lastig zijn als je met rechtenstructuren etc werkt), en laat dan client-side de boel structureren.
Dat werkt wel (en je kan de boel ook wel server-side vanuit PHP sorteren), maar dan moet je dus altijd de hele boom queryen. Bij een beetje complexe boom kan dat vrij kostbaar zijn.

Acties:
  • 0 Henk 'm!

  • drm
  • Registratie: Februari 2001
  • Laatst online: 09-06 13:31

drm

f0pc0dert

Soultaker:
Je moet dit soort dingen altijd in verhouding zien. MySQL queries (en database queries in het algemeen) zijn vele malen trager dan functie-aanroepen in PHP. In de gegeven code wordt in elke functie-aanroep een SQL-query uitgevoerd; die functie-aanroepen wegoptimaliseren levert dus nagenoeg niets op, als je nog steeds de queries moet doen. Dan kun je beter voor een toereikende, overzichtelijke oplossing kiezen.
Daar heb je opzich wel gelijk in, maar ook wanneer je maar 1 query zou doen en php de boom zou laten structureren, zou de recursie de kneep zijn. Ik heb er wel eens wat testjes mee zitten doen, en het viel mij bijzonder op hoeveel invloed recursie heeft op de performance. Ik probeer het daarom tegenwoordig zo veel mogelijk te vermijden.
Verder moet je je afvragen of het vaak voorkomt dat je categoriën verwijdert. Waarschijnlijk niet. In dat geval maakt het dus ook niet uit dat je implementatie relatief traag is.
Da's waar, maar het verwijderen heeft in dit geval een beetje dezelfde performance hit als het tonen van de boom. Met name dat laatste zul je vaak doen en zou je daarom goed moeten optimaliseren.

Music is the pleasure the human mind experiences from counting without being aware that it is counting
~ Gottfried Leibniz


Acties:
  • 0 Henk 'm!

  • Soultaker
  • Registratie: September 2000
  • Laatst online: 22:43
drm schreef op 16 oktober 2004 @ 15:00:
Da's waar, maar het verwijderen heeft in dit geval een beetje dezelfde performance hit als het tonen van de boom. Met name dat laatste zul je vaak doen en zou je daarom goed moeten optimaliseren.
Klopt; plus jouw structuur kan gebruikt worden om efficient 'breadcrumbs' te genereren; die navigatie-links zoals GoT > DevSchuur > P&W > Topic.

Acties:
  • 0 Henk 'm!

  • Cavorka
  • Registratie: April 2003
  • Laatst online: 27-03-2018

Cavorka

Internet Entrepreneur

Soultaker schreef op 16 oktober 2004 @ 15:44:
[...]
Klopt; plus jouw structuur kan gebruikt worden om efficient 'breadcrumbs' te genereren; die navigatie-links zoals GoT > DevSchuur > P&W > Topic.
Het hele punt van die methode, is juist dat ALLES er makkelijker mee gedaan kan worden. Path-to-node operaties zijn heel makkelijk en nooit recursief SQL wise. :) Behalve het inserten van nieuwe nodes dan... :P Maar zelfs dat is eenvoudig, als je de routine eenmaal doorhebt.

Ik gebruik de beschreven methode ook trouwens voor mijn (hoe origineel!) CMS systeem.

[ Voor 9% gewijzigd door Cavorka op 16-10-2004 15:49 ]

the-blueprints.com - The largest free blueprint collection on the internet: 50000+ drawings.


Acties:
  • 0 Henk 'm!

  • Soultaker
  • Registratie: September 2000
  • Laatst online: 22:43
Cavorka schreef op 16 oktober 2004 @ 15:49:
Het hele punt van die methode, is juist dat ALLES er makkelijker mee gedaan kan worden. Path-to-node operaties zijn heel makkelijk en nooit recursief SQL wise. :) Behalve het inserten van nieuwe nodes dan... :P
Dat is wel heel kort door de bocht. Om te beginnen zijn bijna alle denkbare wijzigingen in de boom zijn erg kostbaar in deze structuur en dus is deze structuur eigenlijk alleen geschikt voor databases waaruit vooral gelezen wordt.

Verder zijn er ook operaties die met een verwijzing naar de parent node makkelijker te verwerken zijn dan met het labelen van de zijkanten. Denk bijvoorbeeld aan het opvragen van alle directe child nodes van een bepaalde node; dat kan zeer efficient met een verwijzing naar de parent node, maar in de variant met gelabelde zijkanten moet je de hele deelboom ophalen. Zo'n query heb je bijvoorbeeld nodig als je een menu hebt opgeslagen in een boomstructuur, en je wil een submenu genereren. Bepaald geen hypothetische situatie, naar mijn mening.

Mijn conclusie is dus dat je de keuze voor je datastructuur moet laten afhangen van de operaties die je er (efficient) mee wil kunnen ondersteunen. Je moet je dus eerst afvragen welke operaties je ueberhaupt gaat doen, en vervolgens onderscheid maken in veel voorkomende en zeldzame operaties. Op basis van die analyse kun je een geschikte keuze maken voor je datastructuur (of kiezen voor een hybride, zoals drm ook al suggereerde). Geen van de twee hier genoemde datastructuren is absoluut superieur aan de andere; wie je dat wijst probeert te maken heeft zich niet genoeg in het onderwerp verdiept.
Pagina: 1