**
摘要: 前言點讚其實是乙個很有意思的功能。基本的設計思路有大致兩種, 一種自然是用mysql等資料庫直接落地儲存, 另外一種就是利用點讚的業務特徵來扔到redis(或memcache)中, 然後離線刷回mysql等。直接寫入mysql直接寫入mysql是最簡單的做法。做兩個表即可,1、post_like記錄文章被贊的次數,已有多少人讚過這種資料就可以直接從表中查到;2、user_like_...
前言點讚其實是乙個很有意思的功能。基本的設計思路有大致兩種, 一種自然是用mysql等
資料庫直接落地儲存, 另外一種就是利用點讚的業務特徵來扔到redis(或memcache)中, 然後離線刷回mysql等。
直接寫入mysql
直接寫入mysql是最簡單的做法。
做兩個表即可,
1、post_like
記錄文章被贊的次數,已有多少人讚過這種資料就可以直接從表中查到;
2、user_like_post
記錄使用者讚過了哪些文章, 當開啟文章列表時,顯示的有沒有讚過的資料就在這裡面;
缺點1、資料庫讀寫壓力大
redis儲存隨後批量刷回資料庫
redis主要的特點就是快, 畢竟主要資料都在記憶體嘛;
另外為啥我選擇redis而不是memcache的主要原因在於redis支援更多的資料型別, 例如hash, set, zset等。
下面具體的會用到這幾個型別。
優點1、效能高
2、緩解資料庫讀寫壓力
其實我更多的在於緩解寫壓力, 真的讀壓力, 通過mysql主從甚至通過加入redis對熱點資料做快取都可以解決,
寫壓力對於前面的方案確實是不大好使。
缺點1、開發複雜
這個比直接寫mysql的方案要複雜很多, 需要考慮的地方也很多;
2、不能保證資料安全性
redis掛掉的時候會丟失資料, 同時不及時同步redis中的資料, 可能會在redis記憶體置換的時候被淘汰掉;
不過對於我們點讚而已, 稍微丟失一點資料問題不大;
具體設計
mysql設計
這一塊和寫入寫mysql是一樣的,畢竟是要落地儲存的。
所以還是同樣的需要post_like, user_like_post這兩表儲存文章被點讚的個數(等統計), 使用者對那些文章點了贊(取消贊)。
這兩表分別通過post_id, user_id進行關聯。
redis設計部分:
post_set
在redis中弄乙個set存放所有被點讚的文章
post_user_like_set_
對每個post以post_id作為key, 搞乙個set存放所有對該post點讚的使用者;
post_user_like__
將每個使用者對每個post的點讚情況放到乙個hash裡面去, hash的字段就
隨意跟進需求來處理就行了。
為啥用hash
只所以用hash是因為完全可以用hash來儲存乙個點贊的物件, 對應資料庫的一行記錄。
當然有同學會說用key, value也可以, 將所有的資料序列化(json_encode等)
後全部放到value裡面去。 反覆序列化也是乙個很大的開銷不是, hash可以很
方便的修改某個字段, 而序列化和反序列化的操作。
post__counter
對每個post維護乙個計數器, 用來記錄當前在redis中的點讚數,
這裡我們只用counter記錄尚未同步到mysql中的點讚數(可以為負), 每次
刷回mysql中時將counter中的資料和資料庫已有的讚數相加即可。
使用者點讚/取消贊
獲取user_id, post_id, 查詢該使用者是否已經點過贊, 已點過則不允許再次點讚,
或者設計為前端允許使用者點, 只是後台不重複計算;
這裡需要注意的是使用者點讚的記錄可能在資料庫中, 也可能在快取中, 所以查詢的時候
快取和資料庫都要查詢, 快取沒有再查詢資料庫。
將使用者的點讚/取消贊的情況記錄在redis中, 具體為:
1、寫入post_set
將post_id寫入post_set
2、寫入post_user_like_set_
將user_id寫入post_user_like_set_
3、寫入post_user_like__
將使用者點讚資料, 例如贊狀態, post_id, user_id, ctime(操作時間), mtime(修改時間)寫入post_user_like__中
4、更新post__counter
更新post__counter, 這裡的更新稍晚複雜一點, 需要和前面一樣先獲取當前使用者是否對這個post點過贊
如果點過, 並且本次是取消贊, counter減一, 如果沒點過, 本次是點讚, counter加一。
如果原來是取消贊的情況, 本次是點讚, counter加一。
同步刷回資料庫
迴圈從post_set中pop出來乙個post_id至到空
根據 , 每次從post_user_like_set_中pop出來乙個user_id直到空
根據post_id, user_id, 直接獲取對應的hash表的內容(post_user_like__
將hash表中的資料寫入user_like_post表中
將post__counter中的資料和post_like中的資料相加, 將結果寫入到post_like表中
頁面展示
1、查詢使用者點讚情況
前面已經說過, 需要同時查詢redis和mysql
2、查詢post點讚統計
同樣需要查詢redis中的post__counter和mysql的post_like表, 並將兩者相加
得到的結果才是正確的結果
總結解決了mysql讀寫的問題
但沒有針對使用者量較大的場景考慮分表的設計, 可以考慮針對user_id或者post_id進行分表
點讚功能與redis
摘要 前言點讚其實是乙個很有意思的功能。基本的設計思路有大致兩種,一種自然是用mysql等資料庫直接落地儲存,另外一種就是利用點讚的業務特徵來扔到redis 或memcache 中,然後離線刷回mysql等。直接寫入mysql直接寫入mysql是最簡單的做法。做兩個表即可,1 post like記錄...
redis實現點讚功能參考
public void likearticle long articleid,long likeduserid,long likedpostid likeduserid likedpostid articleid,likeduserid,likedpostid synchronized this l...
Redis實現點讚功能模組
之前看了一篇文章,講redis的應用場景,其中乙個應用場景就是實現點讚功能,紙上得來恐覺淺,必須實戰一波 使用者某篇文章的點讚數 使用hashmap資料結構,hashmap中的key為articleid,value為set,set中的值為使用者id,即hashmap 使用者總的點讚數 使用hashm...