我们都知道,各种主流的社交应用或者阅读应用,基本都有列表类视图,并且都有滑到底部加载更多这一功能, 对应后端就是分页拉取数据。
好处不言而喻,一般来说,这些数据项都是按时间倒序排列的,用户只关心最新的动态,而不关心几个月甚至几年前消息,所以后端返回给客户端的数据是不会一次性传递全部内容的(不仅耗费流量,而且还给服务器带来巨大压力)。

举个例就说MySQL,它已经给我们提供了相应的语句来支持这一功能,那就是limit关键字。
比如我要拉取一个消息表中用户id为1的前10条最新数据,SQL语句如下:

select uid, content, time
from message
where uid = 1
order by time desc
limit 0, 10
1
2
3
4
5
其中,message是表名,查询3个字段uid,content(消息详情内容),time(消息发送时间),用order by time desc对数据进行时间倒序排序,一般time的数据类型可以用datetime(格式:yyyy-MM-dd HH:mm:ss)。
然后limit 0, 10表示将查询结果限制在从下标为0开始的10行数据。
比如你只查询第8行这一行数据,就是limit 7, 1,形式化描述就是:
limit [index], [count]

顺理成章地,我们会自然想到,当用户加载更多时,我们就将上述SQL语句改为:

select uid, content, time
from message
where uid = 1
order by time desc
limit 10, 10
1
2
3
4
5
09行数据我们已经查询过了,接下来就是查询1019行数据,以此类推。

所以,实际的服务端Web程序中,我们可以在编程时把index这个值作为变量,每次加载更多时,就改变index为列表数据项的大小,描述为:
index = listSize
每加载一次新数据,listSize就会增大,下一次查询从index = listSize这个位置开始即可。

MySQL分页就搞定了,但是在实际应用中,我们不得不面临一个数据重复的问题。
举个例子,我第一页有10条数据,在加载第二页新10条数据时,正好总表里增加了n条新数据,这样第二页的前n条数据就会与第一页的后n条数据重复。
如果正确理解这个意思,那么大家就明白当这个n=10时,第二页数据就会和已经加载的第一页数据完全一样。
然而第一页数据已经在客户端UI填充完毕了,我们不可能回头重查,这不仅影响程序效率,而且用户体验也很不好。

为了避免这个问题,我们利用时间来控制查询结果。第1页到第n页的分页数据,其实都是在某个时间点之前的内容,这个时间点之后新插入的数据我们不管。
所以,SQL语句改为:

select uid, content, time
from message
where uid = 1 and time < time_point
order by time desc
limit listSize, 10
1
2
3
4
5
这个time_point在拉取第一页数据之前就要确定下来,并且和listSize一样,都是服务端程序代码中的变量,此处只是个形式化描述。
当前时间可以通过相应的代码来获取系统时间(比如Java中的Calendar或者Date类),也可以直接通过SQL语句的now函数获取系统时间:

select NOW()
1
查询结果为(这是我此时写文的时间):
‘2017-01-19 16:07:46’
所以,time_point实际上也就是形如上的一个时间字符串而已,在MySQL中,时间字符串是可以直接比较大小的。

如果你不喜欢字符串比较或者有其它特殊需求,那么你可以将MySQL中的datetime数据类型转换为整数,这样写:

……
where uid = 1 and (time + 0) < time_point_integer
……
1
2
3
datetime通过加0处理后,会转化为形如20170119160746这样的长整型,所以时间点变量也不能是字符串了,而是经过处理后的整数(在Java中对应long数据类型)。
刚才的时间查询语句即改为:

select NOW() + 0
1
转换成整数有什么好处呢?
比如说,有需求不是定量的分页拉取,而是按时间段拉取,若我需要过去2小时内的数据,就可以通过整数之间的运算来实现,这里不作赘述。

最后的处理:
time_point和listSize这两个变量肯定是需要重置的。
那就是在用户回到列表顶部重新刷新整个列表时,时间点就需要刷新,listSize置为零。
在实际应用中,当用户还在慢慢向下浏览过去的数据时,其实已经有大量新数据已经插入数据库了,正如上文提到的,这时肯定不能立即加载,所以人性化的处理就是,在适当的地方给予用户提示,比如“有n条新动态,点击查看”,用户点击后,就会回到顶部,刷新相应的变量,重新加载整个列表。
---------------------
作者:针叶
来源:CSDN
原文:https://blog.csdn.net/ysy950803/article/details/54617223
版权声明:本文为博主原创文章,转载请附上博文链接!

