如何在数据库中存储Would You Rather应用的选项选择次数?
嘿,你的这个初始思路其实是完全可行的,但确实在用户量上来之后,频繁的数据库写请求会带来性能瓶颈。我给你几个实用的优化方向,帮你搞定高并发场景下的处理难题:
优化方案1:调整数据库结构,减少写操作次数
没必要把两个选项拆成独立的行,你可以把一组「Would You Rather」的两个选项放在同一行里,比如设计这样的表结构:
CREATE TABLE polls ( id INT PRIMARY KEY AUTO_INCREMENT, option_one VARCHAR(255) NOT NULL, option_two VARCHAR(255) NOT NULL, count_one INT DEFAULT 0, count_two INT DEFAULT 0 );
当用户选择第一个选项时,只需要执行一条更新语句:
UPDATE polls SET count_one = count_one + 1 WHERE id = [poll_id];
这样每个投票的更新操作都只需要一次数据库交互,比拆成两行的方式减少了一半的行操作,性能会提升不少。
优化方案2:引入缓存层,扛住高并发
如果用户量真的很大,直接操作数据库还是会有压力,这时候可以用Redis这类内存缓存做中间层:
- 用户选择选项时,先调用Redis的
INCR命令递增对应选项的缓存计数(比如用poll:[poll_id]:option1作为键) - 后台开一个定时任务(比如每分钟一次),把缓存里的计数批量同步到数据库中
- 展示投票结果时,优先从缓存读取,缓存没有的话再查数据库,保证数据实时性
这种方式下,用户的请求几乎都落在Redis上,数据库只需要处理批量同步操作,压力会小很多。
优化方案3:异步处理写请求
如果不想依赖缓存,也可以用消息队列(比如RabbitMQ、Kafka)来异步处理计数更新:
- 用户提交选择后,服务器直接把投票消息发送到队列,然后立即返回成功给用户
- 后台的消费者进程从队列里取出消息,再去更新数据库的计数
这样用户请求的响应速度会非常快,还能把数据库的写操作削峰填谷,避免高并发时的数据库拥堵。
额外提醒:防重复投票
别忘了处理用户重复投票的问题,你可以用Redis的Set来记录每个用户已经参与过的投票ID:
- 用户投票前,先检查
user:[user_id]:voted_polls这个Set里是否包含当前投票ID - 如果已经存在,直接返回「已投票」;如果不存在,再执行后续的计数更新操作,同时把投票ID加入Set
这样既能防止重复投票,又能快速判断,不用每次都查数据库。
内容的提问来源于stack exchange,提问作者user2397282
相关产品推荐
相关产品推荐

