面试官问:跨库多表存在大量数据依赖问题,有哪些解决方案?

说实话,我已经做了十年了,依赖多个数据库和表的数据确实很头疼。
我尝试了很多不同的解决方案。
您列出的每个计划都有涉及的条件和陷阱。
我来说说我的特殊情况吧。

最直接的数据复制方法是将产品名称和型号字段直接存储在订单表中。
我已经在电子商务项目中使用过它。
订单请求速度很快,但每次产品更新时都必须匹配订单中的重复信息。
然后我们同步调用该集合。
因此,如果产品更新失败,订单就必须回滚。
这是一场噩梦。
后来消息队列改成了异步更新,这当然解决了。
但如果不解决消息争用和重试方法,就会再次出现数据不一致的问题。
我是一个保守的人,我认为这种方法适合字段较少且更新频率较低且项目非常静态的情况。
关于消息队列,我看到团队正在尝试跟踪消息已经传输了多少个节点。
复杂度其实并不低。

消息队列同步方案应用并不广泛,但我已经小规模尝试过。
根据服务的不同,您可能需要注册有关产品、类别和产品批次号的不同消息。
每个服务都必须编写订阅和更新逻辑,并且代码一旦保存就会被破坏。
协同调试过程中,消息种类繁多,排错就像大海捞针一样。
后来有团队搭建了统一的数据同步层,统一了消息类型。
代码重复的问题已经解决了很多,但坦白说那层代码写起来很复杂,并且产生了很多新的问题。

业务逻辑数据同步断了,我比较看好这种方式。
关键是利用中间件将生产表与依赖服务库实时同步,依赖服务直接检查同步表。
我以前在金融项目中见过这种方法,而且效果非常好。
当产品服务更新信息时,关于其他人服务不用担心。
依赖服务直接检查同步表,数据结构不改变。
也保存了Repository,只同步产品表数据,不像订单表有很多重复字段。
当时我们使用的是开源中间件Bifrost。
设置很简单,结果也很好。
但在最初的部署过程中,DBA和开发人员就同步延迟的问题争论了很长时间。

分布式交易的情况我没接触过很多,但是金融行业的兄弟却天天在谈论。
两阶段提交(2 pc)当然可以确保一致性,但使用它的任何人都知道性能瓶颈和单点故障。
TCC模式下,业务系统必须编写大量的补偿逻辑,复杂度非常高。
后来他们转而采用Saga模式,即一系列的国内交易和补偿交易。
看起来很先进,但是实现之后,他们发现在长事务的情况下仍然需要锁,性能问题又出现了。
说实话,这个解决方案非常困难。
除非您确实需要处理严格的一致性要求,否则您确实不需要它。

数据服务层抽象,这是我最常使用的技术。
关键是构建统一的数据服务层,包含跨库查询逻辑,应用层直接调用API。
我曾经带领一个团队搭建了一个大型系统,业务逻辑极其复杂。
最后我就靠这个方法减少了关节。
综合优化和缓存策略很容易实现,但初期的增长率也不小。
现有的云原生解决方案(例如 Spring Cloud Gateway 和自定义服务网关)易于使用,但需要专门的人员来维护该层代码。

一般来说,这些选项根据具体情况各有利弊。
数据冗余+消息队列适合轻量级场景,同步业务逻辑适合基于主数据的多个服务,分布式事务仅作为最后手段使用,数据服务层抽象适用于复杂的系统。
主要是要平衡一致性和性能,不要为了分离而让系统变得越来越难。

SQL UPDATE与INNER JOIN:实现跨表数据更新的实用指南

哎呀,让我告诉你一件事,使用 SQL UPDATE 和 JOIN 时必须小心。

前年,我在上海,搭建一个系统,需要更新一张表中的数据,但是这个数据又要由另一张表来确定。
仅仅使用 UPDATE 是不够的,你必须使用 JOIN。

当时我就想,我该怎么办?查了资料发现内部join就足够了。
我刚刚做了一个声明,如下所示:
sql 将表1 更新为t1 内连接表 2 AS t2 ON t1 .id = t2 .id 设置 t1 .value = t1 .value + 1 0 其中 t2 .status = '活动';
你看,我首先使用table1 的别名t1 ,然后使用table2 的内连接别名t2 条件是t1 的id等于t2 的id。
然后将设置的t1 .value更新为比原始值大1 0最后,过滤状态的位置是活动的。

做完之后我还在想,万一出了问题怎么办?我添加了一个 WHERE 子句以确保仅更新匹配的子句。
然后我运行了一下,果然成功了。

但是,你必须小心这件事。
我见过人们会忘记,并最终更改大量数据,这需要花费大量时间。

所以,请记住,使用 INNER JOIN 进行更新时,您需要先运行它以确保只更改您想要更改的内容。
不要只看文字,要尝试看看数据是否正确。

面试官:跨库多表存在大量数据依赖问题有哪些解决方案?

这个陷阱是他们不相信额外的信息解决方案。