【问题标题】:Converting H2/MySQL query to Postgres/cockroach将 H2/MySQL 查询转换为 Postgres/cockroach
【发布时间】:2018-11-20 14:32:14
【问题描述】:

我想将以下(诚然不好)查询从 H2/MySQL 转换为 Postgres/cockroach:

SET @UPDATE_TRANSFER= 
(select count(*) from transfer where id=‘+transfer_id+' and consumed=false)>0;

update balance_address set balance = 
case when @UPDATE_TRANSFER then balance +
     (select value from transaction where transfer_id=‘+id+' and t_index=0) 
else balance end where address = 
     (select address from transaction where transfer_id=‘+id+' and t_index=0)

这个查询涉及三个表:balance_addressbundletransaction。查询的目的是在发生资金转帐时更新总余额。

一次转账可以将许多交易捆绑在一起。例如,假设 Paul 的账户中有 20 美元,他想向 Jane 汇款 3 美元。这将产生 4 笔交易: 一种在简的账户中增加了 3 美元 一笔从 Paul 账户中扣除 20 美元的交易 将 Paul 帐户更改为 0 的一笔交易 一笔交易将剩余的 Paul 资金存入新地址;还是属于他的。

整个传输包中的每个交易都有一个索引和一个值。正如你在上面看到的。所以这个更新查询的目标是更新 Jane 的帐户。

挑战在于这种传输可以由许多服务器并行处理,并且没有分布式锁。所以,如果我们天真地并行处理,每个服务器都会增加 Jane 的帐户,从而导致错误的结果。

为了防止这种情况发生,balance_address 表有一个名为consumed 的列。更新余额的第一台服务器将转移设置为消费=真。其他服务器或线程只有在消费为假时才能更新。

所以,我的目标是 1) 改进此查询并 2) 重写它以与海报一起使用。目前,变量构造尚未被接受。

PS。我无法更改数据模型。

【问题讨论】:

    标签: mysql postgresql h2 cockroachdb


    【解决方案1】:

    CockroachDB 没有变量,但@UPDATE_TRANSFER 变量只使用一次,因此您可以直接替换子查询内联:

    update balance_address set balance = 
        case 
            when (select count(*) from transfer where id=$1 and consumed=false)>0 
            then balance + (select value from transaction where transfer_id=$1 and t_index=0) 
            else balance
        end 
        where address = 
         (select address from transaction where transfer_id=$1 and t_index=0)
    

    但这并没有设置consumed 标志。最简单的方法是在您的客户端应用程序中进行多步骤事务:

    num_rows = txn.execute("UPDATE transfer SET consumed=true 
        WHERE id=$1 AND consumed=false", transfer_id)
    if num_rows == 0: return
    value, address = txn.query("SELECT value, address FROM transaction 
        WHERE transfer_id=$1 and t_index=0", transfer_id)
    txn.execute("UPDATE balance_address SET balance = balance+$1 
        WHERE address = $2", value, address)
    

    在 PostgreSQL 中,我认为您可以使用公用表表达式将其整合到一个大语句中。但是,CockroachDB 2.0 只支持 CTE 的一个子集,我认为在 cockroach 中使用 CTE 还不能做到这一点。

    【讨论】:

      猜你喜欢
      • 2019-07-13
      • 2016-10-23
      • 2019-06-18
      • 1970-01-01
      • 1970-01-01
      • 2021-10-29
      • 1970-01-01
      • 2012-07-21
      • 1970-01-01
      相关资源
      最近更新 更多