pg数据库 多种update方式

场景

常见的几种 update 数据的场景

  1. 单表更新(区分单表数据量级、是否带过滤条件)
  2. 多表联合更新,用 B 表的数据更新 A 表,有点类似 Excel 的 vlookup 函数。

场景就这两个,可以有多种写法,但目的是一样的。

实现

语法(官方文档

[ WITH [ RECURSIVE ] with_query [, ...] ]
UPDATE [ ONLY ] table_name [ * ] [ [ AS ] alias ]
    SET { column_name = { expression | DEFAULT } |
          ( column_name [, ...] ) = [ ROW ] ( { expression | DEFAULT } [, ...] ) |
          ( column_name [, ...] ) = ( sub-SELECT )
        } [, ...]
    [ FROM from_item [, ...] ]
    [ WHERE condition | WHERE CURRENT OF cursor_name ]
    [ RETURNING * | output_expression [ [ AS ] output_name ] [, ...] ]

单表更新

这是最常见的更新方式,用于更新满足特定条件的行,也可以结合 case 表达式实现条件更新。

select column1, column2 from table_name where condition;

--更新前养成先查询的习惯
UPDATE table_name
SET column1 = value1, column2 = value2, ...
WHERE condition; --有条件的更新,如果没有 where 过滤条件,就是全表更新,全表更新需要谨慎。

--条件更新(结合 CASE 表达式)根据不同条件更新不同的值。
UPDATE table_name
SET column1 = CASE
    WHEN id = 1 THEN 'value1'
    WHEN id = 2 THEN 'value2'
    ELSE column1
END
WHERE id IN (1, 2, 3);

多表联合更新

  1. 使用子查询
  2. 使用 from 子句
  3. 使用 CTE 表达式(3 是在 2 的基础上的变体)
--基于子查询的结果更新数据
UPDATE table1
SET column1 = (SELECT column2 FROM table2 WHERE table2.id = table1.id)
WHERE condition;

--使用 FROM 子句,可以从B表中获取数据来更新目标A表。
UPDATE table1
SET column1 = table2.column2
FROM table2
WHERE table1.id = table2.id AND condition;

--在 FROM 子句的基础上,把 FROM 的表改为 with 子句
WITH updated_rows AS (
    SELECT id, new_value
    FROM some_calculation
)
UPDATE table_name
SET column1 = updated_rows.new_value
FROM updated_rows
WHERE table_name.id = updated_rows.id;

更新返回

  • 更新完成后,默认会返回更新的行数量。
  • 如果增加了returning子句,则会返回所有更新的行。可以知道哪些行被更新了。
  • 更新返回结合 CTE 可以实现更新后的数据查询和插入
--更新返回returning
update table_name
set col = 1
where col is null
returning col as xx, col_0 as id, col_1 as yy


--使用returning,做查询插入。将更新后的记录插入另一张表
insert into another_table(xx, id, yy)
with updated as (
    update table_name
    set col = 1
    where col is null
    returning col as xx, col_0 as id, col_1 as yy
)
select * from updated

经验总结

在使用 UPDATE 时,一些经验总结

  • 在执行大规模更新前,先在小范围数据上测试。每次更新前都要先查询看一下或者备份;
  • 大批量的数据,确保有适当的索引以提高性能(在 where 条件中使用索引列),另外尽量切分为小批量数据分批执行,减少锁竞争;
  • 表要定期执行 vaccum和analyze,做表定期维护
  • 尽量避免频繁更新,可以从业务表设计上规避频繁更新情况;
  • 注意并发更新可能带来的问题,如死锁;
  • 如果有相互依赖的表更新操作,最好把他们放到一个事务里面提交,以保证数据一致性;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值