zoukankan      html  css  js  c++  java
  • php 如何生成path及其日常维护

    php 如何生成path及其日常维护

    path字段重要性不言而喻,在查询的时候,如果只用pid,查询效率会很低,增加path,查询效率大大提高,最起码不用递归查库了,重点是维护推荐关系的时候要维护path以及更改。

    在path分隔符中,建议使用英文','号,方便查询。切记使用like,最好是使用find_in_set

    一、path字段

    1、首先是在会员表中,得有path字段,一些情况下,path字段会比较长,建议类型为text,不建议varchar

    2、当推荐新会员的时候,借助父级的path,后面拼接上父级的id,就是新会员的path

    1 $path = $path ? $pid . ',' . $path : $pid;

    二、后台修改推荐人

    这种情况是比较麻烦的,就是后台想更改某会员的父级,如果单纯的只有pid,只更改pid就行了,但是存在path,更改当前会员pid和path的同时,当前会员所有团队成员的path也得更改。

    这里存在当前会员之前有上级和之前没有上级两种情况

    1、已有上级,这时候所有团队成员的path为当前会员新path再拼接上当前会员的id,再拼接上下级之前的path中截取当前用户id之后的部分

    2、没有上级,那所有团队成员的新path就简单了,直接为当前会员新path,直接拼接上下级的path即可

     1 if ($params['pid'] && $params['pid'] != $row['pid']) {
     2     //说明选择了新上级,而且确实和之前上级不一样了,如果新上级和之前上级一样,无需更新path
     3     //首先验证pid不在目标子串中
     4     $arr = explode(',',$puser['path']);
     5     if ($arr && in_array($ids,$arr)) {
     6         $this->error('自己下级不能成为新上级');
     7     }
     8     //更新当前会员自己的pid和path,
     9     $params['path'] = $puser['path'] ? $puser['path'] . ',' . $params['pid'] : $params['pid'];
    10     if ($row['pid']) {
    11         //说明当前会员之前就有上级,
    12         //则所有下级的新path为$params['path'] 再拼接上当前会员的id,再拼接上下级之前的path中截取当前用户id之后的部分
    13         $sql = "update sn_user set path = (CONCAT('".$params['path']."',',',".$ids.",SUBSTRING_INDEX(path,".$ids.",-1))) where FIND_IN_SET(".$ids.",path)";
    14     } else {
    15         //说明当前会员之前没有上级,那所有下级的新path就简单了,直接为$params['path'],直接拼接上下级的path即可
    16         $sql = "update sn_user set path = (CONCAT('".$params['path']."',',',path)) where FIND_IN_SET(".$ids.",path)";
    17     }
    18     $this->model->query($sql);
    19 } else {
    20     unset($params['pid']);
    21 }

    三、在无path下如何增加path

    这种情况一般发生在已有一些会员的情况下,如果会员不多,自己手动改就行,当然,如果会员量比较大的话,手动就费劲了,所以有时候写一个脚本也是挺管用的。

    1、首先在会员表新增path字段,默认为空值,然后新建一个标识path_status,在会员量大的时候进行分段查询

    2、借助脚本,更新path,这里写的了一个递归查询,如有更好的方法,欢迎留言交流!

     1 /*
     2  * 更新path字段
     3  */
     4 public function update_path()
     5 {
     6     //更新所有的用户的path]
     7     $users = Db::name('member')
     8         ->where([
     9             'pid'=>['gt',0],
    10             'path_status'=>0,
    11         ])
    12         ->field('id,pid,path')
    13         ->limit(100)->select();
    14     $count = 0;
    15     foreach ($users as $v) {
    16         //计算path,修改path_status为1
    17         $path = $this->get_path(0,$v['pid']);
    18         //$path = '0-'.$path;//拼接上顶级0
    19         Db::name('member')->where('id',$v['id'])->update(['path'=>$path,'path_status'=>1]);
    20         $count++;
    21     }
    22     echo $count;die;
    23 }

    这里是获取path的方法:

     1 /*
     2  * 递归查库,获取上级pid
     3  */
     4 public function get_path($path,$pid)
     5 {
     6     $path = $path ? $pid.'-'.$path : $pid;
     7     $rid = Db::name('member')->where('id',$pid)->value('pid');
     8     if ($rid) {
     9         return self::get_path($path,$rid);
    10     }
    11     return $path;
    12 }

    如果对于path的实现,有更好的方法或思路,欢迎留言交流!

  • 相关阅读:
    第八讲、原型模式
    第七讲、建造者模式
    第六讲、抽象工厂模式
    第五讲、工厂方法模式
    第四讲、简单工厂模式
    第三讲、策略模式
    第二讲、备忘录模式
    第一讲、单例模式
    二、中国黑客
    java 17
  • 原文地址:https://www.cnblogs.com/cyfblogs/p/11979382.html
Copyright © 2011-2022 走看看