PHP+Redis例【一】いいね+熱上編

33290 ワード

今回の冒頭は、この時間の積み重ねをまとめてみましょう.くだらないことはあまり言わないで、直接やります.
前言
いいねは実はおもしろい機能です.基本的なデザインの考え方は大体2つあります.1つはmysql(数百行のコードを書いてもまだ書き終わっていないので、毒があります)です.
データベースは直接格納され,もう1つは点賛の業務特徴を利用してredis(またはmemcache)に投げ込まれ,オフラインでmysqlなどにブラシが戻る.
私がここで話している機能はすべて私の前のプロジェクトに基づいて話しているので、一部の場所は気にしないことができます.私は主にこの機能の実現構想を記録しています.あなたが理解したら、基本的にどんな幽霊言語で書いても同じです.
Mysqlへの直接書き込み
Mysqlに直接書き込むのが一番簡単です.
3つの時計を作ればいいです.
  • comment_infoは文章の主な内容を記録して、主にlike_がありますcount,hate_count,scoreの3つのフィールドは、今回の機能の主なフィールドです.
  • comment_likeは文章がほめられた回数を記録し、何人がこのようなデータを褒めたことがあるかを直接表から調べることができる.
  • user_like_Commentはユーザーがどの文章を褒めたかを記録し、文章リストを開くと、褒めたことがあるかどうかのデータがここに表示されます.

  • 欠点
  • データベース読み書き圧力大ヒット記事には多くのユーザーがいいねをしたり、短時間でたくさんいいねをされたりして、直接データベースを操作するのは長期的には理想的ではありません
  • redisストレージはその後、一括してデータベースに消去されます.
    redisの主な特徴は速いことです.結局、主なデータはメモリにありますか.
    また、memcacheではなくredisを選択した主な理由は、hash、set、zsetなど、redisがより多くのデータ型をサポートしているからです.
    以下、これらのタイプを具体的に使用します.
    メリット
  • 高性能
  • データベースの読み書き圧力を緩和する実は私はもっと書く圧力を緩和することにあります.本当に読む圧力はmysqlの主従を通じてredisに参加することでホットスポットデータをキャッシュすることもできます.書く圧力は前の案にとって確かによくありません.

  • 欠点
  • 開発は複雑でmysqlを直接書くよりも複雑で、考慮すべき点も多い.
  • はデータの安全性を保証できないredisが掛けた時にデータを失うと同時に、redis中のデータをタイムリーに同期しないと、redisメモリが置換された時に淘汰される可能性がある.しかし、私たちに「いいね」をクリックしただけで、少しデータを失うのは問題ありません.

  • 実は上の第2点の欠点は避けることができて、これはredisのいくつかの設計モードに関連して、分からないのは大丈夫で、私はできるだけ詳しく書いて、後で私はどのようにこの欠点を解決するかを提供します.
    設計機能前の知識準備
      1.使用するredisデータ型:
  • zsetこのタイプは主にソートや数字の増減に用いられ、ここではlikeとhateの数字記録、熱の記録として用いられる.
  • setこれは無秩序な集合で、主に今日更新する必要があるかどうかを記録するために使用され、今日ほめられた(点嫌いを含む)文章idを記録し、夜やこのデータの更新に便利です.
  • hashこれはハッシュであり、主にデータおよびインデックスを格納するために使用されます.ここでは、ユーザーがどの文章に何を注文したかを記録し、次回の判断に便利です(ネット上の紹介を見てsetを使って記録してもいいですが、それはもっとスペースが省け、管理が便利で、あとはhashのスピードが速いと思います).
  • listこれはキューの大物で、私たちのデータがmysqlに安全に戻ることができるかどうかはそれに頼っています.

  •   2.熱についてどう判断するか:
    文章がいいねを獲得すればするほど、文章の熱が高くなることはよく知られていますが、どう判断すればいいのでしょうか.賛数を直接記録すればいいのではないでしょうか.しかし、最新の文章についてはどうしますか.例えば、1年前に発表された文章があって、50個の賛を獲得して、最新の文章が49個の賛を獲得していますが、上記の1年前の文章の熱は最新よりも高くて、これは合理的ではありません.文章はすべて時効性で、誰もが最新の最も熱いものを見たいと思っています.
      so!私たちは方法を変えてこの時効性を処理しなければなりません.ほとんどの言語にはタイムスタンプ生成の方法があります.タイムスタンプは時間が経つにつれて、数字が大きくなるにつれて、直接タイムスタンプを初期化して文章のscoreに割り当て、最新の文章は以前の文章より前になります.次にscoreに対するいいねの影響で、私たちは1日に20人のいいねを得るのが1日で最も暑くて、1日60*60*24=86400秒で、それから1人のいいねを得るのが86400/20=4320分だと仮定します.具体的な数字は自分のビジネスニーズを見て、私はただ例を挙げただけです.点hateはもちろん、対応する数字も減算されます.
    わくわくする時!直接コードをつけました!詳細なコメントが入っています!
      1 php
      2 
      3 class Good
      4 {
      5     public $redis = null;
      6 
      7     //60*60*24/20=4320,         ,    。
      8     public $score = 4320;
      9 
     10     //     ,   hate   
     11     public $num = 1;
     12 
     13     //init redis
     14     public $redis_host = "127.0.0.1";
     15     public $redis_port = "6379";
     16     public $redis_pass = "";
     17 
     18     public function __construct()
     19     {
     20         $this->redis = new Redis();
     21         $this->redis->connect($this->redis_host,$this->redis_port);
     22         $this->redis->auth($this->redis_pass);
     23     }
     24 
     25     /**
     26     * @param int $user_id   id
     27     * @param int $type       1. like,2. hate
     28     * @param int $comment_id   id
     29     * @return string json;
     30     */
     31     public function click($user_id,$type,$comment_id)
     32     {
     33         //  redis            
     34         //  :    redis      
     35         //    redis zset-> zscore()  
     36         if($this->redis->zscore("comment:like",$comment_id))
     37         {
     38             //    
     39             //       
     40             if($type==1)
     41             {
     42                 //        ,     ?
     43                 //redis hash-> hget()
     44                 $rel = $this->redis->hget("comment:record",$user_id.":".$comment_id);
     45                 if(!$rel)
     46                 {
     47                     //      
     48                     //   1
     49                     $this->redis->zincrby("comment:like",$this->num,$comment_id);
     50                     //    
     51                     $this->redis->zincrby("comment:score",$this->score,$comment_id);
     52                     //      
     53                     $this->redis->hset("comment:record",$user_id.":".$comment_id,$type);
     54 
     55                     $data = array(
     56                         "state" => 1,
     57                         "status" => 200,
     58                         "msg" => "like+1",
     59                     );
     60                 }
     61                 else if($rel==$type)
     62                 {
     63                     //    
     64                     //   1
     65                     $this->redis->zincrby("comment:like",-($this->num),$comment_id);
     66                     //    
     67                     $this->redis->zincrby("comment:score",-($this->score),$comment_id);
     68                     $data = array(
     69                         "state" => 2,
     70                         "status" => 200,
     71                         "msg" => "like-1",
     72                     );
     73                 }
     74                 else if($rel==2)
     75                 {
     76                     //  hate
     77                     //hate 1
     78                     $this->redis->zincrby("comment:hate",-($this->num),$comment_id);
     79                     //    
     80                     $this->redis->zincrby("comment:score",$this->score+$this->score,$comment_id);
     81                     //   1
     82                     $this->redis->zincrby("comment:like",$this->num,$comment_id);
     83                     //      
     84                     $this->redis->hset("comment:record",$user_id.":".$comment_id,$type);
     85 
     86                     $data = array(
     87                         "state" => 3,
     88                         "status" => 200,
     89                         "msg" => "like+1",
     90                     );
     91                 }
     92             }
     93             else if($type==2)
     94             {
     95                 // hate          。       
     96                 $rel = $this->redis->hget("comment:record",$user_id.":".$comment_id);
     97                 if(!$rel)
     98                 {
     99                     //      
    100                     // hate 1
    101                     $this->redis->zincrby("comment:hate",$this->num,$comment_id);
    102                     //   
    103                     $this->redis->zincrby("comment:score",-($this->score),$comment_id);
    104                     //      
    105                     $this->redis->hset("comment:record",$user_id.":".$comment_id,$type);
    106 
    107                     $data = array(
    108                         "state" => 4,
    109                         "status" => 200,
    110                         "msg" => "hate+1",
    111                     );
    112                 }
    113                 else if($rel==$type)
    114                 {
    115                     //  hate 
    116                     // hate 1
    117                     $this->redis->zincrby("comment:hate",-($this->num),$comment_id);
    118                     //    
    119                     $this->redis->zincrby("comment:score",$this->score,$comment_id);
    120 
    121                     $data = array(
    122                         "state" => 5,
    123                         "status" => 200,
    124                         "msg" => "hate-1",
    125                     );
    126                     return $data;
    127                 }
    128                 else if($rel==2)
    129                 {
    130                     //  like
    131                     //like 1
    132                     $this->redis->zincrby("comment:like",-($this->num),$comment_id);
    133                     //    
    134                     $this->redis->zincrby("comment:score",-($this->score+$this->score),$comment_id);
    135                     // hate 1
    136                     $this->redis->zincrby("comment:hate",$this->num,$comment_id);
    137 
    138                     $data = array(
    139                         "state" => 6,
    140                         "status" => 200,
    141                         "msg" => "hate+1",
    142                     );
    143                     return $data;
    144                 }
    145             }
    146         }
    147         else
    148         {
    149             //   
    150             if($type==1)
    151             {
    152                 //    
    153                 $this->redis->zincrby("comment:like",$this->num,$comment_id);
    154                 //    
    155                 $this->redis->zincrby("comment:score",$this->score,$comment_id);
    156                 $data = array(
    157                     "state" => 7,
    158                     "status" => 200,
    159                     "msg" => "like+1",
    160                 );
    161             }
    162             else if($type==2)
    163             {
    164                 // hate  
    165                 $this->redis->zincrby("comment:hate",$this->num,$comment_id);
    166                 //    
    167                 $this->redis->zincrby("comment:score",-($this->score),$comment_id);
    168 
    169                 $data = array(
    170                     "state" => 8,
    171                     "status" => 200,
    172                     "msg" => "hate+1",
    173                 );
    174             }
    175             //  
    176             $this->redis->hset("comment:record",$user_id.":".$comment_id,$type);
    177         }
    178 
    179         //          
    180         $this->ifUploadList($comment_id);
    181 
    182         return $data;
    183     }
    184 
    185     public function ifUploadList($comment_id)
    186     {
    187         date_default_timezone_set("Asia/Shanghai"); 
    188         $time = strtotime(date('Y-m-d H:i:s'));
    189 
    190         if(!$this->redis->sismember("comment:uploadset",$comment_id))
    191         {
    192             //
    193             $this->redis->sadd("comment:uploadset",$comment_id);
    194             //     
    195             $data = array(
    196                 "id" => $comment_id,
    197                 "time" => $time,
    198             );
    199             $json = json_encode($data);
    200             $this->redis->lpush("comment:uploadlist",$json);
    201         }
    202     }
    203 }
    204 
    205 //  
    206 $user_id = 100;
    207 $type = 1;
    208 $comment_id= 99;
    209 $good = new Good();
    210 $rel = $good->click($user_id,$type,$comment_id);
    211 var_dump($rel);

    お知らせ:
      1.上のコードは実装の方法の一つにすぎず、中のコードは細かく分けられておらず、ほとんどのパートナーが読むのに適しています.心を込めて見るといつも収穫がある.
      2.サードパーティのインタフェースについては、外で1階以上包装するべきですが、サイド幅が限られているので、私はこのような詳細をしません.ヒントは、参考にすることができます.
      3.残りのデータをデータに戻す方法は、次編以降に続きます.皆さん、心得を交流してください.
    redisマニュアル中国語版転送ドア:http://www.cnblogs.com/zcy_soft/archive/2012/09/21/2697006.html#string_INCR;
     
    転載先:https://www.cnblogs.com/sunshine-H/p/7922285.html