由于CHECK约束不能基于查询,因此有三种基本方法可以解决此类问题。
最简单的方法是在TANK上放置一个触发器,以查询TANKS并在LEVEL超过CAPACITY时引发异常。但是,这种简单化方法的问题在于,几乎不可能正确处理并发问题。如果会话1降低了容量,则会话2增加了LEVEL,然后两个事务都提交,触发器将无法检测到违规。如果很少修改一个或两个表,这可能不是问题,但总的来说,这将是一个问题。
您可以通过创建连接TANK和TANKS表的ON COMMIT实例化视图,然后在该实例化视图上创建一个CHECK约束来验证LEVEL <= CAPACITY来解决并发问题。您还可以通过使实例化视图仅包含违反约束的数据来避免将数据存储两次。这将需要两个基表上的物化视图日志,这将增加插入的开销(尽管比使用触发器要少)。将检查推送到提交时间将解决并发问题,但由于COMMIT操作现在可能由于物化视图刷新失败而失败,因此引入了一些异常管理问题。您的应用程序需要能够处理该问题并向用户发出警告。
如果表A中的值取决于表B中的限制,则可能表明表B中的限制应为表A的属性(而不是表B的属性或除了表B的属性外)。当然,这取决于数据模型的细节,但是通常值得考虑。