我们都知道,各种主流的社交应用或者阅读应用,基本都有列表类视图,并且都有滑到底部加载更多这一功能, 对应后端就是分页拉取数据。
好处不言而喻,一般来说,这些数据项都是按时间倒序排列的,用户只关心最新的动态,而不关心几个月甚至几年前消息,所以后端返回给客户端的数据是不会一次性传递全部内容的(不仅耗费流量,而且还给服务器带来巨大压力)。

举个例就说MySQL,它已经给我们提供了相应的语句来支持这一功能,那就是limit关键字。
比如我要拉取一个消息表中用户id为1的前10条最新数据,SQL语句如下:

select uid, content, time
from message
where uid = 1
order by time desc
limit 0, 10
1
2
3
4
5
其中,message是表名,查询3个字段uid,content(消息详情内容),time(消息发送时间),用order by time desc对数据进行时间倒序排序,一般time的数据类型可以用datetime(格式:yyyy-MM-dd HH:mm:ss)。
然后limit 0, 10表示将查询结果限制在从下标为0开始的10行数据。
比如你只查询第8行这一行数据,就是limit 7, 1,形式化描述就是:
limit [index], [count]

顺理成章地,我们会自然想到,当用户加载更多时,我们就将上述SQL语句改为:

select uid, content, time
from message
where uid = 1
order by time desc
limit 10, 10
1
2
3
4
5
09行数据我们已经查询过了,接下来就是查询1019行数据,以此类推。

所以,实际的服务端Web程序中,我们可以在编程时把index这个值作为变量,每次加载更多时,就改变index为列表数据项的大小,描述为:
index = listSize
每加载一次新数据,listSize就会增大,下一次查询从index = listSize这个位置开始即可。

MySQL分页就搞定了,但是在实际应用中,我们不得不面临一个数据重复的问题。
举个例子,我第一页有10条数据,在加载第二页新10条数据时,正好总表里增加了n条新数据,这样第二页的前n条数据就会与第一页的后n条数据重复。
如果正确理解这个意思,那么大家就明白当这个n=10时,第二页数据就会和已经加载的第一页数据完全一样。
然而第一页数据已经在客户端UI填充完毕了,我们不可能回头重查,这不仅影响程序效率,而且用户体验也很不好。

为了避免这个问题,我们利用时间来控制查询结果。第1页到第n页的分页数据,其实都是在某个时间点之前的内容,这个时间点之后新插入的数据我们不管。
所以,SQL语句改为:

select uid, content, time
from message
where uid = 1 and time < time_point
order by time desc
limit listSize, 10
1
2
3
4
5
这个time_point在拉取第一页数据之前就要确定下来,并且和listSize一样,都是服务端程序代码中的变量,此处只是个形式化描述。
当前时间可以通过相应的代码来获取系统时间(比如Java中的Calendar或者Date类),也可以直接通过SQL语句的now函数获取系统时间:

select NOW()
1
查询结果为(这是我此时写文的时间):
‘2017-01-19 16:07:46’
所以,time_point实际上也就是形如上的一个时间字符串而已,在MySQL中,时间字符串是可以直接比较大小的。

如果你不喜欢字符串比较或者有其它特殊需求,那么你可以将MySQL中的datetime数据类型转换为整数,这样写:

……
where uid = 1 and (time + 0) < time_point_integer
……
1
2
3
datetime通过加0处理后,会转化为形如20170119160746这样的长整型,所以时间点变量也不能是字符串了,而是经过处理后的整数(在Java中对应long数据类型)。
刚才的时间查询语句即改为:

select NOW() + 0
1
转换成整数有什么好处呢?
比如说,有需求不是定量的分页拉取,而是按时间段拉取,若我需要过去2小时内的数据,就可以通过整数之间的运算来实现,这里不作赘述。

最后的处理:
time_point和listSize这两个变量肯定是需要重置的。
那就是在用户回到列表顶部重新刷新整个列表时,时间点就需要刷新,listSize置为零。
在实际应用中,当用户还在慢慢向下浏览过去的数据时,其实已经有大量新数据已经插入数据库了,正如上文提到的,这时肯定不能立即加载,所以人性化的处理就是,在适当的地方给予用户提示,比如“有n条新动态,点击查看”,用户点击后,就会回到顶部,刷新相应的变量,重新加载整个列表。
---------------------
作者:针叶
来源:CSDN
原文:https://blog.csdn.net/ysy950803/article/details/54617223
版权声明:本文为博主原创文章,转载请附上博文链接!

