我现在是要做类似与发红包的功能,比如,用户刚进去的时候,跳出一个红包,用户点击领取红包,这时候,用户消费的时候可用这些红包抵扣。
现在有一个问题,一个用户只能领一次。我的数据库表该怎么建呢?首先肯定是要先建一个红包表的, 我有两种方法:
第一种是 直接在 红包表里面建立一个用户的list字段。到时候如果用户领了红包,把用户的id存到这个list里面,那就能做唯一标识了。但是这种方法有一种缺陷,就是,如果一种红包领取记录达到上万条,到时候查询的时候不会很卡吗?
第二种就是另外建立一个用户领取红包表,就像mysql一样,每个记录都绑定用户id和红包id,但是这种方法,要查询的时候貌似挺麻烦。好像挺费cdn的。。。
正在纠结哪种方法好,求大神给一点建议?
第二种吧
2个集合,
红包集合redPacket(_id, rid,money,start,end) => _id,红包id,红包金额,领取开始时间,领取截止时间
红包领取集合userRedPacketRecord(_id,openid,rid,mony,dateline) _id,openid,红包id,红包金额,领取时间
查询的时候lookup连2个表,查一次就行,既可以查询红包是否过期,也能查询某用户是否已领过
// 云函数入口函数
exports.main = async(event, context) => {
const _ = db.command
const $ = _.aggregate
var now = (new Date()).valueOf(), // 当前时间戳,毫秒级
rid = 1, // 红包id
openid = '用户openid'
return db.collection('redPacket').aggregate()
.addFields({
isAvailable: $.and([$.gte(['$end', now]), $.lte(['$start', now])])
})
.match({
rid: rid
})
.limit(1)
.project({
_id: 0,
rid: 1,
money: 1,
isAvailable: 1,
start:1,
end:1
})
.group({
_id:'any',
redPacket: $.push('$$ROOT')
})
.lookup({
from: 'userRedPacketRecord',
pipeline: $.pipeline()
.match({
rid: rid,
openid: openid
})
.limit(1)
.project({
_id: 0,
rid: 1,
openid: 1,
dateline: 1
})
.done(),
as: 'userRecord',
})
.end()
}
第一种吧,用掉就标记不再让查询到