我有两张table, Order
以及 Slot
. 每个插槽都有时间,但为了简单起见,我们假设它们是整数。像这样:
Order Slot
----- ----
order_id slot_id
earliest order_id
latest time_from
time_to
我在努力保持 earliest
以及 latest
更新如下: earliest = MIN(slot.time_from)
以及 latest = MAX(time_to)
. 总是这样 time_from < time_to
,但这不重要。
为此,我在更新时创建了触发器,并在插槽中插入触发器。触发器:
CREATE OR REPLACE FUNCTION keep_orders_updated() RETURNS trigger AS $trigger$
BEGIN
UPDATE "order"
SET earliest=d.earliest_min, latest=d.latest_max
FROM (SELECT MIN(time_from) as earliest_min, MAX(time_to) AS latest_max FROM "slot" WHERE order_id = NEW.order_id) AS d
WHERE order_id=NEW.order_id;
RETURN NULL;
END;
$trigger$ LANGUAGE plpgsql;
CREATE TRIGGER keep_orders_updated_trigger AFTER INSERT OR UPDATE ON "slot" FOR EACH ROW EXECUTE PROCEDURE keep_orders_updated();
它在大多数情况下都会产生正确的结果,除了下面我正在尝试解决的情况。我们从以下数据开始:
Order:
order_id | earliest | latest
----------+------------------------
1 | 10 | 20
Slots:
slot_id | order_id | time_from | latest
----------+------------------------+------------------------
1 | 1 | 10 | 12
1 | 1 | 18 | 20
在两个并发事务中(在我的例子中,它们使用来自web服务器中连接池的不同连接运行,基本上服务于大约同时到达的两个请求):
tx1: UPDATE "slot" SET time_from=15 AND time_to=17;
tx2: UPDATE "slot" SET time_from=19 AND time_to=25;
我得到的插槽更新正确(预期),和顺序更新错误。仅最新更新:
Order:
order_id | earliest | latest
----------+------------------------
1 | 10 | 25
类似地,如果我将时间从设置为小于10的值,它会更新。
我想我明白为什么会这样。每个槽更新块位于相关行上,允许同时运行更新。触发器只看到其事务更新的数据,而不看到其他事务更新的数据。结果,它计算tx1的min(10,15)和tx2的min(10,19),并按相关顺序将earliest设置为10。
我的理解正确吗?如何使这样的配置正常工作?
1条答案
按热度按时间u3r8eeie1#
与其存储这些派生信息,为什么不创建一个视图呢?
使用这种技术,您不必担心实际维护数据。该视图为您的数据提供始终最新的透视图。