V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
MySQL 5.5 Community Server
MySQL 5.6 Community Server
Percona Configuration Wizard
XtraBackup 搭建主从复制
Great Sites on MySQL
Percona
MySQL Performance Blog
Severalnines
推荐管理工具
Sequel Pro
phpMyAdmin
推荐书目
MySQL Cookbook
MySQL 相关项目
MariaDB
Drizzle
参考文档
http://mysql-python.sourceforge.net/MySQLdb.html
seagull7558
V2EX  ›  MySQL

条件跨数据库了 如何分页查询

  •  1
     
  •   seagull7558 · 2021-04-25 11:22:59 +08:00 · 5197 次点击
    这是一个创建于 1292 天前的主题,其中的信息可能已经有所发展或是发生改变。

    业务是这样的: 有两个表 ①ra 库.A 表 ②rb 库.B 表

    需要分页查询 A 表并且去掉一部分数据,这部分需要去掉的数据存在于 B 表中 请问这个业务如何实现? 目前遇到的问题是 查 A 表 1-20 条 可能需要去掉 3 条数据 不好分页 也不太可能一次性查出来所有的数据在程序中进行分页

    26 条回复    2021-04-26 14:41:53 +08:00
    ChoateYao
        1
    ChoateYao  
       2021-04-25 11:36:26 +08:00
    如果不能上数据库中间件,那么唯一的做法就是根据检索条件,检索出全量 ID,然后根据 ID 进行分页之后在取每页条数具体数据。
    Felldeadbird
        2
    Felldeadbird  
       2021-04-25 11:40:50 +08:00
    如果你可以 SQL 去实现筛选。那么就做跨库视图。
    seagull7558
        3
    seagull7558  
    OP
       2021-04-25 11:45:06 +08:00
    @ChoateYao emmm 这个操作好像还是有点憨 请问数据库中间件是指什么? 跨数据库查询的工具吗? 还是指 ES 这种
    lonenol
        4
    lonenol  
       2021-04-25 11:58:22 +08:00
    搜索引擎
    fdgdbr
        5
    fdgdbr  
       2021-04-25 12:08:28 +08:00
    oracle 可以用 dblink,其他的就不知道了
    love
        6
    love  
       2021-04-25 12:18:38 +08:00
    根本不用管 B 表,直接在 A 表分页,然后在页内去掉 B 表的数据好了,一页少个几条又不是不能用
    ideascf
        7
    ideascf  
       2021-04-25 12:56:26 +08:00
    做宽表,或数据同步到数仓或 es,在数仓或 es 上搜索
    oneisall8955
        8
    oneisall8955  
       2021-04-25 13:02:15 +08:00 via Android
    我司上 es,每天跑 job 刷索引
    timethinker
        9
    timethinker  
       2021-04-25 13:09:39 +08:00
    在不修改表的前提下,可以将 B 表的相关特征(例如需要排除的一些条件列)同步到 A 表的库中(也就是说在 ra 建立一张新的表,用于存储 rb 的 B 表的部分数据,这一部分数据就是 B 表的子集)。同步的时机取决于对延迟的要求,可以定时同步,或者在更新 B 表的时候立即同步。

    同步过来的这些数据跟 A 表应该具有某种对应关系吧,例如包含 XX 值、或者有外键关联的信息,这样就可以直接用 SQL 去过滤 A 表的数据了。
    mingmeng
        10
    mingmeng  
       2021-04-25 13:35:50 +08:00 via Android
    @seagull7558 mycat 这种,类似于将 db 请求代理一下,将不同库间查询封装起来,向上透明成一个请求,自己会处理分裤分表的差异。但是一般中间件成本比较高吧,团队一般不会为了一两个查询上这种中间件。如果确有需要可以看下,这个的运维成本比较高主要是
    tommyzhang
        11
    tommyzhang  
       2021-04-25 13:57:39 +08:00
    ES
    wdytoya
        12
    wdytoya  
       2021-04-25 14:52:14 +08:00
    那这种就是有关联特征的,有几种做法
    1. 要么查完 A,再查 B,删掉之后再查 A 补,可能需要多次,看业务需求折中查询上限和展示条数
    2. 要么在 A 中冗余 B 的一些特征,查的时候就不再要用 B 表数据了,直接在 A 表是过滤
    3. 要么两边都按一定位点往下查,查完再聚合处理,也可能涉及多次,跟 1 一样需要折中处理
    当然其他的一些做法其实也是类似的思路去做,只是可能有其他的一些中间件或异步分支来做这些事情,而不在主流程上做
    sujin190
        13
    sujin190  
       2021-04-25 15:04:52 +08:00
    可以两个表分别都查出对应完整数据,然后再合并取前一页条数就行,这个因为已经在数据库排序好了,合并复杂读就是 o(1)的,非常快
    查询下一页的时候只要记住每个库上一页的最后一个 id,然后从最后一个 id 往后再查询一页返回,最后和刚才一样在内存中合并就可以了
    其实数据库中间件可以查询多个库分页用的差不多也是这么个逻辑吧
    andy2415
        14
    andy2415  
       2021-04-25 15:09:02 +08:00
    pgsql 可以用 FOREIGN TABLE
    ZhaoHuiLiu
        15
    ZhaoHuiLiu  
       2021-04-25 15:21:20 +08:00
    好像所有数据都提供跨库查询
    比如 MySQL 的话,你搜索 MySQL 跨库查询,就有相关资料了。查询方式和普通 select 一样。。。。
    clf
        16
    clf  
       2021-04-25 17:38:42 +08:00
    如果数据库都是一样的类型的话目前主流数据库都是可以跨库查询的。

    如果不是一样的类型,比如一个是 MongoDB,一个是 Mysql 。这其实更多的是数据库设计的时候出现了问题。强关联的数据应该放到关系数据库里,文档类数据才放到 Mongo 里。这时候一般是采用数据库冗余另外一个数据库的数据进行搜索,但会增加数据一致性维护的成本。还有一种就是把几个库的数据都丢到 ES 里。统一用 ES 搜索。
    kekxv
        17
    kekxv  
       2021-04-25 18:02:14 +08:00 via iPhone
    如果数据量不大或不考虑优化,直接联合查询分页不就好了?
    或者直接建个视图表。
    或者干脆 直接新建一个表,做这个用途,每次插入更新的时候做 hook 更新该表,然后分页就只需要对这个表分页,再做关系查出另两张表数据。
    kekxv
        18
    kekxv  
       2021-04-25 18:06:34 +08:00 via iPhone
    @kekxv 没看清是跨库了🐶
    CRUD
        19
    CRUD  
       2021-04-25 18:14:57 +08:00
    我司也遇到了这个问题,目前我打算用 canal 将多库数据同步至 elasticsearch 中,然后在 elasticsearch 中做检索。
    vickchen1992
        20
    vickchen1992  
       2021-04-25 18:23:19 +08:00
    es
    masterclock
        21
    masterclock  
       2021-04-25 18:31:46 +08:00
    做过的方法:
    1. PostgreSQL FDW
    2. 复制到 ES
    3. apache calcite
    都行,各有优点缺点
    passerbytiny
        22
    passerbytiny  
       2021-04-25 18:44:02 +08:00 via Android
    如果总结果数不大(少于 10000 行),那么直接全部查到内存中然后用代码分页。否则,要么重构数据模型设计(重新分配数据或者增加至少达到最终一致性的宂余数据,使得只需查一个库),要么重构需求,要么炒掉提需求的人。
    notejava
        24
    notejava  
       2021-04-26 12:02:53 +08:00
    既然做了分库,就不应该再考虑连表操作。
    xiaoxinshiwo
        25
    xiaoxinshiwo  
       2021-04-26 13:47:25 +08:00
    sharding jdbc 或者 ES
    weizhen199
        26
    weizhen199  
       2021-04-26 14:41:53 +08:00
    你可以让应用承担一部分数据库中查询优化器的功能,判断下两张表的扫描模式和连结方式。




    额,就是前面人说的 apache calcite
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1138 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 180ms · UTC 18:36 · PVG 02:36 · LAX 10:36 · JFK 13:36
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.