Pereiti prie turinio

Hierarchijos algoritmas


Rekomenduojami pranešimai

Sveiki,

 

norėčiau Jūsų pagalbos vienu klausimu.

Turiu lentele su tokiais laukais: ID, PARENT_ID, NAME.

Internete pilna visokiausių paaškinimų, kurie yra per daug komplikuoti. Gal kas nors turit ar žinot kur rast paprastą užklausą traukt duomenim nežinant nei deep, nei kiek lygių yra, nei nuo kurio pradėti?

Bandžiau be jokių ciklų, tiesiog žinodamas, kiek yra lygių, surašyti užklausas į php faila ir jas atvaizduoti, gavosi gerai, tačiau kyla visokių O JEIGU BUS TAIP. Tada net galvą paskausta.

Tad laukiu Jūsų minčių, gal kas nors užvesit ant teisingesnio kelio.

Nuoroda į pranešimą
Dalintis kituose puslapiuose

Logika maždaug tokia būtų, turbūt :) -

 

1. root`iniai elementai turėtų turėt PARENT_ID = null (SQL: ... PARENT_ID is null);

2. surenkam masyvą visų root`inių elementų ID;

3. iteruojam per gautą masyvą ir ieškom kiekvieno root`o vaikų (SQL: .... WHERE PARENT_ID = <root_id_iš_masyvo>);

4. ir taip toliau gylyn.

 

Paskui galima jau galvoti apie efektyvesnius algoritmus. Bet pradžiai galima ir taip. Juk svarbiausia idėja ;)

Nuoroda į pranešimą
Dalintis kituose puslapiuose

Na pavyzdžiui, jei nori gauti konkrečios kategorijos duomenis, tai manau tiktų tokia rekursinė funkcija:

 

function getCatData($parent_id, $table) {
 global $kategorijos;

 $sql = mysql_query("SELECT * FROM $table WHERE id = '$parent_id'");
 if(dbrows($sql) > 0) {
  while($r = mysql_fetch_assoc($sql)) {
  	array_push($kategorijos, $r);
  	getCatData($r['parent_id'], $table);
  }
 }

 return $kategorijos;
}

 

Jos panaudojimas būtų toks:

 

$kategorijos = array();
$kategorijos = getCatData(KATEGORIJOS_ID, LENTELE);

Nuoroda į pranešimą
Dalintis kituose puslapiuose

Na pavyzdžiui, jei nori gauti konkrečios kategorijos duomenis, tai manau tiktų tokia rekursinė funkcija:

 

function getCatData($parent_id, $table) {
 global $kategorijos;

 $sql = mysql_query("SELECT * FROM $table WHERE id = '$parent_id'");
 if(dbrows($sql) > 0) {
  while($r = mysql_fetch_assoc($sql)) {
  	array_push($kategorijos, $r);
  	getCatData($r['parent_id'], $table);
  }
 }

 return $kategorijos;
}

 

Jos panaudojimas būtų toks:

 

$kategorijos = array();
$kategorijos = getCatData(KATEGORIJOS_ID, LENTELE);

Šitą metodą galima patobulint, bet toks koks jis dabar yra tai mirtis. Suvoki kas bus kai norėsi visą kategorijų medį atvaizduot su tokiu metodu? 100 užklausų? T.y. kiekvienai kategorijai bent po vieną.

Liekant prie tokios metodikos, reikėtų įrašus nuskaitinėt pagal "gylį". Pradžiai įrašus be tėvų, tada jų vaikus, vaikų vaikus ir t.t.

 

Aišku geriausia būtų naudoti Justino minėtus "komplikuotus" metodus. Realiai jie komplikuoti tik realizacijoj. Pasirašytum (susirastum) klasę ir viskas pataptų elementaru.

Nuoroda į pranešimą
Dalintis kituose puslapiuose

Pačiam neseniai reikėjo, tai buvau pasibaisėjęs, kad internete visi pavyzdžiai tokie griozdiški, teko pasirašyti pačiam. Esmė tokia, kad pradžioje reikia elementus pasortinti pagal PARENT desc. Pliusas tas, kad užtenka tik vienos sql užklausos vietoje milijono+1 taikant kitus metodus :) Šios funkcijos logika tokia, kad elementus pradedame dėlioti ne nuo viršaus į apačią (gylį), o iš pačios apačios į viršutinius lygius.

 

function maketree($els){
$elsv=array_values($els);
$id=$elsv[0]['id'];
$parent=$elsv[0]['parent'];
if ($parent!=0){
	$elsv[0]['level']+=1;
	$els[$parent]['childs'][]=$elsv[0];
	unset($els[$id]);
	if ($elsv[1]['parent']!=0){$els=maketree($els);}
}
return $els;
}

$cats=$db->select("select * from kategorijos order by parent desc,name asc");
$cats=maketree($cats);

Redagavo pushkis
Nuoroda į pranešimą
Dalintis kituose puslapiuose

Pačiam neseniai reikėjo, tai buvau pasibaisėjęs, kad internete visi pavyzdžiai tokie griozdiški, teko pasirašyti pačiam. Esmė tokia, kad pradžioje reikia elementus pasortinti pagal PARENT desc. Pliusas tas, kad užtenka tik vienos sql užklausos vietoje milijono+1 taikant kitus metodus :) Šios funkcijos logika tokia, kad elementus pradedame dėlioti ne nuo viršaus į apačią (gylį), o iš pačios apačios į viršutinius lygius.

 

function maketree($els){
$elsv=array_values($els);
$id=$elsv[0]['id'];
$parent=$elsv[0]['parent'];
if ($parent!=0){
	$elsv[0]['level']+=1;
	$els[$parent]['childs'][]=$elsv[0];
	unset($els[$id]);
	if ($elsv[1]['parent']!=0){$els=maketree($els);}
}
return $els;
}

$cats=$db->select("select * from kategorijos order by parent desc,name asc");
$cats=maketree($cats);

 

Šitas metodas visada nuskaito milijoną + 1 įrašą kai mums reikia tik tų kurių tėvo ID, pvz., 15.

Netestavau aš šito metodo, bet ta rekursija atrodo žudanti. Sakyčiau variantas kaip tikrai nereikėtų daryti.

Testavai metodą? Kas jei kategorijos ID = 5, o tėvo ID = 15?

 

P.S. Jei kode įdėtum daugiau tarpų ir parinktum protingus kintamųjų vardus, būtų lengviau skaityti.

P.P.S. Įprasta SQL raktinius žodžius rašyti iš didžiųjų raidžių.

Nuoroda į pranešimą
Dalintis kituose puslapiuose

Šitas metodas visada nuskaito milijoną + 1 įrašą kai mums reikia tik tų kurių tėvo ID, pvz., 15.

Netestavau aš šito metodo, bet ta rekursija atrodo žudanti. Sakyčiau variantas kaip tikrai nereikėtų daryti.

Testavai metodą? Kas jei kategorijos ID = 5, o tėvo ID = 15?

 

P.S. Jei kode įdėtum daugiau tarpų ir parinktum protingus kintamųjų vardus, būtų lengviau skaityti.

P.P.S. Įprasta SQL raktinius žodžius rašyti iš didžiųjų raidžių.

 

1. Man ir reikia visų elementų.

2. Labai atsiprašau, kad dėl tavęs neparašiau didžiosiomis raidėmis. Viliuosi, kad kada nors galėsite man atleisti už tai ;)

3. Prašau, man nesunku buvo :)

Nuoroda į pranešimą
Dalintis kituose puslapiuose

Prisijunkite prie diskusijos

Jūs galite rašyti dabar, o registruotis vėliau. Jeigu turite paskyrą, prisijunkite dabar, kad rašytumėte iš savo paskyros.

Svečias
Parašykite atsakymą...

×   Įdėta kaip raiškusis tekstas.   Atkurti formatavimą

  Only 75 emoji are allowed.

×   Nuorodos turinys įdėtas automatiškai.   Rodyti kaip įprastą nuorodą

×   Jūsų anksčiau įrašytas turinys buvo atkurtas.   Išvalyti redaktorių

×   You cannot paste images directly. Upload or insert images from URL.

Įkraunama...
  • Dabar naršo   0 narių

    Nei vienas registruotas narys šiuo metu nežiūri šio puslapio.

×
×
  • Pasirinkite naujai kuriamo turinio tipą...