有个问题求大神指点,比如有个业务 因为公司限制数据库不能跨库查询。查询的字段又分布在不同的数据库的不同表上,如何根据查询条件查询出数据并进行分页。
比如 下面这种情况ida是table_a中的id,idc是table_c中的id,且都是1对1的关系
DB_A: table_a(id,name)
table_b(id,ida,size)
DB_B:table_c(id,ida,height)
table_d(id,idc,width)
,那如何实现通过size、height、width这三个查询条件查询结果并分页(不允许跨库)。
之前我们的做法是 取比较大的关联数据放到缓存里,然后直接查询缓存的数据,再分页。但这样的话有个问题是数据不能做到将已经更新的数据实时显示,数据要求比较实时。
求指点
事情是有个前端的朋友吐槽说,他们提供接口的后端因为不能跨库,因此分页不好处理,就直接将一堆数据丢给前端。前端自己进行分页处理,就问我 一般我们后端碰到这种怎么处理,然后刚好我们也是类似情况,就跟他说了我们目前暂时的解决方法,以后可能采用搜索引擎。但他说他只是前端 不能让后端怎么怎么做 只能建议,无力吐槽,而且他们是所谓大公司的一个非核心业务组,动表的流程多,麻烦,因此他们后端能不动就不动。问我有没有直接在数据库层面 做优化的,这个我暂时想不到,因此才在这边提问的,还是没找到满意的答案。
可以将你的需要的分页数据通过【复制】到本库
相关的表比较多 而且表的数据量都比较大 起码都是百万级别的
可以加一层Redis缓存之类的
目前的做法就是放到redis的 但因为数据量比较大 所以redis只能放近期的一部分数据 就是想有没有更好的方法
@Artikel: 把数据排序,放一部分到redis中,比如一千页之类的,不要放全部,后续的分页其实没什么用。
@编程点滴: 之前我们的做法就是这么干的 但这样做就有我说的问题 经常有数据不能及时更新的,比如状态改了,不应该再展示的。导致我们只能在查询接口 最后展示时再进行过滤。
@Artikel: 调整更新的时间吧,像淘宝这样的网站都没有数据实时的
@Artikel: 又或者,加一个消息队列,数据修改时做数据更新
@编程点滴: 我们讨论出的新方案,就是这样。将所需要的字段都扩展到一张新的大表上,然后写服务几分钟掉一次刷新接口,根据更新时间刷新有变更的数据,查询数据的话直接查询这张新的大表。
主要想问下有没有更优解
@Artikel: 没有了吧,有一点是可以肯定的,数据很难做到实时
这个问题最根本的解决方案就是不要跨库,不要说什么限制什么就是这样的,这种跨库查询本来就不合理。要根本性解决这个问题是在被查询的表上做冗余,或者针对查询加专门用于查询的索引表(类似倒排索引),然后直接查询被分页的数据的唯一标识后去实际表中拉数据。
为什么不合理。当时设计的时候就是根据不同业务或者模块,比如基础信息、活动信息 划分到基础数据库、活动数据库这些不同的数据库了。然后业务部门有新的查询需求 就是要求可以结合不同的而且比较多的查询组合 查询到合适的数据。
现在关键 是查询所需的条件字段分布到的数据库很散。现在就是存缓存 相当于放在一张大表上 查询的
@Artikel: 业务分模块没问题,划分不同db也没问题,但针对你现在这种场景做这种查询一味考虑如何在分散的数据上完成查询就不对,的确你现在可以通过前置缓存,小表查后再去大表中聚合可以解决,但如果数据量大了,或者并发量大了甚至只是改下查询维度这样的做法就不现实了。
解决这个的根本方案就是要把数据归并到一起,不要说什么实时,这个现有技术条件下是不现实的,你cache也好,a表查了再去查b表也好都不可能实时,所以你要牺牲这点。这块最简单的方案就是我前面说的,如果实现上有阻力可以考虑用storm之类的把数据洗出来后供你查询。这样不管在性能还是适应性上肯定比你的方案要好。
@Daniel Cai: storm洗数据这种可以学习下试看看,之前用了缓存 半小时缓存失效,效果不是特别好,然后讨论出新的方案,将所需要的字段都扩展到一张新的大表上,然后写服务几分钟掉一次刷新接口,根据更新时间刷新有变更的数据,查询数据的话直接查询这张新的大表。
就是想问看看 别人有没有碰到类似的问题,有没有更好的解决方案。
@Artikel: 你最后这种方案是可行的,但建议是原始数据提供方(业务端)在数据变化后直接推消息过来,这样对业务端的干扰最小,后面限制及对业务端的耦合度也最低,而且很容易做到准实时(实际有些地方已经有点类似storm了)
你可以先查主表,分页后,在显示绑定的时候在去查子表的信息
是查询条件 就有子表的字段 不能像你说的那样做
找领导咯!
知道弹性搜索elasticsearch吗,通过对应数据库river直接可以同步数据到其中,
接下来的搜索可是它最无敌的能力.另外我得说,
同样mongo也有同步工具
也有考虑ES 但以前只是稍微了解过 还没用过 有空的时候研究下 自己搭下看看。利用现有数据库资源有没有更好的解决方法
可以把需要查询的数据从生产库抽取到数据仓库里面进行多表关联查询。这就是一个非常简单的ETL过程
数据清洗可以有,但多表关联查询 还不如用大表查询
@Artikel: 一对多的也搞进一个大表里面?
@xuanbg: 1对多 就不会放到大表了。前面说了 都是1对1的关系