Lyscms+
登录注册
mysql使用uuid主键当排序字段数据重复时的上下页分页问题解决
原创mysql使用uuid主键当排序字段数据重复时的上下页分页问题解决

Java
image
亮月官方
2020-12-30 14:30:56
阅读数:207
mysqlmysql上一篇下一篇uuid下一篇

问题

​在对文章进行上一篇和下一篇查询的时候,当我们利用mysql作为存储,主键为uuid时,同时我们的查询一级排序字段查询出来的结果依然存在相同的情况时,那么我们的上一篇下一篇按照常规的处理方式可能存在问题。

解决

  1. 先按照页面展示好的列表进行排序,保持一致的排序规则
  2. 在排序好的结果集进行递增编号(行号),1,2,3,4,5,…
  3. 根据自增编号(行号)与记录的主键关系映射找到当前记录的编号(行号)
  4. 利用之前排序好的查询结果形成虚拟表进行再次按照编号(行号)判断小于(上一篇)或者大于(下一篇)查询,
  5. 查询得到的结果按照编号排序(降序(上一篇)或者升序(下一篇))且限制查询条数limit 1,即为你的上一篇或者下一篇
  6. UNION ALL连接两条查询sql,一条为上一篇,另外一条为下一篇返回结果
SELECT
	bef.* 
FROM
(
    SELECT
    	-- 1.根据自己需要定义字段(2处查询结果的子集)
        t.rownum_bef,
        t.id,
        "before" as type
    FROM
    ( 
        -- 2."t_bus_news"为你需要查询的表名(下同),保证该查询结果排序稳定,eg:order by create_time desc,id asc
        SELECT @rownum_bef := @rownum_bef + 1 AS rownum_bef, t_bus_news.* 
        FROM ( SELECT @rownum_bef := 0 ) r, t_bus_news order by create_time desc,id asc
    ) t 
    WHERE
    t.rownum_bef < (
        SELECT
        	w.rownum_bef_in 
        FROM
        ( 
            -- 3.注意此处的@rownum_bef_in需与上层2(rownum_bef)不同,
            --   保证该查询结果排序稳定,eg:order by create_time desc,id asc
            SELECT @rownum_bef_in := @rownum_bef_in + 1 AS rownum_bef_in, t_bus_news.id 
            FROM ( SELECT @rownum_bef_in := 0 ) r, t_bus_news order by create_time desc,id asc
        ) w 
        WHERE
        w.id = '2c948a837024572f017024586da20000' 
    ) 
    ORDER BY t.rownum_bef DESC LIMIT 1 
) bef 

UNION ALL

SELECT
	aft.* 
FROM
(
    SELECT
    -- 4. 同1一致(顺序也必须一致)
        t.rownum_aft,
        t.id,
    	"after" as type
    FROM
    ( 
        -- 5. 同2一致,rownum_aft与前面1,2,3都不能相同
        SELECT @rownum_aft := @rownum_aft + 1 AS rownum_aft, t_bus_news.* 
        FROM ( SELECT @rownum_aft := 0 ) r, t_bus_news order by create_time desc,id asc
    ) t 
    WHERE
    t.rownum_aft > (
        SELECT
        w.rownum_aft_in 
        FROM
        ( 
            -- 6. 同3一致,rownum_aft与前面1,2,3、4、5都不能相同
            SELECT @rownum_aft_in := @rownum_aft_in + 1 AS rownum_aft_in, t_bus_news.id 
            FROM ( SELECT @rownum_aft_in := 0 ) r, t_bus_news order by create_time desc,id asc
        ) w 
        WHERE
        w.id = '2c948a837024572f017024586da20000' 
	) 
	ORDER BY t.rownum_aft ASC LIMIT 1 
) aft

注意:

  1. id(2c948a837024572f017024586da20000)为当前的选中的主键id替换位你自己的id即可,一般传参进来
  2. t_bus_news为你需要查询上一篇和下一篇的表名,全局替换你自己的即可
    1. 查询结果字段可以根据自己的需要添加

Mybatis 返回HashMap

/**
 * 查询上一篇和下一篇,根据type作为map的key
 */
@MapKey(value = "type")
Map<String, Object> queryBeforeAndAfter(@Param("id") String id);

一个人在年轻的时候浪费自己的才华与天赋是一件非常可惜的事情,文章最后更新于:2020-12-30 14:30:56

没有更多了
123
loading