解决 MySQL 比如我要拉取一个消息表中用户id为1的前10条最新数据的更多相关文章

  1. Git如何强制拉取一个远程分支到本地分支(转载)

    有时候,我们在使用git pull指令想把一个远程分支拉取到本地分支的时候,老是会拉取失败,这一般是因为某种原因,本地分支和远程分支的内容差异无法被git成功识别出来,所以git pull指令什么都不 ...

  2. 配置kuernetes集群pod拉取私有镜像仓库中的镜像

    目录 1 背景说明 2 实现方法 3 具体实现 配置镜像仓库项目为公开类型(任何人可以访问) 配置docker-registry类型的secret(pod使用secret获取镜像认证) 通过账户名密码 ...

  3. Jenkins拉取Git远程仓库中指定目录至本地指定目录

    Jenkins拉取源码是非常实用的操作,比如每天在跑自动化测试前,拉取Git远程仓库中最新的脚本至本地.那么,Jenkins如何拉取Git远程仓库中指定目录至本地指定目录呢?下面来看看具体的设置方法. ...

  4. oracle 取前10条记录

    1.oracle 取前10条记录 1) select * from tbname where rownum < 11; 2) select * from (select * from tbnam ...

  5. Oracle 取两个表中数据的交集并集差异集合

    Oracle 取两个表中数据的交集 关键字: Oracle 取两个表中数据的交集 INTERSECT Oracle 作为一个大型的关系数据库,日常应用中往往需要提取两个表的交集数据 例如现有如下表,要 ...

  6. c# applibrary实现一个Sheet表中存放多张DataTable数据

    1.工具类(applibrary.dll) public class ExcelHelper { /// <summary> /// 文件名 /// </summary> pu ...

  7. 一个表中的id有多个记录,把所有这个id的记录查出来,并显示共有多少条记录数

    一个表中的id有多个记录,把所有这个id的记录查出来,并显示共有多少条记录数 select id ,Count(*) from table_name group by id having count( ...

  8. oracle和sql server中,取前10条数据语法的区别

    在sql server中,取数据中前10条语句,我们可以用top 10 这样语句,但是oracle就没有这个函数,接下来介绍它们之间的区别 1.sql server 取前10语句和随机10条的语法 - ...

  9. Azure DevOps Server: 使用Rest Api获取拉取请求Pull Request中的变更文件清单

    需求: Azure DevOps Server 的拉取请求模块,为开发团队提供了强大而且灵活的代码评审功能.拉取请求中变更文件清单,对质量管理人员,是一个宝贵的材料.质量保障人员可以从代码清单中分析不 ...

随机推荐

  1. 1016B - Segment Occurrences(字符串的匹配)

    题意:字符串a,字符串b,给你q个区间,让你求a的区间内字符串b出现了多少次 之前用的前缀数组做的,没想起来,发现这个其实也可以 #include<cstdio> #include< ...

  2. linux下svn不能连接上windows服务器:SSL handshake failed: SSL error

    在linux服务器下载https链接的svn源码时出现:SSL handshake failed: SSL error: Key usage violation in certificate has ...

  3. ReactiveX 学习笔记(7)聚合操作符

    Mathematical and Aggregate Operators 本文的主题为处理 Observable 的聚合操作符. 这里的 Observable 实质上是可观察的数据流. RxJava操 ...

  4. Haskell语言学习笔记(19)File IO

    关于IO Action 类型为IO t. 运算时不执行,因而没有任何效果,只有执行时才会有效果,产生副作用. 一个IO Action只有在其他IO Action中才能被执行. 类型为IO t的IO A ...

  5. 【376】COMP 9021 相关笔记(二)

    Note_01 zip() itertools.zip_longest() %time Note_02 for 循环单行输出 list 技巧 迭代器 生成器 map() zip() from path ...

  6. rhel7磁盘管理

     一.MBR主引导记录        MBR有512个字节,分为三个部分:第一部分446个字节,存储了引导分区:第二部分64字节为分区表:第三部分2个字节结束符:每个分区需16个字节,所以MBR的模式 ...

  7. Spring容器中获取bean实例的方法

    // 得到上下文环境 WebApplicationContext webContext = ContextLoader .getCurrentWebApplicationContext(); // 使 ...

  8. 重装unbantu 问题集合,下载别人的代码运行问题集合

    安装angular 的时候要全局设置 npm install -g angular-cli nodemon server.js 出现[nodemon] Internal watch failed:xx ...

  9. 基于ajax请求异常捕获

    第一步:controller中 @RequestMapping("/ajaxerror") public String ajaxerror() { return "thy ...

  10. Ajax 学习 第三篇

    1.什么是json 第一种方法 第二种方法 比较evar and jsondata 任何时候使用EVAR要特别小心,他不会管输入对象的类型 JSONLint可以在线校验代码的正确性 改写代码