[英]What is the best way to update another table based on a certain condition ON UPDATE?
我有两个表subscription
和subscription_event
。 subscription_event
可以是以下类型之一:
public enum SubscriptionEventType {
CREATED,
CANCELED,
CHARGED_SUCCESSFULLY,
CHARGED_UNSUCCESSFULLY,
EXPIRED,
TRIAL_STARTED,
TRIAL_ENDED,
WENT_ACTIVE, // Subscription went active and can be charged from now on.
WENT_PAST_DUE;
public Long getValue() {
return this.ordinal() + 1L;
}
}
我想要做的是保持对最新事件的subscription
状态。 问题是:这些事件的顺序不正确。 例如,可以在CHARGED_SUCCESSFULLY
事件之前获得WENT_ACTIVE
事件。
因此,有几种方法可以实现我所需要的。 首先,我可以检查应用程序层中的条件,并始终根据事件的时间戳设置该“最新”状态。
Long subscriptionId = lastRecordedEvent.getSubscriptionId();
if(event.getTimestamp() > lastRecordedEvent.getTimestamp()) {
// Since the current event is more recent than all other events
// we also have to update the subscription state
subscriptionRepository.updateState(subscriptionId, event.getTimestamp());
}
但是,我不想在我的应用程序层中执行此操作。 另一个解决方案是在subscription_event
表上使用TRIGGER
,然后决定是否更新相关的subscription
。 我之所以不这样做,是因为我知道触发器很容易被遗忘,并且很难维护。 我也知道在使用TRIGGER
之前应该将所有其他选项都考虑在内,但是由于我不是SQL / MySQL专家,所以我不了解这里的所有选项。
那么在这种情况下使subscription
保持最新的最可行方法是什么?
像往常一样将事件插入表中,然后执行以下命令
UPDATE subscriptions set state=events.state
FROM subscriptions inner join events on subscriptions.id = events.subscriptionID
Where events.SubscriptionId = ? and events.Timestamp =
(select max(timestamp) from events where events.SubscriptionId = ?)
您将需要传递两个参数?
s为您刚刚插入的事件的订阅ID
编辑
一种替代方法是在数据库中没有状态字段,而是为您的订阅创建一个视图,然后始终查询该视图。
CREATE VIEW vw_subscriptions as
Select s.id, otherfields from subscription, coalesce(e.Status, 1) as status
from subscriptions s left outer join events e on s.id=e.subscriptionId
AND e.timestamp =
(select max(timestamp) from events where subscriptionId=s.id)
如果您担心忘记/维护SQL或触发器,请在存储库功能中将它们记录为注释,并将对数据库的所有更改作为与源代码一起存储的更改脚本进行维护。 这样,您所做的更改全部都在源代码控制中。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.