跨库跨表的分页查询实现

本贴最后更新于 3122 天前,其中的信息可能已经事过境迁

对于数据库分库分表之后,涉及到查询时就会存在一些问题,比如如何分页,如何排序,如何处理函数平均值等等,特别是对于分页功能,需要在应用中将数据合并后进行排序,在显示,还需要考虑应用中翻页的页码与实际库中查询时页码的关系,同时还需要考虑某个库数据查询完毕后,其他库中如何增加每次查询页码的问题,否则查询后的总页数不能满足应用中的页数。

当前GAP平台正在进行组织权限系统的服务化,存在一个统一集中式管理的远端组织权限服务系统,同时也存在一个具体业务系统的本地组织权限,那么当用户登陆到本地业务系统后,在进行系统用户管理时,希望看到的是能登陆到本地系统所有的用户信息,此时看到的用户数据来自远端(公共管理的用户数据)和本地(业务系统特有的用户数据),如何实现分页?下面结合具体情况说明如何实现。

场景是2个数据库,要求排序,并且查询不是非常频繁,访问量也不会很大,没有用户会一直在那里进行翻页操作,同时对于一个企业来说,用户信息频繁变动也是不切实际的。

对于分页功能来说,分两种情况,一种要求排序,一种不要求排序。非排序分页,可以按照同等步长的方式在2个数据源上进行分页查询,也就是分页的每页记录数,平均来自这2个数据源,每次查询每页的记录数都平均来自这2个数据源,当某个数据源没有符合条件的数据记录时,就需要单独查询另外一个数据源,查询的记录数同时也就需要增加;而另外一种情况可以按照同等比例的分页方式,也就是某个数据源每次分页查询时查询的记录数占该数据源符合条件的所有记录的比例是一定的,因为每次分页查询查多少记录是根据2个数据源中所有符合条件的记录总数计算出来的,这样就保证了当分页查询结束后,2个数据源也就同时查询完毕。

那么非排序分页的弊端在那里,首先不能进行排序,这样数据出来比较乱,用户不会满意,其次对于同等比例或者同等步长这两种方式,需要考虑的因素比较多,如下:

  • 每次分页如何平均2个数据源上的查询记录数
  • 当每页记录数变化时怎么处理
  • 当某个数据源查询完毕,没有符合条件的记录时,如何对另一个数据源增加每次查询的记录数?增加后就会影响到计算起始记录数

所以我们决定选择排序分页方式。就是从2个数据源处将足够多的数据取回来,在应用中按照某个条件进行归并排序,然后进行分页显示,难点在于取多少才算是足够的数据?考虑一种比较极端的情况,就是满足当前页的排好序的记录都来自同一个数据源,那么就要求每次查询时,每个数据源的分页记录数至少是这个值。比如当前每页显示4条记录,那么查询第一页时,需要每个数据源至少查出排好序的记录数4条,也就是总共8条记录数,然后进行归并排序,再显示排好序的4条,另外4条记录将会被丢掉;当查询第二页时,是不是只要查询每个数据源中的第二页数据呢?其实不是这样的,因为虽然每个数据源中的分页数据是已经排好序的,但是你无法确定这2个数据源中第二页数据之间的排序情况,有可能其中一个数据源的第三页数据与另外一个数据源的第五页数据才是临近排序的,所以我们需要取回每个数据源的前两页数据,再进行归并排序,那么当用户直接翻到100页的时候,就需要把每个数据源的前100页所有数据都取出,然后进行排序,而且是每次分页查询都需要重新查询一次上次已经查出的数据。

对于这种方式,我们的改进措施是使用缓存,将每次查询出的记录都保存在缓存中,当然是已经排好序的。当用户第一次翻页时,查询第一页数据,实际是从2个数据源处总共查出4(这个偏移量是可以配置的)页大小的数据(每个数据源2页大小数据),同时应用中排好序后进行缓存,这样这四页数据全部从缓存中加载,速度很快;当翻到第五页的时候,再做一次查询(前四页数据不再重复查询),按照偏移量大小,将取回来的数据与原来前四页数据进行重新排好序,然后再次放入缓存中,这样前8页数据都是从缓存中获取,而且是排好序的。

极端情况是,用户一下子直接查询了第100页的数据,那么按照偏移量设置,每个数据源是查询了200页的数据,总共是400页数据被一下子查询出来,然后进行排序放入缓存,对于这种情况,我们做了预防措施,如果跨度过大,比如这里的100页翻页情况,我们直接不予进行查询。

