中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

PHP+Redis怎么實現點贊效果

發布時間:2021-11-30 18:06:10 來源:億速云 閱讀:209 作者:iii 欄目:開發技術

這篇文章主要介紹“PHP+Redis怎么實現點贊效果”,在日常操作中,相信很多人在PHP+Redis怎么實現點贊效果問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”PHP+Redis怎么實現點贊效果”的疑惑有所幫助!接下來,請跟著小編一起來學習吧!

前言

點贊其實是一個很有意思的功能。基本的設計思路有大致兩種, 一種自然是用mysql(寫了幾百行的代碼都還沒寫完,有毒)啦

數據庫直接落地存儲, 另外一種就是利用點贊的業務特征來扔到redis(或memcache)中, 然后離線刷回mysql等。

我這里所講的功能都是基于我之前的項目去說的,所以有些地方可以不用管的,我主要是記錄這個功能的實現思路,當你理解了,基本想用什么鬼語言寫都一樣的。

直接寫入Mysql

直接寫入Mysql是最簡單的做法。

做三個表即可,

  • comment_info

    記錄文章的主要內容,主要有like_count,hate_count,score這三個字段是我們本次功能的主要字段。

  • comment_like

    記錄文章被贊的次數,已有多少人贊過這種數據就可以直接從表中查到;

  • user_like_comment

    記錄用戶贊過了哪些文章, 當打開文章列表時,顯示的有沒有贊過的數據就在這里面;

缺點

  • 數據庫讀寫壓力大

    熱門文章會有很多用戶點贊,甚至是短時間內被大量點贊, 直接操作數據庫從長久來看不是很理想的做法

redis存儲隨后批量刷回數據庫

redis主要的特點就是快, 畢竟主要數據都在內存嘛;

另外為啥我選擇redis而不是memcache的主要原因在于redis支持更多的數據類型, 例如hash, set, zset等。

下面具體的會用到這幾個類型。

優點

  • 性能高

  • 緩解數據庫讀寫壓力

    其實我更多的在于緩解寫壓力, 真的讀壓力, 通過mysql主從甚至通過加入redis對熱點數據做緩存都可以解決,

    寫壓力對于前面的方案確實是不大好使。

缺點

  • 開發復雜

    這個比直接寫mysql的方案要復雜很多, 需要考慮的地方也很多;

  • 不能保證數據安全性

    redis掛掉的時候會丟失數據, 同時不及時同步redis中的數據, 可能會在redis內存置換的時候被淘汰掉;

    不過對于我們點贊而已, 稍微丟失一點數據問題不大;

其實上面第二點缺點是可以避免的,這就涉及到redis 的一些設計模式,不懂沒關系,我盡量詳細的寫,后面我會給出如何解決這個缺點。

