我正在为我的妻子编写一份日程安排申请表,我遇到了以下问题。
我有一个可以用ActiveRecord术语描述的模式:
我想对我的数据设置以下限制:
A. For each timespan, timespan.start-time ≤ timespan.end-time B. For each event, for each t_a, t_b ∈ TIMESPANS(event), either t_a = t_b or t_a.day ≠ t_b.day or t_a.end-time ≤ t_b.start-time or t_a.start-time ≥ t_b.end-time C. For each resource, for each e_a, e_b ∈ EVENTS(resource), either e_a = e_b or for each t_a ∈ TIMESPANS(e_a) and t_b ∈ TIMESPANS(e_b), either t_a.day ≠ t_b.day or t_a.end-time ≤ t_b.start-time or t_a.start-time ≥ t_b.end-time
(A)确保时间跨度良好,(B)确保事件不会发生自我冲突,(C)确保资源不会过度安排。
目前我正在应用层执行这些约束,但为了自学,我想知道是否可以将这些约束放在数据库层中。
我有什么方法可以在SQL中表达这些约束吗?
修改
所以我发现我想要的是SQL的CREATE ASSERTION
语句(至少,对于那些简单的CHECK
无法涵盖的语句),但它似乎不像任何支持它的RDBMS (at least, as of 2005)
答案 0 :(得分:2)
A很容易用时间表上的CHECK CONSTRAINT
表示,因为每行都可以检查自身的一致性而不检查任何其他行。
B和C更复杂,需要从其他表中读取信息。在这种情况下(至少在SQL Server中),可以使用用户定义的函数(从当前行传递值)来检查其他表,或者可以使用TRIGGER
来检查其他表表。
注意:在编写这样的触发器时,请记住触发器会为SQL语句触发一次。如果该语句INSERT
或UPDATE
多行,则INSERTED
表将包含多行,应使用适当的技术检查所有行以匹配您的域约束,例如{{ 1}}。
BTW:Joe Celko最近有good article个约束。