我有两张表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());
}
但是,我不希望在我的应用程序层中执行此操作。另一种解决方案是在TRIGGER
表上使用subscription_event
,然后决定是否更新相关的subscription
。我之所以不这么做的原因是因为我知道触发器很容易被遗忘,也很难维持。另外我知道在使用TRIGGER
之前应考虑其他所有选项,但由于我不是SQL / MySQL专家,所以我不知道我的所有选择。
那么在这种情况下保持subscription
最新的最实用方法是什么?
答案 0 :(得分:1)
将您的活动照常插入表中,然后执行以下
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 = ?)
您需要将两个?
的参数传递为刚刚插入的事件的订阅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或触发器,请将它们记录为存储库函数中的注释,并将对数据库的所有更改作为与源代码一起存储的更改脚本进行维护。这样你的更改就在你的源代码控制中。