初步設計了一下用戶簽到的設計方案,記錄下這種思路,以後可能需要完善。每月最多有31天,int32有32位,簽到與沒簽到只有兩種狀態,簽到用1來表示,未簽到用0來表示,因此可以用int32來表示用戶每月的簽到情況。
數據庫表(sign_record)的設計:
列 | 類型 | 描述 |
---|---|---|
id | int64 | 自增鍵 |
user_id | int64 | 索引,用戶表的id |
date_month | date | 索引,月份,形如2019-02 |
mask | int32 | 用戶簽到的數據 |
continue_sign_month | int32 | 用戶本月連續簽到的天數 |
需要解決的一些問題:假設當前服務器月份是month
1. 獲取用戶當月的簽到狀態:
根據服務器時間判斷當前的月份month,根據傳入的user_id和month去數據庫中查找用戶簽到的數據mask。
2. 簽到:
假設當日是本月第i天(這個可以計算得出),更新數據庫中mask: mask = mask | (1 << i),更新連續簽到天數+1
3. 判斷當日是否簽到:
如果mask & (1 << i)爲1,說明簽到了,如果爲0,說明未簽到。
4. 本月補籤:
補籤某個日期,假設是第j天,更新數據庫中mask: mask = mask | (1 << j),重新統計本月連續簽到天數,從第i位開始逆序遍歷統計天數。
5. 本月連續簽到天數:
直接返回數據庫中continue_sign_month字段。
6. 待續……
由於存在可能補籤的情況,需要記錄所有的簽到記錄,由於有了所有的簽到記錄,其實任何功能都可以實現,只是實現的複雜度可能不同。
這個只是簡單初步設計,歡迎大家討論交流。