会员积分功能模型设计
會員積分功能模型設(shè)計
最近在開發(fā)中遇上一個會員(用戶)積分的場景,我在網(wǎng)上查找相關(guān)設(shè)計文章,并沒有發(fā)現(xiàn)合適的方案,所以在此寫下我思考和設(shè)計的過程,供程序猿們參考。
積分管理這一功能,已經(jīng)算是十分常見,夸張點說是爛大街了的場景,但仔細(xì)分析后,發(fā)現(xiàn)要做好也不容易,得考量多個細(xì)節(jié),對初級程序員來說,也算是一個很有意義的練習(xí)題目。以下內(nèi)容,沒有一行代碼,沒有一張圖表,也沒有設(shè)計文檔參見的模式套路,對一些人來說,讀之枯燥,但是,如果您對“設(shè)計”工作有興趣,相信我,不妨一讀。
因為不是專業(yè)做CRM或銷售領(lǐng)域的,對“會員積分”的需求了解并不深,這里僅僅是對一般的需求場景進(jìn)行分析設(shè)計,權(quán)當(dāng)拋磚引玉,如果有更多復(fù)雜需求,還請留言,不吝賜教。
需求概要
假設(shè)某企業(yè)引入會員積分業(yè)務(wù)。會員有多種渠道獲得積分,另外還可以兌換積分。此外,積分有有效期,每項積分6個月不兌換,則自動失效。
請設(shè)計一下數(shù)據(jù)模型結(jié)構(gòu)和基本業(yè)務(wù)邏輯。要求能計算會員的總積分、當(dāng)前有效積分、最近7天內(nèi)要到期的積分,能統(tǒng)計每月、每季度、每年的積分發(fā)放、消費(fèi)、剩余情況。
接下來,我們來將需求細(xì)化,一步步完成對應(yīng)的設(shè)計。
需求一 記錄積分獲取和積分消費(fèi)
創(chuàng)建一個對象,里面記錄用戶id,獲得積分,原因等等,再記錄時間,就可以了。所以我們有了第一個實體模型:【積分記錄】
同樣的,積分消費(fèi),用一個對象記錄消費(fèi)情況,也記錄消費(fèi)積分、內(nèi)容、時間等。然后我們發(fā)現(xiàn)積分消費(fèi)可以用積分記錄模型,只是分?jǐn)?shù)為負(fù)數(shù)就好。
需求二 積分消費(fèi)校驗和積分統(tǒng)計
要統(tǒng)計某用戶積分,將他的積分記錄查詢出來,對積分字段求和就好。
在做積分消費(fèi)時,查詢用戶之前積分合計,如果分?jǐn)?shù)小于要消費(fèi)的積分,就返回不允許消費(fèi)。
需求三 積分過期
接下來考慮積分的有效期需求,比如積分以年為固定周期,每年將去年積分失效,或者每筆積分的有效期都是一年。我們先按后面一種情況考慮。
首先積分過期可以使用定期執(zhí)行的策略,查詢積分記錄,進(jìn)行過期處理。
很直觀地,在積分記錄里面,增加一個字段,記錄過期時間。定期檢查過期時候,判斷過期就號。但是,如果這筆積分被消費(fèi)了,那么就不存在過期的概念了,如果繼續(xù)按過期處理,那么積分統(tǒng)計時,無法區(qū)分這筆是否被消費(fèi)過,即需求2不能滿足。
一種方案,將消費(fèi)時消費(fèi)了之前哪些積分記錄下來,但是這種方式的計算量大,額外增加不少存儲空間,并不好。
另一種方案,在積分記錄里面增減一個“剩余積分”字段,用戶的有效積分改為“剩余積分”字段的合計。積分消費(fèi)時,按時間順序取積分記錄,逐條扣減剩余積分。積分過期時,簡單地把剩余積分清零就好。
積分統(tǒng)計就改為統(tǒng)計【積分記錄】的“剩余積分”字段。
但是這仍然有個問題,我們看下一條需求。
需求四 求截止上月的積分統(tǒng)計
之前的方案,能解決當(dāng)前實時的積分統(tǒng)計,但是假設(shè)某用戶上個月有條記錄未過期,但這個月過期,剩余積分為0,這時候我們就統(tǒng)計不出上個月的積分情況了。這是因為“剩余積分”里面記錄了被消費(fèi)扣減的積分和過期的積分,無法區(qū)分,“過期時間”這個信息還不足夠,除非我們再增加字段,將消費(fèi)扣除的積分和過期扣除的積分區(qū)分開來,算上個月積分時,排除過期時間晚于1號的過期積分記錄。
但是這樣一來,積分的業(yè)務(wù)規(guī)則就相當(dāng)復(fù)雜了。為此我們調(diào)整一下方案。
首先,將積分過期也視為一條【積分記錄】,積分過期就增加一筆“過期”的【積分記錄】。之前引入的“剩余積分”字段取消。然后增加一個【積分賬戶】實體模型,里面有一個指針,指向最后一條被扣減的積分記錄,以及該記錄的剩余積分。比如有某用戶有10條積分獲取記錄,每條積分都是10分(id從1-10),然后消費(fèi)一筆35積分,那么 記錄最后一次消費(fèi)積分時,積分指針id=4,該記錄剩余積分等于5。然后,假設(shè)第二天前5條都過期了,那么【積分賬戶】里的指針指向id=5,剩余積分0。
同時,我們將用戶的總積分、剩余積分也存在【積分賬戶】里,獲取這個信息時候就不用再從【積分記錄】里面去計算了。
要統(tǒng)計截止上個月的積分,只需要查詢【積分記錄】里截止上個月的記錄,匯總積分字段即可。
要統(tǒng)計近期過期積分,查詢【積分賬戶】里指針之后的記錄,并且滿足近期過期條件的即可。
假設(shè)數(shù)據(jù)有異常,需要調(diào)整某個用戶很久以前的一筆積分,那么【積分賬戶】是能被重新計算出來的,取出所有積分獲取記錄,積分消費(fèi)記錄,按時間順序,逐條執(zhí)行積分賬戶消費(fèi)處理和積分過期處理就行。
最后,羅列一下需求,如果你有其他設(shè)計思路,看看是否滿足以下需求:
能記錄用戶獲取積分的明細(xì)信息并展示;
能記錄用戶獲取積分和消費(fèi)積分的明細(xì)信息并展示;
消費(fèi)積分時,要檢查積分余額是否大于等于要消費(fèi)的積分;
積分有有效期,過期失效;
能統(tǒng)計用戶的總積分,剩余積分,能提醒用戶近期過期積分;
能統(tǒng)計之前某個時間點比如上個月的積分情況;
能支持調(diào)整之前的積分?jǐn)?shù)據(jù);
能滿足數(shù)據(jù)量較大或巨大的場景;
補(bǔ)充,高并發(fā)大數(shù)據(jù)量如何處理
高并發(fā)場景,可能要引入負(fù)載均衡部署,這時候一般的處理邏輯會引入并發(fā)問題,對此業(yè)內(nèi)有很多對應(yīng)方案了,簡單的處理辦法,使用消息隊列,將并發(fā)請求轉(zhuǎn)換為單一隊列(串行)。這里給出一個簡單方案。
首先,所有增加和消費(fèi)積分的請求,都發(fā)送到 redis 里(把 redis 當(dāng)作消息隊列用)。然后,部署一個應(yīng)用專門處理積分檢查和持久化操作,按順序執(zhí)行請求即可,這樣就不會有并發(fā)沖突了。如果一個應(yīng)用處理還是不夠,那么也可以部署多個應(yīng)用,在處理積分請求時,針對這個用戶id加鎖(把 redis 當(dāng)作分布式鎖),完成后解鎖。
大數(shù)據(jù)量場景,可以考慮按年/月將積分記錄轉(zhuǎn)移到歷史記錄表,降低【積分記錄】表的數(shù)量量即可。
總結(jié)
以上是生活随笔為你收集整理的会员积分功能模型设计的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: AD中设置PCB线间距
- 下一篇: 招隐-古琴曲-山中鸣琴,万籁声沉沉,何泠