大数据量下如何根据B表更新A表数据?

18679684979
  • 5
新手上路,请多包涵

问题描述

大数据量下如何根据B表更新A表数据?

问题出现的环境背景及自己尝试过哪些方法

背景如下:
A表为工作量表,
B表为积分表,
公式为 积分 = 工作量 * 系数
当系数发生变化时,需要根据工作量重算积分。
我能想到的方案:

1.将积分和工作量分别取出,再逐行更新,这样十几万的数据量下可能会出现性能问题。
2.做一个联表更新sql,将系数传入。但是如果以后做拆分,这样的sql会比较难维护。
3.将方案1中的sql语句拼起来,每100条做一次提交。但是很难保证失败的情况下数据的一致性。
4.将方案1做成异步场景,然后引入失败重试机制。这样的话开发成本较大。

相关代码

场景是:

table A
id col1 col2
1  A1   A2

table B
id cola colb
1  B1   B2

公式为:
B1 = A1 * c
B2 =A2 * d
(c,d均为传入的常数)
如何最优的做数据的级联更新。

你期待的结果是什么?实际看到的错误信息又是什么?

有没有什么比较好的方案?### 问题描述
回复
阅读 1.9k
1 个回答
✓ 已被采纳

题主你好, 我提供一点自己的思路.

  1. 强业务场景,也就是说, 数据不能出错. 所以我不推荐,启动其他进程,监听binlog来做,虽然这是我最喜欢的方式, 但是编码以及运维保证这套流程绝对正确,没那么简单.
  2. 不推荐数据库层面搞触发器之类的东西,维护比较困难.
  3. 所以我觉得你的方案,思路问题不大, 那就是要解决性能问题了.

那么,首先写几个假设:

  1. 数据量比较大.
  2. 系数更改后,不能接受一段时间后再拿到新的积分.
  3. 不能接受系统修改积分期间,拒绝对外提供服务.

这个场景是不是有点熟悉了?不妨参考redis的rehash过程试一下?
在系数更改后

  1. 更改某一个标志位
  2. 触发业务中的一段代码,启动其他线程,以一个温和的速率不断计算新的积分.
  3. 在重新计算期间,每一个新的查询进来,如果当前不是重新计算的结果, 就重新计算一下当前用户的积分.
  4. 所有积分计算完毕, 重置标志位.

思路其实就是,把瞬间的计算量分为两部分:

  1. 一个线程以温和的速度不断重计算.
  2. 每一个请求进来, 帮忙计算当前用户(也可以多帮几个)的积分.

直到完成.

宣传栏