[PHP/SQL] Hiërarchische data opslaan en ophalen

Pagina: 1
Acties:
  • 232 views sinds 30-01-2008
  • Reageer

Onderwerpen


Acties:
  • 0 Henk 'm!

  • RickyHeijnen
  • Registratie: Maart 2005
  • Laatst online: 30-04 09:02
Beste,

Ik heb een functie gemaakt die van een account alle sub-accounts ophaalt. Let op, de sub-accounts niveau gaan X aantal lagen diep. Een subaccount kan dus ook weer een subaccount hebben. Zo heb ik dus een functie gemaakt die ik steeds vanuit zichzelf opnieuw aanroep. Echter geeft het aanroepen van deze functie soms wel 10.000 queries, gewoon omdat sommige accounts wel 10.000 sub-sub-sub-sub accounts hebben. Nja goed, hoop dat het een beetje duidelijk is.

PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
   function get_sub_ids($handle_id, $inner=false) {

         $sql = "SELECT handle_id FROM accounts WHERE parent_handle_id = '$handle_id' AND handle_id <> '$handle_id' ORDER BY handle";
         //print "$sql";
         $recordset = mysql_query_eval($sql);
         $num_rows = mysql_num_rows($recordset);
         if ($num_rows != 0) {
            while ($record = mysql_fetch_array($recordset)) {
               $sub_ids .= get_sub_ids($record[handle_id], true);  
               $sub_ids .= $record[handle_id] .",";  
            }
         }
      

      if($inner){  return $sub_ids;                }
      else {       return $sub_ids . $handle_id; }      
   }


Nu is mijn vraag eigenlijk, kan dit ook in 1 query? Of in iedergeval wat korter.

Helaas is het voor mij niet mogelijk om een stored procedure te maken, dat was natuurlijk helemaal mooi geweest...

Acties:
  • 0 Henk 'm!

Verwijderd

SELECT a1.handle_id FROM accounts a1 LEFT JOIN accounts a2 ON a1.handle_id = a2.parent_handle_id

(niet getest, dus garantie tot de deur)

Acties:
  • 0 Henk 'm!

  • NMe
  • Registratie: Februari 2004
  • Laatst online: 09-09 13:58

NMe

Quia Ego Sic Dico.

'E's fighting in there!' he stuttered, grabbing the captain's arm.
'All by himself?' said the captain.
'No, with everyone!' shouted Nobby, hopping from one foot to the other.


Acties:
  • 0 Henk 'm!

  • SchizoDuckie
  • Registratie: April 2001
  • Laatst online: 18-02 23:12

SchizoDuckie

Kwaak

Hier is echt al zoooo veel over geschreven...

Wat ik zou doen is in 1x de hele tabel binnenslepen (of een subselectie) en de tree opbouwen via PHP.

[edit]
leesvoer

[ Voor 29% gewijzigd door SchizoDuckie op 17-01-2008 14:13 ]

Stop uploading passwords to Github!


Acties:
  • 0 Henk 'm!

  • mithras
  • Registratie: Maart 2003
  • Niet online
Met een MPTT model kan je veel efficiënter je gegevens ophalen. Zolang je veel minder wijzigingen aanbrengt dan dat je gegevens ophaalt, kan je het beste een MPTT oplossing gebruiken.

Naast de efficiëntie heb je trouwens ook meer mogelijkheden bij het ophalen: alles ophalen, subtree ophalen, het leaf->root pad vinden, alle leafs ophalen e.d. :)

/edit: het gaat dan om het linkje wat -NMe- gaf :)

[ Voor 7% gewijzigd door mithras op 17-01-2008 14:12 ]


Acties:
  • 0 Henk 'm!

  • justmental
  • Registratie: April 2000
  • Niet online

justmental

my heart, the beat

Wat voor database gebruik je?
Oracle heeft hier bijvoorbeeld de 'connect by' clausule voor.

Who is John Galt?


Acties:
  • 0 Henk 'm!

  • mithras
  • Registratie: Maart 2003
  • Niet online
