物化视图不更新
Materialized view not updating
我有一个物化视图,基本上可以跟踪结帐时使用的所有代金券,因此我可以跟踪已经使用了多少,还剩下多少等。我刚刚注意到物化视图不会更新,目前显示如下:
其中left
随着代金券的使用明显减少(代金券类型和使用的代金券以及使用它的用户id在不同的table中)。然而,它检测到一张优惠券已被使用,但至于我在测试中使用的另外 2 张优惠券,它不会从存储已用优惠券的 table 中提取它们并更新 MV。
这是我目前制作MV的迁移的一部分:
exports.up = function(knex, Promise) {
return knex.schema
.raw(`
CREATE MATERIALIZED VIEW mv_vouchers as
SELECT v.voucher_id, v.quantity, COUNT(ov.voucher_id) AS "used", v.quantity - COUNT(ov.voucher_id) AS "left"
FROM public.vouchers v LEFT OUTER JOIN
public.order_vouchers ov
ON v.voucher_id = ov.voucher_id
GROUP BY v.voucher_id, v.quantity;
`);
};
我感觉我用错了物化视图,它只运行迁移中的查询一次(当我最初实现mv时)。
编辑
这里有另外 2 个 table 的额外信息:
代金券:
order_vouchers:
MV 基本上只是一个 table,除了它还记得应该执行哪个查询来更新(实际上替换)其内容。
我认为 Postgres 没有任何实时或定期的 parameter for automatically refreshing the MV。
创建视图时会查询和存储数据,除非您指定 WITH NO DATA
,在这种情况下,它会创建为空。
然后您可以通过调用 REFRESH MATERIALIZED VIEW
.
按需(重新)填充视图
只是想我会为此添加一个快速解决方案:
exports.up = function(knex, Promise) {
return knex.schema
.raw(`
CREATE MATERIALIZED VIEW mv_vouchers as
SELECT v.voucher_id, v.quantity, COUNT(ov.voucher_id) AS "used", v.quantity - COUNT(ov.voucher_id) AS "left"
FROM public.vouchers v LEFT OUTER JOIN
public.order_vouchers ov
ON v.voucher_id = ov.voucher_id
GROUP BY v.voucher_id, v.quantity;
`)
.raw(`
CREATE FUNCTION refresh_mv_vouchers() RETURNS trigger LANGUAGE plpgsql AS $$
BEGIN
REFRESH MATERIALIZED VIEW CONCURRENTLY mv_vouchers;
RETURN null;
END $$;
`)
.raw(`
CREATE TRIGGER refresh_mv_vouchers
AFTER insert OR update OR delete OR truncate
ON order_vouchers
EXECUTE PROCEDURE refresh_mv_vouchers();
`);
};
exports.down = function(knex, Promise) {
return knex.schema
.raw('DROP MATERIALIZED VIEW mv_vouchers')
.raw('DROP TRIGGER refresh_mv_vouchers ON order_vouchers')
.raw('DROP FUNCTION refresh_mv_vouchers()');
};
使用 :
比我最初想象的要简单得多
BEGIN
REFRESH MATERIALIZED VIEW CONCURRENTLY mv_vouchers; ...
我有一个物化视图,基本上可以跟踪结帐时使用的所有代金券,因此我可以跟踪已经使用了多少,还剩下多少等。我刚刚注意到物化视图不会更新,目前显示如下:
其中left
随着代金券的使用明显减少(代金券类型和使用的代金券以及使用它的用户id在不同的table中)。然而,它检测到一张优惠券已被使用,但至于我在测试中使用的另外 2 张优惠券,它不会从存储已用优惠券的 table 中提取它们并更新 MV。
这是我目前制作MV的迁移的一部分:
exports.up = function(knex, Promise) {
return knex.schema
.raw(`
CREATE MATERIALIZED VIEW mv_vouchers as
SELECT v.voucher_id, v.quantity, COUNT(ov.voucher_id) AS "used", v.quantity - COUNT(ov.voucher_id) AS "left"
FROM public.vouchers v LEFT OUTER JOIN
public.order_vouchers ov
ON v.voucher_id = ov.voucher_id
GROUP BY v.voucher_id, v.quantity;
`);
};
我感觉我用错了物化视图,它只运行迁移中的查询一次(当我最初实现mv时)。
编辑
这里有另外 2 个 table 的额外信息:
代金券:
order_vouchers:
MV 基本上只是一个 table,除了它还记得应该执行哪个查询来更新(实际上替换)其内容。
我认为 Postgres 没有任何实时或定期的 parameter for automatically refreshing the MV。
创建视图时会查询和存储数据,除非您指定 WITH NO DATA
,在这种情况下,它会创建为空。
然后您可以通过调用 REFRESH MATERIALIZED VIEW
.
只是想我会为此添加一个快速解决方案:
exports.up = function(knex, Promise) {
return knex.schema
.raw(`
CREATE MATERIALIZED VIEW mv_vouchers as
SELECT v.voucher_id, v.quantity, COUNT(ov.voucher_id) AS "used", v.quantity - COUNT(ov.voucher_id) AS "left"
FROM public.vouchers v LEFT OUTER JOIN
public.order_vouchers ov
ON v.voucher_id = ov.voucher_id
GROUP BY v.voucher_id, v.quantity;
`)
.raw(`
CREATE FUNCTION refresh_mv_vouchers() RETURNS trigger LANGUAGE plpgsql AS $$
BEGIN
REFRESH MATERIALIZED VIEW CONCURRENTLY mv_vouchers;
RETURN null;
END $$;
`)
.raw(`
CREATE TRIGGER refresh_mv_vouchers
AFTER insert OR update OR delete OR truncate
ON order_vouchers
EXECUTE PROCEDURE refresh_mv_vouchers();
`);
};
exports.down = function(knex, Promise) {
return knex.schema
.raw('DROP MATERIALIZED VIEW mv_vouchers')
.raw('DROP TRIGGER refresh_mv_vouchers ON order_vouchers')
.raw('DROP FUNCTION refresh_mv_vouchers()');
};
使用 :
比我最初想象的要简单得多BEGIN
REFRESH MATERIALIZED VIEW CONCURRENTLY mv_vouchers; ...