背景:
数据库:MySQL
语言:PHP
(因为架构复杂度的问题,暂时不考虑引入其他的基础设施依赖,所以只能用MySQL作为数据库,而且PHP没有队列支持。一切都从最简单出发。)
(好在我真的非常聪明的让框架透明的支持了按照表名称进行分库查询,所以这些表可以放在其他数据库服务器上不会而影响其他服务器的性能。当然,虽然这也导致了不能支持任何事务……)
===============================
正文:
正在给自己的网站写提醒服务,通过一个Ajax的Post请求不停的给Web发送带有参数的查询来获得数据并检查是否有给当前用户的提醒。然后按照这样显示出来:
功能上类似于V2EX的“N 条未读提醒”,但是需要查询两张表,一张提醒,一张消息。
查询是由Ajax发出并控制频率的,正常用户不会干预(非正常用户可以直接攻击接口,但是能根据会话频率限制来阻止)。不能是Websocket,也不能进行频繁的查询操作(MySQL大家都懂的)。所以大约60秒查询一次这样。
===============================
设想的方案:
现在已经有两个设想的方案,想知道那个好一些,请大家帮忙评价下,或者给个其他方案:
1、代码上最简单的方案:
当收到Ajax调用时,分别查询两张表,列出至多N条记录,然后将N返回,呈现给客户端。且不做缓存处理。
查询语句类似于
SELECT * FROM messages WHERE userID = 1 AND readed = 0 LIMIT 10;
SELECT * FROM notifications WHERE userID = 1 AND readed = 0 LIMIT 10;
优点:
A:复杂度低,容易实现;
B:可扩展性好。未来如果需要,可以不用仅显示“收到了 1 条新消息”,而是列出这最多10条消息/通知。
缺点:
A:列出这些数据相对耗时,尤其是直接读取了操作表,可能会导致性能下降。
2、复杂度高一点的方案:
建立一张数据表(如pushs),分别记录未读消息的数量,然后每次有新消息/通知写入和被阅读时,增减记录的数据值。这些数据直接从数据库取得,不做缓存。
数据表类似于
pushID(主健), countMessages, countNotifications, userID(唯一索引), time;
查询语句类似于
SELECT countMessages, countNotifications WHERE userID = 1;
优点:
A:唯一索引查询速度更快,而且它是唯一的查询条件;
B:单独的数据表可以作为内存表,获得更快的查询速度,只需要在用户登录时重新统计数据即可(这意味着方案1里那两条查询会在用户登录时执行一次)。
缺点:
A:复杂度高。需要变更一系列已有代码(好在我可以用预留的钩子实现),同时还需要维护表中的这些数据以确保其准确。
B:扩展性差,基本上就只能那样了,如果未来需要显示其他数据,则需要变更大量代码。
// 啥时候支持Markdown?
这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。
https://www.v2ex.com/t/119720
V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。
V2EX is a community of developers, designers and creative people.