justmental schreef op donderdag 17 januari 2008 @ 14:12:
Wat voor database gebruik je?
Oracle heeft hier bijvoorbeeld de 'connect by' clausule voor.
Zie de code: mysql_query_eval(), mysql_num_rows() en mysql_fetch_array() ;)

Acties:
  • 0 Henk 'm!

  • Niemand_Anders
  • Registratie: Juli 2006
  • Laatst online: 09-07-2024

Niemand_Anders

Dat was ik niet..

Moeten de gegevens echt uit een database komen? Is het niet mogelijk om op basis van de tabel bijvoorbeeld een XML document te genereren. XML heeft van nature een hiërarchische structuur.
Je kunt dan de gehele tabel opvragen uit de database en op basis hiervan een 'account' node aanmaken welke je hangt onder de node met parent_id 'parent_handle_id'.

Op het moment dat je dan alle sub accounts wilt ophalen hoef je alleen de juiste XML node te selecteren en recursief de childnodes af te lopen.

Bij een wijziging aan de tabel, kun je bijvoorbeeld alle gewijzigde records ophalen sinds je laatste XML update. Op die manier kun je vrij eenvoudig de XML up-to-date houden.

Just thinking outside the box ;-)


update: Ha ha, moet sneller lerren schrijven want in luttele seconden zijn er aardig wat reacties geschreven ;-)

[ Voor 7% gewijzigd door Niemand_Anders op 17-01-2008 14:20 ]

If it isn't broken, fix it until it is..


Acties:
  • 0 Henk 'm!

  • SchizoDuckie
  • Registratie: April 2001
  • Laatst online: 18-02 23:12

SchizoDuckie

Kwaak

mithras schreef op donderdag 17 januari 2008 @ 14:14:
[...]
Zie de code: mysql_query_eval()
Que :?

Stop uploading passwords to Github!


Acties:
  • 0 Henk 'm!

  • mithras
  • Registratie: Maart 2003
  • Niet online
Ja, ken de functie ook niet; komt ook niet voor in de php manual (http://php.net/mysql_query_eval), maar TS gebruikt hem wel. Geen idee, het zou gewoon een mysql_query moeten zijn.

Maar de functies waren puur om aan te geven dat het 99.9% zeker over MySQL ging, en niet over Oracle :)
SchizoDuckie schreef op donderdag 17 januari 2008 @ 14:11:
Hier is echt al zoooo veel over geschreven...

Wat ik zou doen is in 1x de hele tabel binnenslepen (of een subselectie) en de tree opbouwen via PHP.

[edit]
leesvoer
http://crisp.tweakblogs.n...only-one-query.html#r_448 ;)

[ Voor 36% gewijzigd door mithras op 17-01-2008 14:28 ]


Acties:
  • 0 Henk 'm!

  • RickyHeijnen
  • Registratie: Maart 2005
  • Laatst online: 30-04 09:02
Ik heb het gelezen, klinkt intressant... alleen lijkt dit voor mij niet de beste oplossingen aangezien er per dag ongeveer 100x iets ingevoegd word en daarbij eigenlijk in de structuur van de boom weinig verandert.

