我有一个物化视图,基本上可以跟踪结帐时使用的所有凭证,因此我可以跟踪已使用的凭证,剩余的数量等。我只是注意到,物化视图不会更新,目前显示以下内容:
left
随使用凭证而明显减少的地方(凭证类型和使用凭证以及使用凭证的用户ID在不同的表中)。但是,它检测到已使用了一张凭证,但至于我在测试中使用的另外2张凭证,则不会从存储已使用凭证的表中拾取它们并更新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时)。
EDIT
有关其他信息,这里是我拥有的另外两个表:
优惠券:
order_vouchers:
答案 0 :(得分:2)
MV基本上只是一个表,除了它还记得应该执行哪个查询以更新(实际上是替换)其内容。
我认为Postgres没有任何parameter for automatically refreshing the MV,无论是实时的还是定期的。
创建视图时将查询并存储数据,除非您指定WITH NO DATA
,否则将创建为空。
然后您可以通过调用REFRESH MATERIALIZED VIEW
来按需(重新)填充视图。
答案 1 :(得分:0)
只是想我会为此添加一个快速解决方案:
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()');
};
比我最初想象的要直接得多。