开发者社区> 问答> 正文

关于 MYSQL 排名算法的问题

我需要给数据库里的所有成员(大约10万个)按照某个字段(point)做排名,这个排名既要显示在列表页,也要显示在会员详情页。
于是我给每个会员做了一个排名缓存字段 rank
我在前台有一个根据point倒序排列的页面(foreach $rs as $key=>$value),我的做法是在这个页面中判断缓存「rank字段」和「($key+1)+(当前页数-1)*每页显示数量」是否相等,如果不等就更新rank字段。
这个方案解决了列表页面的排名同步到详情页的问题。但是新问题来了。用户的point是变化的
我需要给point发生变化的个体更新他的排名(总不能到列表页去更新吧,尤其是用户排名比较靠后的),于是当用户的point发生变化的时候我又写了一个
SELECT count(1) FROM user WHERE point>='用户当前最新的point值';
并把这个 count(1) 写入到了该用户的rank字段,长久运行之后,总是发现 这个count(1) 和列表计算出的排名有差距,于是成员的排名总是发生浮动。。。体验很不好
而我如果去掉列表页的更新方案,单独采用 SELECT count(1) 的话,又总是出现排名重复的情况(前几名都会有重复)
请问大侠们有没有什么好的解决方案!?

展开
收起
蛮大人123 2016-02-08 18:24:01 2679 0
1 条回答
写回答
取消 提交回答
  • 公益是一辈子的事, I am digoal, just do it. 阿里云数据库团队, 擅长PolarDB, PostgreSQL, DuckDB, ADB等, 长期致力于推动开源数据库技术、生态在中国的发展与开源产业人才培养. 曾荣获阿里巴巴麒麟布道师称号、2018届OSCAR开源尖峰人物.

    这个需求用窗口查询很方便,在PostgreSQL里可以这样查询:

    digoal=# create table test(id int, info text,point int);
    CREATE TABLE
    digoal=# insert into test values (1, 'a', 100);
    INSERT 0 1
    digoal=# insert into test values (2, 'a', 101);
    INSERT 0 1
    digoal=# insert into test values (3, 'b', 90);
    INSERT 0 1
    digoal=# insert into test values (4, 'c', 10);
    INSERT 0 1
    digoal=# select row_number() over(order by point desc) rn,* from test order by rn;
     rn | id | info | point 
    ----+----+------+-------
      1 |  2 | a    |   101
      2 |  1 | a    |   100
      3 |  3 | b    |    90
      4 |  4 | c    |    10
    (4 rows)
    2019-07-17 18:39:53
    赞同 展开评论 打赏
问答排行榜
最热
最新

相关电子书

更多
MySQL 5.7优化不求人 立即下载
PostgresChina2018_张启程_为什么我们抛弃MongoDB和MySQL,选择PgSQL 立即下载
MySQL5.7 让优化更轻松 立即下载