zoukankan      html  css  js  c++  java
  • 解决 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
    版权声明:本文为博主原创文章,转载请附上博文链接!

  • 相关阅读:
    (视频)Erich Gamma 与 Visual Studio Online 的一点野史
    三维重建技术概述
    三维重建基础
    用户故事驱动的敏捷开发 – 2. 创建backlog
    用户故事驱动的敏捷开发 – 1. 规划篇
    TFS 10周年生日快乐 – TFS与布莱恩大叔的故事
    【DevOps敏捷开发动手实验】开源文档 v2015.2 stable 版发布
    看见的力量 – (II) 影响地图
    看见的力量 – (I) 解题的思维
    UDAD 用户故事驱动的敏捷开发 – 演讲实录
  • 原文地址:https://www.cnblogs.com/lykbk/p/sdasessrewrwer3453345435.html
Copyright © 2011-2022 走看看