请教一个关于 Mysql 按顺序取数据记录的问题,主键非自增

2017-02-21 20:02:36 +08:00
 mokeyjay

部分数据如图所示:

由于一些历史原因,主键 id 非自增,唯一但不连续

现在要做的是文章内容页的 下一篇上一篇 按钮

以上图数据为例,想要达到的效果就是:

例如当前文章 ID 为137,那么上一篇则为136下一篇则为70。也就是按照表内现有的记录顺序来排

在不考虑性能开销(访问量很低,且可以做缓存)以及尽可能不修改数据表的前提下,如何取出这上 /下一篇的 ID ?

谢谢各位

5584 次点击
所在节点    MySQL
20 条回复
psychesworld
2017-02-21 20:07:00 +08:00
似乎是按时间排序的,你 order by date 就可以了
mokeyjay
2017-02-21 20:12:53 +08:00
@psychesworld #1 唔……貌似不一定是按照时间来的
hd7771
2017-02-21 20:15:53 +08:00
你对这个表扫一遍是不是正常顺序?
batnss
2017-02-21 20:16:46 +08:00
id>xxx order by id asc limit 1
mokeyjay
2017-02-21 20:17:50 +08:00
@hd7771 #3 什么意思呢?
hd7771
2017-02-21 20:18:26 +08:00
@mokeyjay 就是你截图里的顺序是怎么得到的
mokeyjay
2017-02-21 20:18:50 +08:00
@batnss #4 不好意思忘记说了, ID 并不连续,**且并不按照顺序**,目前如图所示的顺序才是正确的。希望能够按照如图顺序取出上 /下一篇的 id
mokeyjay
2017-02-21 20:19:29 +08:00
@hd7771 #6 就是 select * from xxx limit x 得到的,没有特意去排序
hd7771
2017-02-21 20:23:43 +08:00
那就 key-value 一下。
从上往下扫描
key = 0;
map1[key] = col.id;
map2[cao.id] = key;
key ++;
key 就是正确的顺序,
map1[key - 1]就是前一行的 id , map1[key + 1]就是后一行的 id 。
shiny
2017-02-21 20:25:14 +08:00
应该贴 SQL 。看上去像是先按 date 排序,如果 date 相同则按 id ASC

ORDER BY date DESC, id ASC LIMIT 1
hd7771
2017-02-21 20:25:36 +08:00
@mokeyjay 你可以把 key-value 存到一个新的表里,你这个表更新,新建的表一起更新就行了。
mokeyjay
2017-02-21 20:34:27 +08:00
@hd7771 #9
@shiny #10
感谢你们
不过我也不能确定是不是都是按照时间降序&id 升序来排的
所以最终我决定新建张表存 自增 ID-文章 ID 键值对,这样就能方便的排序了
(毕竟是二手老项目,还是不要瞎改表结构和数据了)

再次感谢你们!
flniu
2017-02-21 21:11:40 +08:00
楼主已经有方案了。
额外补充一句:表不是数组,如果不指定 ORDER BY ,查询结果的顺序是不确定的。所以要么按时间排序,要么增加序号。
另外自增 ID 可能不连续,所以只能作为序号,但直接用 CurrentID + 1 取下一条可能有问题。
danielmiao
2017-02-21 22:11:33 +08:00
方案是有的,就是极其损耗性能:
使用存储过程游标查询,从头遍历表,直到查到纪录为止。

最好是只遍历一次,依据数据,建立索引表,链式纪录,指向前一条纪录和后一条纪录 id ,索引表如果数据量不大可以完全缓存在内存里,这样直接命中主键,效率会很高
akira
2017-02-21 22:26:08 +08:00
@danielmiao 再加个定时刷新一次记录就好。这种数据量在千万级别以内,都是可以随便开内存处理的
ETiV
2017-02-21 23:04:36 +08:00
如果 poster 自古以来就是这种命名规范,按它来排序就行了……

另外根据常理, weight 、权重,也可以是排序依据
ryd994
2017-02-22 02:20:46 +08:00
看这个 ID 也不是太稀疏的样子,直接加一看看没有再加一可能反而更快
测试一下看看
msg7086
2017-02-22 05:24:54 +08:00
不指定排序条件的,数据库可以自行选择返回数据的顺序。
MySQL 应该是按照记录的物理存储地址来返回的。
这就意味着这张数据表如果被导出再导入,可能就不是原来的顺序了。
will0404
2017-02-22 07:49:05 +08:00
不是应该先整理下数据再考虑排序的事吗
paranoiagu
2017-02-22 07:54:16 +08:00
没有排序字段(规则),怎么确保排序呢?

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/342160

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX