需求
对用户的查询关键词进行次数统计。并在用户搜索的时候,给出热词提示。
解决方案1:维护一张汇总表
其中包括关键词及其查询次数。当访问的用户很多时,数据库修改时会加一个排他锁,导致效率很低。
解决方案2:维护一张明细表
我们搜索一次,就在表中插入一条查询记录。之后进行分组统计。插入要比更新的速度快,不需要加锁解锁。缺点是表的数量会越来越大,分组统计会越来越耗时。
解决方案3:前面的两张表结合起来。
这时我们开启一个定时任务,如每隔一个小时对明细表中的内容进行统计,将结果插入到汇总表中。
明细表主键使用GUID类型,这个比自增类型的主键插入性能高,因为自增类型的主键在插入时要先找到表中主键Id最大值,之后加锁,更新,之后在解锁。而逐渐使用GUID类型则无需上述过程(由于明细表的主键不需要连续,而且用自动增长字段会排队、加锁从而降低效率,因此主键用Guid)。
每查询一次,就向明细表中插入一条记录。同时后台在运行一个定时框架,到达设定的时间就进行一次统计,并将统计的结果放入汇总表中。
在浏览器端使用JQuery UI中的autocompletewidget(组件),向后台输出一个名为term的字符串。在服务器端从汇总表中进行查询,并输出json格式给前台组件。而且考虑要把提示的热词放到缓存中,定时框架来进行更新。
解决方案4:使用NoSql中的MongoDB。
频繁的向一张表中插入数据,特别是高并发的应用场景下效率本身就很慢。为了解决高并发、大量数据的插入、更新问题,引入非关系型数据库NoSql。
使用MongoDB的思路是这样的,由于MongoDB的非关系属性,向其集合中可以插入海量数据,无需考虑并发的读写慢问题。MongoDB也可以进行类似sql的关系查询,那么直接从集合中查询出group by sum(keyword) top 10就可以了。
总结
解决方法3和4可以合并,明细表的功能由MongoDB实现,定时框架统计结果并同步到MySQL中。前端的查询可以选择从MongoDB也可以选择从MySQL。