很多网站都有一个随便看看功能,常见的实现方式是通过数据库的rand()函数来随机排序实现获取随机的数据,但是效率不高,并且每次获取的数据没有关联,会出现重复的数据。
如果业务上需要随机读取表中的数据,但是每次读取的数据不能重复怎么实现呢
我在网上找了一圈,没有找到可行方案,最后自己想到了一个方法
如果数据的主键id是UUID最好实现,或者数据中有稍微长一点点的字符串字段
因为我的数据id的主键是UUID,查询数据之前,通过random类计算出两个随机数,每次查询数据库都带上这两个随机的数字,通过数据库的sub函数截取id的随机范围,通过这个id的子串排序实现随机数据的读取,并且每次读取都不会得到重复的数据。
说的可能有点抽象,我举个例子
比如我的数据库中的数据有三条数据,它们的id分别是
id
003c34f3648c4c8aaf8a8049fcc8d706
2bc9193f577b4b52a34bd85bf4307c11
55d4e5da10ad454e9f3ecf87d8f86b69
id字符串总长是32,通过random类计算截取id的哪部分,比如得到的开始位置是3,长度5,那么查询的语句就是 select * from xxx ORDER BY SUBSTR(id,${position},${len}) limit 0,10
003c34f3648c4c8aaf8a8049fcc8d706
2bc9193f577b4b52a34bd85bf4307c11
55d4e5da10ad454e9f3ecf87d8f86b69
排序之后得的结果就是 2 1 3
下次再读取可以重新计算截取的部分,就会得到其他的顺序,例如
003c34f3648c4c8aaf8a8049fcc8d706
2bc9193f577b4b52a34bd85bf4307c11
55d4e5da10ad454e9f3ecf87d8f86b69
如果没有这种长的字符串,数字也行,如果每个字段的值都很短,也可以通过concat函数将多个列的值拼到一起再截取排序。
end