Eigenlijk is de boom ook niet zo diep, denk maximaal 10, en daarvan zit zeker 90% op het eerste niveau. Als ik nu dmv een COUNT() al kan zien of de handle_id wel subhandles heeft, hoef ik niet voor die handle nog 'proberen' dieper in de boom te duiken. Dat moet met een inner join vast wel lukken. |:(

Acties:
  • 0 Henk 'm!

  • RickyHeijnen
  • Registratie: Maart 2005
  • Laatst online: 30-04 09:02
mithras schreef op donderdag 17 januari 2008 @ 14:26:
[...]
Ja, ken de functie ook niet; komt ook niet voor in de php manual (http://php.net/mysql_query_eval), maar TS gebruikt hem wel. Geen idee, het zou gewoon een mysql_query moeten zijn.
Functie die ik zelf gemaakt heb waarin wat hocus-pocus gebeurd :)

Acties:
  • 0 Henk 'm!

  • SchizoDuckie
  • Registratie: April 2001
  • Laatst online: 18-02 23:12

SchizoDuckie

Kwaak

zoetericky schreef op donderdag 17 januari 2008 @ 14:29:
[...]

Functie die ik zelf gemaakt heb waarin wat hocus-pocus gebeurd :)
Het klinkt eng, vooral al aan de functie naam te zien.. :X
mithras schreef op donderdag 17 januari 2008 @ 14:26:
[...]
Maar de functies waren puur om aan te geven dat het 99.9% zeker over MySQL ging, en niet over Oracle :)
Aaah vandaar :P
Jep, ik had 'm gelezen, maar nog steeds heb ik in mijn sites een actie gevonden waarbij ik zoiets had van damn, kon ik nu maar alleen deze slice eruit halen, of kon ik nu maar de parent terugvinden, etc. Kortom, voor de simpele trees blijf ik bij mn standpunt dat gewoon de hele meuk binnenslepen en binnen PHP verwerken simpeler is :) (Zeker als je die een via een recursieve functie zichzelf voert)

Stop uploading passwords to Github!


Acties:
  • 0 Henk 'm!

  • RickyHeijnen
  • Registratie: Maart 2005
  • Laatst online: 30-04 09:02
SchizoDuckie schreef op donderdag 17 januari 2008 @ 14:36:

Jep, ik had 'm gelezen, maar nog steeds heb ik in mijn sites een actie gevonden waarbij ik zoiets had van damn, kon ik nu maar alleen deze slice eruit halen, of kon ik nu maar de parent terugvinden, etc. Kortom, voor de simpele trees blijf ik bij mn standpunt dat gewoon de hele meuk binnenslepen en binnen PHP verwerken simpeler is :) (Zeker als je die een via een recursieve functie zichzelf voert)
Heb je daar voor mij zo snel een code van _/-\o_ , google is niet zo lief vandaag.... 8)7

Acties:
  • 0 Henk 'm!

  • SchizoDuckie
  • Registratie: April 2001
  • Laatst online: 18-02 23:12

SchizoDuckie

Kwaak

zoetericky schreef op donderdag 17 januari 2008 @ 14:40:
[...]
Heb je daar voor mij zo snel een code van _/-\o_ , google is niet zo lief vandaag.... 8)7
Ik geloof niet dat je er zo veel aan zou hebben want het is allemaal op m'n eigen framework gebaseerd die automagisch al objecten om query results heenvouwt. Maar een recursieve functie is toch niet zo moeilijk dat je daar google voor nodig hebt?

Stop uploading passwords to Github!


Acties:
  • 0 Henk 'm!

  • RickyHeijnen
  • Registratie: Maart 2005
  • Laatst online: 30-04 09:02
Ik blijf een (luie) programmeur :X maargoed ik laat mijn vingertjes wel eventjes spelen met het toetsenbord. Ga het eens meten hoeveel seconde het scheelt, want de functie die ik had met de vele mysql queries duurde bij 9.652 resultaten bijna 3,5 seconde 8)7

Acties:
  • 0 Henk 'm!

  • SchizoDuckie
  • Registratie: April 2001
  • Laatst online: 18-02 23:12

SchizoDuckie

Kwaak

zoetericky schreef op donderdag 17 januari 2008 @ 14:47:
Ik blijf een (luie) programmeur :X maargoed ik laat mijn vingertjes wel eventjes spelen met het toetsenbord. Ga het eens meten hoeveel seconde het scheelt, want de functie die ik had met de vele mysql queries duurde bij 9.652 resultaten bijna 3,5 seconde 8)7
Luiheid in een programmeur is een kwaliteit. Zonder luie programmeurs was bijv. de For loop nooit uitgevonden :+

Zorg er alleen wel voor dat je die kwaliteit goed gebruikt ;)

[ Voor 8% gewijzigd door SchizoDuckie op 17-01-2008 14:54 ]

Stop uploading passwords to Github!

Pagina: 1