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的实现,有更好的方法或思路,欢迎留言交流!

  • 相关阅读:
    NOIP2011 D1T1 铺地毯
    NOIP2013 D1T3 货车运输 倍增LCA OR 并查集按秩合并
    POJ 2513 trie树+并查集判断无向图的欧拉路
    599. Minimum Index Sum of Two Lists
    594. Longest Harmonious Subsequence
    575. Distribute Candies
    554. Brick Wall
    535. Encode and Decode TinyURL(rand and srand)
    525. Contiguous Array
    500. Keyboard Row
  • 原文地址:https://www.cnblogs.com/cyfblogs/p/11979382.html
Copyright © 2011-2022 走看看