业务是这样的: 有两个表 ①ra 库.A 表 ②rb 库.B 表
需要分页查询 A 表并且去掉一部分数据,这部分需要去掉的数据存在于 B 表中 请问这个业务如何实现? 目前遇到的问题是 查 A 表 1-20 条 可能需要去掉 3 条数据 不好分页 也不太可能一次性查出来所有的数据在程序中进行分页
1
ChoateYao 2021-04-25 11:36:26 +08:00
如果不能上数据库中间件,那么唯一的做法就是根据检索条件,检索出全量 ID,然后根据 ID 进行分页之后在取每页条数具体数据。
|
2
Felldeadbird 2021-04-25 11:40:50 +08:00
如果你可以 SQL 去实现筛选。那么就做跨库视图。
|
3
seagull7558 OP @ChoateYao emmm 这个操作好像还是有点憨 请问数据库中间件是指什么? 跨数据库查询的工具吗? 还是指 ES 这种
|
4
lonenol 2021-04-25 11:58:22 +08:00
搜索引擎
|
5
fdgdbr 2021-04-25 12:08:28 +08:00
oracle 可以用 dblink,其他的就不知道了
|
6
love 2021-04-25 12:18:38 +08:00
根本不用管 B 表,直接在 A 表分页,然后在页内去掉 B 表的数据好了,一页少个几条又不是不能用
|
7
ideascf 2021-04-25 12:56:26 +08:00
做宽表,或数据同步到数仓或 es,在数仓或 es 上搜索
|
8
oneisall8955 2021-04-25 13:02:15 +08:00 via Android
我司上 es,每天跑 job 刷索引
|
9
timethinker 2021-04-25 13:09:39 +08:00
在不修改表的前提下,可以将 B 表的相关特征(例如需要排除的一些条件列)同步到 A 表的库中(也就是说在 ra 建立一张新的表,用于存储 rb 的 B 表的部分数据,这一部分数据就是 B 表的子集)。同步的时机取决于对延迟的要求,可以定时同步,或者在更新 B 表的时候立即同步。
同步过来的这些数据跟 A 表应该具有某种对应关系吧,例如包含 XX 值、或者有外键关联的信息,这样就可以直接用 SQL 去过滤 A 表的数据了。 |
10
mingmeng 2021-04-25 13:35:50 +08:00 via Android
@seagull7558 mycat 这种,类似于将 db 请求代理一下,将不同库间查询封装起来,向上透明成一个请求,自己会处理分裤分表的差异。但是一般中间件成本比较高吧,团队一般不会为了一两个查询上这种中间件。如果确有需要可以看下,这个的运维成本比较高主要是
|
11
tommyzhang 2021-04-25 13:57:39 +08:00
ES
|
12
wdytoya 2021-04-25 14:52:14 +08:00
那这种就是有关联特征的,有几种做法
1. 要么查完 A,再查 B,删掉之后再查 A 补,可能需要多次,看业务需求折中查询上限和展示条数 2. 要么在 A 中冗余 B 的一些特征,查的时候就不再要用 B 表数据了,直接在 A 表是过滤 3. 要么两边都按一定位点往下查,查完再聚合处理,也可能涉及多次,跟 1 一样需要折中处理 当然其他的一些做法其实也是类似的思路去做,只是可能有其他的一些中间件或异步分支来做这些事情,而不在主流程上做 |
13
sujin190 2021-04-25 15:04:52 +08:00
可以两个表分别都查出对应完整数据,然后再合并取前一页条数就行,这个因为已经在数据库排序好了,合并复杂读就是 o(1)的,非常快
查询下一页的时候只要记住每个库上一页的最后一个 id,然后从最后一个 id 往后再查询一页返回,最后和刚才一样在内存中合并就可以了 其实数据库中间件可以查询多个库分页用的差不多也是这么个逻辑吧 |
14
andy2415 2021-04-25 15:09:02 +08:00
pgsql 可以用 FOREIGN TABLE
|
15
ZhaoHuiLiu 2021-04-25 15:21:20 +08:00
好像所有数据都提供跨库查询
比如 MySQL 的话,你搜索 MySQL 跨库查询,就有相关资料了。查询方式和普通 select 一样。。。。 |
16
clf 2021-04-25 17:38:42 +08:00
如果数据库都是一样的类型的话目前主流数据库都是可以跨库查询的。
如果不是一样的类型,比如一个是 MongoDB,一个是 Mysql 。这其实更多的是数据库设计的时候出现了问题。强关联的数据应该放到关系数据库里,文档类数据才放到 Mongo 里。这时候一般是采用数据库冗余另外一个数据库的数据进行搜索,但会增加数据一致性维护的成本。还有一种就是把几个库的数据都丢到 ES 里。统一用 ES 搜索。 |
17
kekxv 2021-04-25 18:02:14 +08:00 via iPhone
如果数据量不大或不考虑优化,直接联合查询分页不就好了?
或者直接建个视图表。 或者干脆 直接新建一个表,做这个用途,每次插入更新的时候做 hook 更新该表,然后分页就只需要对这个表分页,再做关系查出另两张表数据。 |
19
CRUD 2021-04-25 18:14:57 +08:00
我司也遇到了这个问题,目前我打算用 canal 将多库数据同步至 elasticsearch 中,然后在 elasticsearch 中做检索。
|
20
vickchen1992 2021-04-25 18:23:19 +08:00
es
|
21
masterclock 2021-04-25 18:31:46 +08:00
做过的方法:
1. PostgreSQL FDW 2. 复制到 ES 3. apache calcite 都行,各有优点缺点 |
22
passerbytiny 2021-04-25 18:44:02 +08:00 via Android
如果总结果数不大(少于 10000 行),那么直接全部查到内存中然后用代码分页。否则,要么重构数据模型设计(重新分配数据或者增加至少达到最终一致性的宂余数据,使得只需查一个库),要么重构需求,要么炒掉提需求的人。
|
23
labulaka521 2021-04-25 18:59:41 +08:00
|
24
notejava 2021-04-26 12:02:53 +08:00
既然做了分库,就不应该再考虑连表操作。
|
25
xiaoxinshiwo 2021-04-26 13:47:25 +08:00
sharding jdbc 或者 ES
|
26
weizhen199 2021-04-26 14:41:53 +08:00
你可以让应用承担一部分数据库中查询优化器的功能,判断下两张表的扫描模式和连结方式。
额,就是前面人说的 apache calcite |