在某些活动中,应用中的用户会获得奖励/惩罚点数。
我想为每位用户存储:
1- Bonused [EventID,#points]
2-惩罚列表[EventID,#points]
必须能够将新[EventID, #points]
对推送到列表中。
可以轻松检索EventID
列表。
#points
可以是十进制,而不仅仅是整数。
E.g。
用户#10
奖金:[[122,10],[128,10],[133,5]]
刑罚:[[22,10],[28,5],[13,1]]
·用户#1 余额:(10 + 10 + 5) - (10 + 5 + 1)= 9
我正在使用postgres + Redis。
E.g。 User.find(10).bonus_events => {'122':'10','128':'10','133':'5'}
E.g。 User.find(10).bonus_events =>
[{id:'122',points:'10'},
{id:'128',points:'10'}
{id:'133',points:'5'}]
不相信......
答案 0 :(得分:0)
ZSET(排序集)可以这种方式使用。在你的问题中,eventId和points是整数,所以Redis会以最大可能的效率存储它们。
Redis排序集是非重复的字符串集合。不同之处在于,排序集的每个成员都与得分相关联,用于从最小得分到最高得分排序。虽然成员是独一无二的,但可能会重复分数。
使用有序集,您可以以非常快的方式添加,删除或更新元素(在与元素数量的对数成比例的时间内)。由于元素按顺序排列而不是之后排序,因此您还可以通过分数或排名(位置)以非常快的方式获取范围。访问排序集的中间也非常快,因此您可以使用排序集作为非重复元素的智能列表,您可以快速访问所需的所有内容:按顺序排列元素,快速存在测试,快速访问中间元素!
解决方案:
EventID
是关键,#points
是ZSET的得分。添加活动:
ZADD bonuses:1 10 122
ZADD penalization:1 10 22
...
聚集他们(伪代码):
function getBalance(userId) {
bonusKey = "bonuses:" + userId;
penalizationKey = "penalization:" + userIdl
bonuses = redis.call("ZRANGE", bonusKey, 0 -1, "WITHSCORES")
penalization = redis.call("ZRANGE", penalizationKey, 0 -1, "WITHSCORES")
//`bonuses` and `penalization` are array of eventId->points,
// so use index 1 to aceess just points
return bonuses.reduse(acc, element => acc + element[1]) +
penalization.reduse(acc, element => acc + element[1]);
}
仅当您在每个列表中都有唯一的eventId时才使用此案例
Redis Hashes是字符串字段和字符串值之间的映射,因此它们是表示对象的完美数据类型(例如,具有多个字段的用户,如姓名,姓氏,年龄等)。具有少量字段的哈希以一种占用空间非常小的方式存储,因此您可以在一个小的Redis实例中存储数百万个对象。
解决方案:
EventID
是关键,#points
是HSET的值。添加活动:
HSET bonuses:1 122 10
HSET penalization:1 22 10
...
聚集他们(伪代码):
function getBalance(userId) {
bonusKey = "bonuses:" + userId;
penalizationKey = "penalization:" + userIdl
bonuses = redis.call("HGETALL", bonusKey)
penalization = redis.call("HGETALL", penalizationKey)
//`bonuses` and `penalization` are array of eventId->points,
// so use index 1 to aceess just points
return bonuses.reduse(acc, element => acc + element[1]) +
penalization.reduse(acc, element => acc + element[1]);
}
HSET案例使用RAM越来越好。如果每个列表中只有唯一的eventId - 请使用这种情况。