設計功能前知識準備

  1.將要用到的redis數據類型(具體的類型說明,請看底部鏈接,有詳細說明):

  • zset  這個類型主要用來做排序或者數字的增減,這里被用作like 和hate的數字記錄,以及熱度的記錄。

  • set  這個是無序集合,主要用來記錄今天需不需要更新,將今天被點贊(包括點討厭)過的文章id記錄下來,方便晚上或者有時間對這部分數據更新。

  • hash  這個是散列,主要用來存儲數據以及索引。這里被用來記錄用戶對哪個文章點了什么,方便下次判斷(我看過一些網上的介紹使用set來記錄,那個也可以,但是本人覺得這樣做更省空間,以及方便管理,再有就是hash的速度快)。

  • list  這個是隊列大佬,我們的數據能不能 安全 回到mysql就靠它了。

  2.關于熱度如何去判斷:

  大家都知道,文章獲得點贊數越高,文章的熱度就越高,那么怎么判斷呢?不就直接記錄點贊數就行啦,但是對于最新的文章怎么辦?例如有一篇文章一年前發布的,獲得50個贊,有篇最新文章獲得49個贊,但是按照上面所說的一年前的文章熱度還比最新的高,這就不合理了,文章都是時效性,誰都想看最新最熱的。

  so!我們要換個方法去處理這個時效性,絕大部分語言都有 時間戳 生成的方法,時間戳隨著時間越新,數字越大,直接將時間戳初始化賦值給文章的score,這樣最新的文章相比以前的文章就會靠前了。接著是點贊對score的影響,我們假設一天得到20個贊算是一天最熱,一天60*60*24=86400秒,然后得到一個贊就是得到86400 / 20 = 4320分。具體數字看自己的業務需求定,我只是舉例子而已。點hate當然也會減去相應的數字。

  1. <?php


  2. class Good

  3. {

  4.     public $redis = null;


  5.     //60*60*24/20=4320,每個點贊得到的分數,反之即之。

  6.     public $score = 4320;


  7.     //點贊增加數,或者點hate增加數

  8.     public $num = 1;


  9.     //init redis

  10.     public $redis_host = "127.0.0.1";

  11.     public $redis_port = "6379";

  12.     public $redis_pass = "";


  13.     public function __construct()

  14.     {

  15.         $this->redis = new Redis();

  16.         $this->redis->connect($this->redis_host,$this->redis_port);

  17.         $this->reids->auth($this->redis_pass);

  18.     }


  19.     /**

  20.     * @param int $user_id 用戶id

  21.     * @param int $type 點擊的類型 1.點like,2.點hate

  22.     * @param int $comment_id 文章id

  23.     * @return string json;

  24.     */

  25.     public function click($user_id,$type,$comment_id)

  26.     {

  27.         //判斷redis是否已經緩存了該文章數據

  28.         //使用:分隔符對redis管理是友好的

  29.         //這里使用redis zset-> zscore()方法

  30.         if($this->redis->zscore("comment:like",$comment_id))

  31.         {

  32.             //已經存在

  33.             //判斷點的是什么

  34.             if($type==1)

  35.             {

  36.                 //判斷以前是否點過,點的是什么?

  37.                 //redis hash-> hget()

  38.                 $rel = $this->redis->hget("comment:record",$user_id.":".$comment_id);

  39.                 if(!$rel)

  40.                 {

  41.                     //什么都沒點過

  42.                     //點贊加1

  43.                     $this->redis->zincrby("comment:like",$this->num,$comment_id);

  44.                     //增加分數

  45.                     $this->redis->zincrby("comment:score",$this->score,$comment_id);

  46.                     //記錄上次操作

  47.                     $this->redis->hset("comment:record",$user_id.":".$comment_id,$type);


  48.                     $data = array(

  49.                         "state" => 1,

  50.                         "status" => 200,

  51.                         "msg" => "like+1",

  52.                     );

  53.                 }

  54.                 else if($rel==$type)

  55.                 {

  56.                     //點過贊了

  57.                     //點贊減1

  58.                     $this->redis->zincrby("comment:like",-($this->num),$comment_id);

  59.                     //增加分數

  60.                     $this->redis->zincrby("comment:score",-($this->score),$comment_id);

  61.                     $data = array(

  62.                         "state" => 2,

  63.                         "status" => 200,

  64.                         "msg" => "like-1",

  65.                     );

  66.                 }

  67.                 else if($rel==2)

  68.                 {

  69.                     //點過hate

  70.                     //hate減1

  71.                     $this->redis->zincrby("comment:hate",-($this->num),$comment_id);

  72.                     //增加分數

  73.                     $this->redis->zincrby("comment:score",$this->score+$this->score,$comment_id);

  74.                     //點贊加1

  75.                     $this->redis->zincrby("comment:like",$this->num,$comment_id);

  76.                     //記錄上次操作

  77.                     $this->redis->hset("comment:record",$user_id.":".$comment_id,$type);


  78.                     $data = array(

  79.                         "state" => 3,

  80.                         "status" => 200,

  81.                         "msg" => "like+1",

  82.                     );

  83.                 }

  84.             }

  85.             else if($type==2)

  86.             {

  87.                 //點hate和點贊的邏輯是一樣的。參看上面的點贊

  88.                 $rel = $this->redis->hget("comment:record",$user_id.":".$comment_id);

  89.                 if(!$rel)

  90.                 {

  91.                     //什么都沒點過

  92.                     //點hate加1

  93.                     $this->redis->zincrby("comment:hate",$this->num,$comment_id);

  94.                     //減分數

  95.                     $this->redis->zincrby("comment:score",-($this->score),$comment_id);

  96.                     //記錄上次操作

  97.                     $this->redis->hset("comment:record",$user_id.":".$comment_id,$type);


  98.                     $data = array(

  99.                         "state" => 4,

  100.                         "status" => 200,

  101.                         "msg" => "hate+1",

  102.                     );

  103.                 }

  104.                 else if($rel==$type)

  105.                 {

  106.                     //點過hate了

  107.                     //點hate減1

  108.                     $this->redis->zincrby("comment:hate",-($this->num),$comment_id);

  109.                     //增加分數

  110.                     $this->redis->zincrby("comment:score",$this->score,$comment_id);


  111.                     $data = array(

  112.                         "state" => 5,

  113.                         "status" => 200,

  114.                         "msg" => "hate-1",

  115.                     );

  116.                     return $data;

  117.                 }

  118.                 else if($rel==2)

  119.                 {

  120.                     //點過like

  121.                     //like減1

  122.                     $this->redis->zincrby("comment:like",-($this->num),$comment_id);

  123.                     //增加分數

  124.                     $this->redis->zincrby("comment:score",-($this->score+$this->score),$comment_id);

  125.                     //點hate加1

  126.                     $this->redis->zincrby("comment:hate",$this->num,$comment_id);


  127.                     $data = array(

  128.                         "state" => 6,

  129.                         "status" => 200,

  130.                         "msg" => "hate+1",

  131.                     );

  132.                     return $data;

  133.                 }

  134.             }

  135.         }

  136.         else

  137.         {

  138.             //未存在

  139.             if($type==1)

  140.             {

  141.                 //點贊加一

  142.                 $this->redis->zincrby("comment:like",$this->num,$comment_id);

  143.                 //分數增加

  144.                 $this->redis->zincrby("comment:score",$this->score,$comment_id);

  145.                 $data = array(

  146.                     "state" => 7,

  147.                     "status" => 200,

  148.                     "msg" => "like+1",

  149.                 );

  150.             }

  151.             else if($type==2)

  152.             {

  153.                 //點hate加一

  154.                 $this->redis->zincrby("comment:hate",$this->num,$comment_id);

  155.                 //分數減少

  156.                 $this->redis->zincrby("comment:score",-($this->score),$comment_id);


  157.                 $data = array(

  158.                     "state" => 8,

  159.                     "status" => 200,

  160.                     "msg" => "hate+1",

  161.                 );

  162.             }

  163.             //記錄

  164.             $this->redis->hset("comment:record",$user_id.":".$comment_id,$type);

  165.         }


  166.         //判斷是否需要更新數據

  167.         $this->ifUploadList($comment_id);


  168.         return $data;

  169.     }


  170.     public function ifUploadList($comment_id)

  171.     {

  172.         date_default_timezone_set("Asia/Shanghai");

  173.         $time = strtotime(date('Y-m-d H:i:s'));


  174.         if(!$this->redis->sismember("comment:uploadset",$comment_id))

  175.         {

  176.             //文章不存在集合里,需要更新

  177.             $this->redis->sadd("comment:uploadset",$comment_id);

  178.             //更新到隊列

  179.             $data = array(

  180.                 "id" => $comment_id,

  181.                 "time" => $time,

  182.             );

  183.             $json = json_encode($data);

  184.             $this->redis->lpush("comment:uploadlist",$json);

  185.         }

  186.     }

  187. }


  188. //調用

  189. $user_id = 100;

  190. $type = 1;

  191. $comment_id= 99;

  192. $good = new Good();

  193. $rel = $good->click($user_id,$type,$comment_id);

  194. var_dump($rel);

到此,關于“PHP+Redis怎么實現點贊效果”的學習就結束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學習,快去試試吧!若想繼續學習更多相關知識,請繼續關注億速云網站,小編會繼續努力為大家帶來更多實用的文章!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

七台河市| 郯城县| 商洛市| 高青县| 巨鹿县| 新津县| 崇仁县| 台湾省| 绥棱县| 罗源县| 灵川县| 玉树县| 北宁市| 吉水县| 凌云县| 巫溪县| 浦城县| 固镇县| 汤原县| 红安县| 荥阳市| 正阳县| 黔江区| 光泽县| 霍林郭勒市| 抚宁县| 科尔| 甘肃省| 石柱| 沙洋县| 哈尔滨市| 玉树县| 托里县| 台南市| 黄平县| 新郑市| 鸡泽县| 高青县| 昭通市| 鸡西市| 邹平县|