1
yefuchao 246 天前
余额就是一个数字,过期时间到了给你扣掉不就好了
|
2
NoOneNoBody 246 天前 1
硬件足够的话,数据越细越好
不需要每次计算,缓存,或者保存预计算结果就可以了 |
4
Donjote 246 天前
更新 30 条记录也没啥吧,余额可以存另外一个表里
|
5
Subfire 246 天前 1
跟游戏开发中的道具类似, 每次获得的书币道具, 只是 configId 一样, 但是 instanceId 是新增的, 不同 instanceId 的道具都有独立的有效期. 扣减书币道具的时候, 优先扣减即将到期的
|
6
xxxaadsdss 246 天前
每次领取都是一条领取记录。领取的商品有过期时间。到时间了。减一下总表的 书币数就好了
|
7
zero47 OP 想了想还有一个情况是,30 块的交易,用户有 29 个 1 块书币奖励和 1 个 2 块书币奖励,还得在最后一个 2 块奖励里记录消费了 1 块,还有 1 块没被消费,这太不优雅了吧
|
8
zero47 OP @xxxaadsdss 这只能解决 sum 的问题,实际消费还得一条一条的更新奖励记录
|
9
NessajCN 246 天前 4
参考比特币的区块嘛
做一个表,只记录交易信息,譬如 xxxx(时间戳) 入账 1 币,一个月后该条交易记录失效 消费的时候就是手动将依然在有效期内的前 3 条 1 币交易记录失效,如果是入账 3 币只消费 2 币的记录就失效掉 3 币的记录重新生成一条基于原时间戳的 1 币记录 余额计算就是简单的所有有效入账记录求和 |
12
Rickkkkkkk 246 天前
每条领取记录都是库里一条记录
定期跑离线任务去库里把数据都过期掉 算余额会把库里的值全部加起来 这里会出现几个问题: 跑全量任务更新过期会不会太重了? (记录很多, 真正要过期的很少) 每次算余额要把所有的记录加起来会不会慢查询? (留为作业吧) |
13
Fish1024 246 天前
领取的时候就写入了这些币的过期时间,到时间自动过期了。
|
14
tomatocici2333 246 天前
@Fish1024 我感觉也是 写个定时任务扫描过期
|
15
caotian 246 天前 5
之前做一个简单的系统想积分带过期功能,硬着头皮做了类似的方案,基本也实现了需求,结果最后做到退款功能时,还是给整破防了,因为还要考虑退款时退积分,退的积分要根据退款金额计算,退的积分还要保持原来的过期时间,还要考虑退款时,退回的积分有可能已经过期了,过期的积分是直接过期,还是根据规则折算成新积分,感觉本来一个简单的功能越做越复杂,最后索性不做积分过期功能了
|
16
deltadawn 246 天前 2
按每月存 1 条记录,初始值为 32 个 0 ,签到的时候把当前天数那一位改成获得的金币数,过期只要把上个月当前天那一位改成 0 ,扣钱的时候,从上个月当天开始循环减。这样数据库操作就少了
|
17
jookr 246 天前
先进先出呗。
先获取的,先到期/先使用 |
18
ashuai 246 天前
balance 另有个 detail 表,独立过期时间就行了,不是啥麻烦事
|
19
nqlair 246 天前
存成 sortedMap ,key 是过期时间,value 是积分,每次登录把过期的删除,积分就是未过期的所有 value 的和,使用时候优先扣过期时间近的
|
20
tinytoadd 246 天前
使用书币是先用快过期的还是先用新领取的。
|
22
qeqv 246 天前
感觉最简单的方法就是你正文提到的了,别的逻辑都很复杂。
1. 购买时更新 30 条记录也没什么 2. 总额可以做缓存,余额变动时更新 3. 1 个 2 块书币奖励可以设置成两条 1 书币记录 |
23
futuretech6 246 天前
感觉是类似 NFT 的实现,每个 token 有自己的 id 和过期时间,然后整体也会维护一个 token 数量信息
|
24
runzekk 246 天前
sum 也没什么问题,冗余存也没什么问题,量不大,没有大事物都不是问题
|
25
444571840 246 天前
如果要实现的话要挺容易的,数据库一个字段就能解决。
记录的时候 [获得书币 A ,到期时间戳 1 。获得书币 B ,到期时间戳 2 。xxx],每次要写入新数据的时候,先判断是否有已经到期的书币,删除了,再在字段后面添加(新活动书币,新到期时间戳)即可。 客户端每次要展示的时候,根据当前时间戳把数据库未到期的 sum 一遍就好了。 其他查历史的话看 log 就好。 |
26
mrgeneral 246 天前
总和可以是单独的数据,过期是定时任务就能解决,流水信息可以定期归档,实际数据量不大。
|
27
janus77 246 天前
领取时一条一条更新
使用时只需要更新一下总数字就行了,只有一次啊 |
28
hanbin 246 天前 2
两个表:
CREATE TABLE PointsRecord ( id INT AUTO_INCREMENT PRIMARY KEY COMMENT '自增 ID', user_id INT NOT NULL COMMENT '用户 ID', points_amount INT NOT NULL COMMENT '积分数量', receive_time TIMESTAMP NOT NULL COMMENT '领取时间', expiration_time TIMESTAMP NOT NULL COMMENT '过期时间', status VARCHAR(20) NOT NULL COMMENT '状态', receive_source VARCHAR(50) NOT NULL COMMENT '领取来源', created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT '记录时间', updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间' ) COMMENT '积分领取记录表'; CREATE TABLE PointsWallet ( id INT AUTO_INCREMENT PRIMARY KEY COMMENT '积分钱包 ID', user_id INT NOT NULL COMMENT '用户 ID', points_balance INT NOT NULL DEFAULT 0 COMMENT '积分余额', total_points INT NOT NULL DEFAULT 0 COMMENT '积分总额', used_points INT NOT NULL DEFAULT 0 COMMENT '已用积分总额', expired_points INT NOT NULL DEFAULT 0 COMMENT '已过期积分总额', created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间' ) COMMENT '积分钱包表'; 领取积分: PointsRecord 入库一条记录,PointsWallet 更新 total_points & points_balance ,事务处理 过期积分: PointsRecord 更新一条数据,PointsWallet 更新 total_points & points_balance & expired_points ,事务处理 积分消费: PointsWallet 更新 used_points & points_balance 过期积分用脚本处理 积分消费时判断余额够就允许消费。 |
31
pkoukk 246 天前
两个表,一个当前的 sum ,一个 detail
通过事件系统,detial 表的变动通知到 sum ,sum 改余额就完事了 而且一天才一两条,不用事件系统,搞定时任务扫都绰绰有余 |
32
NizumaEiji 246 天前
流水过期
|
33
handpr 246 天前
类似物流的.出入库. 入库明细-》 spu,sku,批次,效期次,入库数量
|
34
ZnductR0MjHvjRQ3 246 天前
@zero47 有没有一种可能 实际上都是 1
|
35
ZnductR0MjHvjRQ3 246 天前
@deltadawn 有道理
|
36
kaedea 246 天前 via Android
你在查找的是不是:数据库
|
37
somebody1 246 天前
@deltadawn
补充思路,可以是 32 个 0-9 ,a-z ,这样每天获取到的就可以非常多了,只需要计算一个 32 的字符串,就可以算出来了。 但是缺点有很明显,微信读书可以做到分钟级别的失效,这个就做不到了。 |
38
yanliu 246 天前
以我浅见,这种余额类的大都是事件溯源的,即你看到的余额不是简单的存储了一个数字,而是由交易记录实时计算出来的,然后定期合并一个快照,减少计算量,那么就可以在交易记录上打标记来实现过期。这是最常用,也是最安全的做法。当然,也有简单的方案,比如将这类会过期的书币存入 redis 的 zset 中,然后将过期时间戳作为 score ,就可以使用 ZRANGEBYSCORE 之类的命令来返回当前时间和过期时间之间的数据,求和就行了。
|
39
yanliu 246 天前
@yanliu 一切都要看业务。如果你有 15L 说的那样情况,或者其它情况,那么事件溯源,就是这一类问题目前的唯一解,同时兼顾了安全性和灵活性,并且快照设置合适的话,并发性也不差。
|
40
cellar 246 天前
又不是严格的金融系统。。要么弄个 job ,过期的全删了,要么 where 条件永远带个时间条件就是了。。
资源有的是的话弄个 redis... |
41
whileFalse 246 天前 via Android
余额会单独存储,每次买书同时更新余额和 30 条消费记录
DB 性能很强的,现在的硬件太牛逼了 |
43
sherryqueen 245 天前
每天记录多加一个余额和状态字段. 消费前拉出所有可用余额, 找出要扣除的记录更新对应状态和余额就好了吧?
|
44
sherryqueen 245 天前
至于总余额 临时算或找个地方 cache 下. 每条记录的过期的话, 定时任务或找个用户查询/消费的时候进行一次统一计算就行.但用户也就是一次批量查询 + 一次批量更新. 计算量也不大
|
45
flyingghost 243 天前
大体量用户❎
蝇量级计算✅ 数字产品没有库存问题,所以各用户间购买行为无关,自己消费自己的就行。 购买行为不涉及用户间的借款、代付,所以自己算自己的账就行。 每个用户独立计算自己的币和消费过程,总共百条书币记录,0.1TPS 的操作,单用户放文件存储都不怕效率低。 过期状态更新只存在于查看时、消费时,依然百条书币记录,0.1TPS 的操作。 先不考虑其他功能需求,单说你的问题来看,这简直和大体量没关系啊。。。 唯一和大体量有关的是,如何在亿级用户中找到这个用户独立的账户存储空间。 |
46
lazyfighter 243 天前
可以算一下, 我们默认存储金币记录 1 年, 假设所有用户每天全部签到 365 ,假设共 2 亿用户,那么 2 年的金币记录就是:2*2*365 亿,假设分 128 个表,每个表就是 6 亿左右,所以目前来看存储不是大问题, 那么问题来了就是过期怎么搞,单纯的定时任务去扫这几百亿的数据很扯,所以分开看线上用户实时查看: 实时算每个用户请求自己实时算生效的金币。运营数据统计: 离线任务
|