通过结合缓存,保证了排序分页的实现,同时对每次查询条件不同,缓存的内容不同,所以系统对于相同查询条件的查询结果都做了缓存,速度提升明显。并且当用户数据有更新时,并没有及时更新缓存,我们提供了一个刷新按钮,强制清除缓存,重新查询,因为缓存数据配置的是永不过期策略。

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...
  • crick77 via macOS

    缓存会造成数据不一致的问题。
    分页不允许用户查询到 100 页之后??

推荐标签 标签

  • CloudFoundry

    Cloud Foundry 是 VMware 推出的业界第一个开源 PaaS 云平台,它支持多种框架、语言、运行时环境、云平台及应用服务,使开发人员能够在几秒钟内进行应用程序的部署和扩展,无需担心任何基础架构的问题。

    5 引用 • 18 回帖 • 179 关注
  • Sym

    Sym 是一款用 Java 实现的现代化社区(论坛/BBS/社交网络/博客)系统平台。

    下一代的社区系统,为未来而构建

    524 引用 • 4601 回帖 • 698 关注
  • Pipe

    Pipe 是一款小而美的开源博客平台。Pipe 有着非常活跃的社区,可将文章作为帖子推送到社区,来自社区的回帖将作为博客评论进行联动(具体细节请浏览 B3log 构思 - 分布式社区网络)。

    这是一种全新的网络社区体验,让热爱记录和分享的你不再感到孤单!

    132 引用 • 1115 回帖 • 122 关注
  • Office

    Office 现已更名为 Microsoft 365. Microsoft 365 将高级 Office 应用(如 Word、Excel 和 PowerPoint)与 1 TB 的 OneDrive 云存储空间、高级安全性等结合在一起,可帮助你在任何设备上完成操作。

    5 引用 • 34 回帖
  • Hexo

    Hexo 是一款快速、简洁且高效的博客框架,使用 Node.js 编写。

    22 引用 • 148 回帖 • 13 关注
  • DNSPod

    DNSPod 建立于 2006 年 3 月份,是一款免费智能 DNS 产品。 DNSPod 可以为同时有电信、网通、教育网服务器的网站提供智能的解析,让电信用户访问电信的服务器,网通的用户访问网通的服务器,教育网的用户访问教育网的服务器,达到互联互通的效果。

    6 引用 • 26 回帖 • 524 关注
  • 30Seconds

    📙 前端知识精选集,包含 HTML、CSS、JavaScript、React、Node、安全等方面,每天仅需 30 秒。

    • 精选常见面试题,帮助您准备下一次面试
    • 精选常见交互,帮助您拥有简洁酷炫的站点
    • 精选有用的 React 片段,帮助你获取最佳实践
    • 精选常见代码集,帮助您提高打码效率
    • 整理前端界的最新资讯,邀您一同探索新世界
    488 引用 • 384 回帖 • 3 关注
  • Thymeleaf

    Thymeleaf 是一款用于渲染 XML/XHTML/HTML5 内容的模板引擎。类似 Velocity、 FreeMarker 等,它也可以轻易的与 Spring 等 Web 框架进行集成作为 Web 应用的模板引擎。与其它模板引擎相比,Thymeleaf 最大的特点是能够直接在浏览器中打开并正确显示模板页面,而不需要启动整个 Web 应用。

    11 引用 • 19 回帖 • 381 关注
  • OAuth

    OAuth 协议为用户资源的授权提供了一个安全的、开放而又简易的标准。与以往的授权方式不同之处是 oAuth 的授权不会使第三方触及到用户的帐号信息(如用户名与密码),即第三方无需使用用户的用户名与密码就可以申请获得该用户资源的授权,因此 oAuth 是安全的。oAuth 是 Open Authorization 的简写。

    36 引用 • 103 回帖 • 26 关注
  • Redis

    Redis 是一个开源的使用 ANSI C 语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value 数据库,并提供多种语言的 API。从 2010 年 3 月 15 日起,Redis 的开发工作由 VMware 主持。从 2013 年 5 月开始,Redis 的开发由 Pivotal 赞助。

    286 引用 • 248 回帖 • 19 关注
  • Telegram

    Telegram 是一个非盈利性、基于云端的即时消息服务。它提供了支持各大操作系统平台的开源的客户端,也提供了很多强大的 APIs 给开发者创建自己的客户端和机器人。

    5 引用 • 35 回帖
  • 设计模式

    设计模式(Design pattern)代表了最佳的实践,通常被有经验的面向对象的软件开发人员所采用。设计模式是软件开发人员在软件开发过程中面临的一般问题的解决方案。这些解决方案是众多软件开发人员经过相当长的一段时间的试验和错误总结出来的。

    200 引用 • 120 回帖 • 1 关注
  • InfluxDB

    InfluxDB 是一个开源的没有外部依赖的时间序列数据库。适用于记录度量,事件及实时分析。

    2 引用 • 91 关注
  • 人工智能

    人工智能(Artificial Intelligence)是研究、开发用于模拟、延伸和扩展人的智能的理论、方法、技术及应用系统的一门技术科学。

    152 引用 • 279 回帖
  • Access
    1 引用 • 3 回帖 • 6 关注
  • TextBundle

    TextBundle 文件格式旨在应用程序之间交换 Markdown 或 Fountain 之类的纯文本文件时,提供更无缝的用户体验。

    1 引用 • 2 回帖 • 73 关注
  • 链滴

    链滴是一个记录生活的地方。

    记录生活,连接点滴

    167 引用 • 3832 回帖 • 1 关注
  • Ant-Design

    Ant Design 是服务于企业级产品的设计体系,基于确定和自然的设计价值观上的模块化解决方案,让设计者和开发者专注于更好的用户体验。

    17 引用 • 23 回帖 • 1 关注
  • 代码片段

    代码片段分为 CSS 与 JS 两种代码,添加在 [设置 - 外观 - 代码片段] 中,这些代码会在思源笔记加载时自动执行,用于改善笔记的样式或功能。

    用户在该标签下分享代码片段时需在帖子标题前添加 [css] [js] 用于区分代码片段类型。

    127 引用 • 856 回帖
  • 印象笔记
    3 引用 • 16 回帖
  • GitHub

    GitHub 于 2008 年上线,目前,除了 Git 代码仓库托管及基本的 Web 管理界面以外,还提供了订阅、讨论组、文本渲染、在线文件编辑器、协作图谱(报表)、代码片段分享(Gist)等功能。正因为这些功能所提供的便利,又经过长期的积累,GitHub 的用户活跃度很高,在开源世界里享有深远的声望,并形成了社交化编程文化(Social Coding)。

    210 引用 • 2040 回帖
  • Python

    Python 是一种面向对象、直译式电脑编程语言,具有近二十年的发展历史,成熟且稳定。它包含了一组完善而且容易理解的标准库,能够轻松完成很多常见的任务。它的语法简捷和清晰,尽量使用无异义的英语单词,与其它大多数程序设计语言使用大括号不一样,它使用缩进来定义语句块。

    549 引用 • 674 回帖
  • MySQL

    MySQL 是一个关系型数据库管理系统,由瑞典 MySQL AB 公司开发,目前属于 Oracle 公司。MySQL 是最流行的关系型数据库管理系统之一。

    692 引用 • 535 回帖 • 1 关注
  • MongoDB

    MongoDB(来自于英文单词“Humongous”,中文含义为“庞大”)是一个基于分布式文件存储的数据库,由 C++ 语言编写。旨在为应用提供可扩展的高性能数据存储解决方案。MongoDB 是一个介于关系数据库和非关系数据库之间的产品,是非关系数据库当中功能最丰富,最像关系数据库的。它支持的数据结构非常松散,是类似 JSON 的 BSON 格式,因此可以存储比较复杂的数据类型。

    90 引用 • 59 回帖 • 4 关注
  • 域名

    域名(Domain Name),简称域名、网域,是由一串用点分隔的名字组成的 Internet 上某一台计算机或计算机组的名称,用于在数据传输时标识计算机的电子方位(有时也指地理位置)。

    43 引用 • 208 回帖 • 1 关注
  • Kubernetes

    Kubernetes 是 Google 开源的一个容器编排引擎,它支持自动化部署、大规模可伸缩、应用容器化管理。

    116 引用 • 54 回帖
  • Windows

    Microsoft Windows 是美国微软公司研发的一套操作系统,它问世于 1985 年,起初仅仅是 Microsoft-DOS 模拟环境,后续的系统版本由于微软不断的更新升级,不但易用,也慢慢的成为家家户户人们最喜爱的操作系统。

    226 引用 • 476 回帖