[类别树]寻求从数据库中取出类别树的最高效的办法

如果要对数据库进行N*N次的查询才能取出多级类别的树,这是个糟糕的解决办法。

梅花雪的解决办法是一次取出,多次利用。我受到启发。他在客户端完成这个操作。然而字符串是在服务器端生成的。

我的做法是在服务器端将数据分两次从库里取出,用两个交叉索引的数组来存放对象。然后对这两个数组进行正则查询的操作,分级找出,生成类别菜单字符串

数据表和css还有图片我都打包了。

<?php
//$q = "select CONCAT_WS( '_', id , pid) as indexKey , CONCAT_WS('_' , title , link , published , ordering , access , params  ) as valueKey  from #__collector_menu where access>=0 ";

/**
* 共计查找数据库两次,使用CONCAT_WS函数两次
* 使用正则搜数组一次(N条记录)*N次(N*X条记录)*(N*X)次(Y条记录,依次类推)。
* 对于2级类,则是 2数据库+1*N次正则。
* 如果用数据库,则是1数据库 * N次数据库。
* 如果用数组遍历,则是1数据库(Y条记录)+N*Y+(Y-N)次数组循环。
*
* 不知道哪个效率更高。
*/


$q = "select CONCAT_WS( '_', id , pid) as indexKey , id , pid ,  title , link , published , ordering , access , params   from #__collector_menu where access>=0 ";
$database->setQuery($q);
$rowsIndex = $database->loadResultArray(0,'id','indexKey'); //prt($rowsIndex);
$rows = $database->loadAssocList( 'indexKey'); //prt($rows);

/* 搜出所有的顶级类别 */
$reg = "#([0-9]+)_0#i";
$mainIndex=preg_grep($reg,$rowsIndex); //prt($mainIndex);

/* 为每一个顶级类别找出其子类别 */
foreach ($mainIndex as $mkey=>$vk) {
 /* 取出模版 */
 $mainItem = MainItemTpl();
 $mainItem = str_replace('{topTitle}',$rows[$vk]['title'],$mainItem);
 $sub='';

 /* 在索引数组里找出下级类别 */
 $reg = "#([0-9]+)_".$mkey."#i";
 $subIndex=preg_grep($reg,$rowsIndex); //prt($subIndex);

 /* 如果找到 */
 if(count($subIndex)){
  /* 组合子菜单 */
  $sub ='<table width="100%" border="0" cellspacing="0" cellpadding="0" bgcolor="#F4FBF4">'."/n";
  foreach ($subIndex as $subKey=>$subV) {
   //echo $subKey."=".$subV."<br/>";//prt($rows[$subV]);
   
   /* 组合子菜单 */

   $sub .="<tr>/n";
   $sub .='<td width="17%" align="center" class="tdline"><img src="img/newitem.gif" width="7" height="10"/></td>';
   $sub .='<td width="83%" class="tdline"><a href="'.$rows[$subV][link].'" >'.$rows[$subV]['title']."</a></td>/n";
   $sub .="</tr>";

  }//遍历字项结束
  $sub .="</table>/n";
 }//end if
 
 $mainItem = str_replace('{sub}',$sub,$mainItem);
 echo $mainItem;
}


function MainItemTpl(){

$mainTpl = <<<EOD

<!-- mainItem -->
<table width="120" border="0" align="center" cellpadding="0" cellspacing="0">
  <tr>
    <td width="19" height="24" align="center" background="img/newlinebg2.gif"><img src="img/topitem2.gif" width="11" height="13" border="0" onClick="showHide(this)" class="topitem"/></td>
    <td width="101" background="img/newlinebg2.gif" class="topitem" onClick="showHide(this)">{topTitle}</td>
  </tr>
  <tr>
    <td colspan="2" align="center">
 {sub}
 </td>
  </tr>
</table>
<!-- /mainItem -->

EOD;
return $mainTpl;

}//end func


?>

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值