解决 MySQL 比如我要拉取一个消息表中用户id为1的前10条最新数据
我们都知道,各种主流的社交应用或者阅读应用,基本都有列表类视图,并且都有滑到底部加载更多这一功能, 对应后端就是分页拉取数据。
好处不言而喻,一般来说,这些数据项都是按时间倒序排列的,用户只关心最新的动态,而不关心几个月甚至几年前消息,所以后端返回给客户端的数据是不会一次性传递全部内容的(不仅耗费流量,而且还给服务器带来巨大压力)。
举个例就说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条最新数据的更多相关文章
- Git如何强制拉取一个远程分支到本地分支(转载)
有时候,我们在使用git pull指令想把一个远程分支拉取到本地分支的时候,老是会拉取失败,这一般是因为某种原因,本地分支和远程分支的内容差异无法被git成功识别出来,所以git pull指令什么都不 ...
- 配置kuernetes集群pod拉取私有镜像仓库中的镜像
目录 1 背景说明 2 实现方法 3 具体实现 配置镜像仓库项目为公开类型(任何人可以访问) 配置docker-registry类型的secret(pod使用secret获取镜像认证) 通过账户名密码 ...
- Jenkins拉取Git远程仓库中指定目录至本地指定目录
Jenkins拉取源码是非常实用的操作,比如每天在跑自动化测试前,拉取Git远程仓库中最新的脚本至本地.那么,Jenkins如何拉取Git远程仓库中指定目录至本地指定目录呢?下面来看看具体的设置方法. ...
- oracle 取前10条记录
1.oracle 取前10条记录 1) select * from tbname where rownum < 11; 2) select * from (select * from tbnam ...
- Oracle 取两个表中数据的交集并集差异集合
Oracle 取两个表中数据的交集 关键字: Oracle 取两个表中数据的交集 INTERSECT Oracle 作为一个大型的关系数据库,日常应用中往往需要提取两个表的交集数据 例如现有如下表,要 ...
- c# applibrary实现一个Sheet表中存放多张DataTable数据
1.工具类(applibrary.dll) public class ExcelHelper { /// <summary> /// 文件名 /// </summary> pu ...
- 一个表中的id有多个记录,把所有这个id的记录查出来,并显示共有多少条记录数
一个表中的id有多个记录,把所有这个id的记录查出来,并显示共有多少条记录数 select id ,Count(*) from table_name group by id having count( ...
- oracle和sql server中,取前10条数据语法的区别
在sql server中,取数据中前10条语句,我们可以用top 10 这样语句,但是oracle就没有这个函数,接下来介绍它们之间的区别 1.sql server 取前10语句和随机10条的语法 - ...
- Azure DevOps Server: 使用Rest Api获取拉取请求Pull Request中的变更文件清单
需求: Azure DevOps Server 的拉取请求模块,为开发团队提供了强大而且灵活的代码评审功能.拉取请求中变更文件清单,对质量管理人员,是一个宝贵的材料.质量保障人员可以从代码清单中分析不 ...
随机推荐
- mfc cef<转>
在mfc单文档程序中加入cef: .在BOOL CtestCEFApp::InitInstance()中初始化cef HINSTANCE hInst = GetModuleHandle(NULL); ...
- python中函数基础
函数 什么是函数? 函数分为内置函数和自定义函数 定义:在程序中具备某一功能的工具.在使用之前需准备该工具(函数的定义),遇到应用场景拿来就用(后引用). 为什么要用函数? 1.代码冗余 程序组织结构 ...
- RabbitMQ系列教程之四:路由(Routing)(转载)
RabbitMQ系列教程之四:路由(Routing) (使用Net客户端) 在上一个教程中,我们构建了一个简单的日志系统,我们能够向许多消息接受者广播发送日志消息. 在本教程中,我们将为其添加一项功能 ...
- 【362】python 正则表达式
参考:正则表达式 - 廖雪峰 参考:Python3 正则表达式 - 菜鸟教程 参考:正则表达式 - 教程 re.match 尝试从字符串的起始位置匹配一个模式,如果不是起始位置匹配成功的话,match ...
- week06 07 创建RPC SERVER 换个镜像安装下载
RPC server 使用python类库 https://pypi.org/project/python-jsonrpc/ 和NPM 不一样 他没有global选项 他安装的就是全局的安装的类库叫p ...
- 16.0 Auth0注册与设置
首先呢?注册https://manage.auth0.com 填写回调网页,意思是当我们点sign in 那个按钮的时候 会访问这个官网 这个官网又回调下面的网页,不然会报错.这个网站因为我们是开发所 ...
- python基础学习Day12 生成器、列表推导式、字典的表达式、字典键值对的互换、集合推导式
一.生成器 1.1 生成器:就是(python)自己用代码写的迭代器,生成器的本质就是迭代器. 1.2 生成器函数 def func1(x): x += print() yield x print() ...
- SPSS-生存分析
生存分析 定义:一些医学事件所经历的时间:从开始观察到事件发生的时间,不是短期内可以明确判断的.针对这类生存资料的分析方法叫生存分析.生存分析的基本概念1.终点事件终点事件outcome event: ...
- DRDS 概述
DRDS 概述 更新时间:2017-08-04 13:53:50 分布式关系型数据库服务(Distributed Relational Database Service , 简称 DRDS ) ...
- java.net.UnknownHostException: www.terracotta.org
异常日志: java.net.UnknownHostException: www.terracotta.org at java.net.PlainSocketImpl.connect(PlainSoc ...