2016-05-12 63 views
2

我想用Redis製作通知系統,而不是使用MySQL,這是我用於系統其餘部分的。這是因爲我並不需要保存那麼多的數據,所以它可以保存在內存中,我希望它輕量且快速。我應該在Redis中使用哪種數據結構用於通知系統?

通知將暫時保留。我的意思是,我不想保存所有通知,但更像是每個用戶最近50次未見通知。所以我想到的第一件事是使用鏈表與50

加蓋的長度,我需要保存這些信息的通知:

postId 
commentId 
type 
time 
userId 
username 
image 

因此,也許一個JSON序列化的字符串是這樣的:

{"postId":1,"commentId":10,"type":1,"time":1462960058,"userId":2,"username":"Alexander","image":"ntfpRrgx.png"} 

該通知會是這樣輸出在客戶端:

Alexander commented on your post. 
Alexander replied to your comment. 

類型決定它是什麼類型的通知。我可以處理「類型」檢查客戶端並相應地輸出通知格式。但這是我難以接受的部分。

1)我需要能夠以有序方式保存通知,以便我知道哪個通知是最新的。

2)我需要能夠知道何時已經看到通知,以便它不會被註冊爲不再被看到。

3)我需要計算一下我可以向用戶顯示的看不見的通知。如果用戶點擊通知,我需要將其標記爲已看到的通知,並減少看不見的通知的數量。

4)我需要能夠將所有通知標記爲已標記,如果用戶希望這樣做。

5)我需要能夠獲得通知的一個子集,無論是看過還是看不見,就像MySQL的偏移量和限制。例如,用戶可以看到最新的5個通知,但他可以單擊下一個按鈕並查看下一個5和下一個5,依此類推。

我不知道如何在Redis上完成所有這些。

列表或集的關鍵可能是user:1:notification。我知道一個清單是排序的,我們可以從頭部和尾部添加和刪除。但是,我如何實現所有這些要點?

回答

1

1:您可以使用redis排序集(zset)操作並使用時間戳作爲分數,並將事件id(或整個事件json)用作成員。

ZADD我的設置鍵時間戳事件ID

然後獲得一個網頁的最新項目使用zrevrange命令。如果您選擇使用事件ID作爲成員,那麼您需要額外的結構來存儲事件字段。我會推薦HSET eventid,字段,值。

2:您可以通過成員刪除項目(事件ID)

ZREM我的設置鍵事件ID

3:假設你的zset只保留看不見的,那麼你可以使用ZCARD來獲得一套

ZCARD的大小我設置鍵

4:您可以使用

一次性刪除整個集合刪除我的設置鍵

5:您可以分頁使用zrange/zrevrange:

ZREVRANGE我的設置鍵啓動位置,位置

如果你需要保持看見也看不見的項目,那麼你就需要一個額外的zset你只能添加,但不要刪除一旦一個項目被看到

+0

因此,如果我理解正確,我應該只保存一些eventset在zset,然後使用hset保存有關事件的信息?我將如何有效地利用他們的信息獲取所有事件?在MySQL中,我只是做一個連接,但在這裏是不可能的。我不知道如何通過組合兩個數據結構來最好地獲取結果。 zset和hset,其中zset記錄Ids,而hset記錄信息。 – Alex

+0

據我所知,你只需要一次顯示一頁的細節。因此,一次不需要超過頁面大小的查找。 (您可以在一個請求中讀取整個事件哈希)。 Redis在查找時非常快速,因爲它可以從內存中獲取它們。如果它仍然是你的問題(例如你想最小化網絡往返),你可以再次存儲整個偶數(如json)。或者,您可以將所有事件中的事件字段存儲在單個密鑰中,例如hset event-data-key event-id:field value。這樣,您可以通過一個請求批量讀取給定頁面的事件標識的所有值。 – yurgis

+0

我知道如何在一個請求(一次往返)中讀取所有事件,只有當我將整個json作爲有序集合中的關鍵字時。但是,如果我只有eventId作爲排序集中的鍵,並且事件信息如此:hset eventId data「{.... json structure}」或hset eventId fields ... names ... ++ ,那麼我不知道如何在一個請求中以正確的順序將它們各自的數據從hset中提取出來,因爲redis不能像MySQL那樣進行連接。 – Alex

相關問題