【问题标题】:Expressing data constraints in SQL在 SQL 中表达数据约束
【发布时间】:2009-02-02 15:14:52
【问题描述】:

我正在为我的妻子编写一个日程安排应用程序,我遇到了以下问题。

我有一个可以用 ActiveRecord 术语描述的架构:

  • 每个资源拥有并属于许多事件
  • 每个事件拥有并属于许多资源,并且有许多时间跨度
  • 每个timespan都属于一个event,并具有三个属性:daystart-time结束时间

我想对我的数据设置以下约束:

A. 对于每个 timespantimespan.start-time ≤ timespan.end-time B. 对于每个event,对于每个t_at_bTIMESPANS(event)t_a = t_bt_a.day ≠ t_b.dayt_a.end-time ≤ t_b.start-timet_a.start-time ≥ t_b.end-time C. 对于每个resource,对于每个e_ae_bEVENTS(resource)e_a = e_b 或者对于每个 t_aTIMESPANS(e_a)t_bTIMESPANS(e_b)t_a.day ≠ t_b.dayt_a.end-time ≤ t_b.start-timet_a.start-time ≥ t_b.end-time

(A) 确保时间跨度的格式正确,(B) 确保事件不会自我冲突,(C) 确保资源不会过度调度。

目前我在应用层执行这些约束,但是,为了自学,我想知道是否可以将这些约束放在数据库层。

有什么方法可以在 SQL 中表达这些约束?

编辑: 所以我发现我想要的是 SQL 的CREATE ASSERTION 语句(至少,对于那些简单的CHECK 无法涵盖的语句),但它似乎不像任何支持它的 RDBMS(at least, as of 2005 )

【问题讨论】:

  • 你在安排你的妻子? ;-)

标签: sql


【解决方案1】:

A 很容易在时间跨度表上用CHECK CONSTRAINT 表示,因为每一行都可以检查自身的一致性,而无需检查任何其他行。

B 和 C 更复杂,需要从其他表中读取信息。在这种情况下(至少在 SQL Server 中),可以使用用户定义的函数(将当前行中的值传递给它)来检查其他表,或者您可以使用 TRIGGER 来检查其他表。

注意:编写此类触发器时,请记住触发器会为 SQL 语句触发一次。如果该语句 INSERTs 或 UPDATEs 多行,INSERTED 表将包含多行,应使用适当的技术检查所有行以匹配您的域约束,例如 JOIN

顺便说一句:Joe Celko 最近收到了good article 约束。

【讨论】:

  • 谢谢!这很有帮助。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-04-11
  • 2017-12-23
  • 2014-01-26
  • 1970-01-01
  • 1970-01-01
  • 2013-05-21
  • 1970-01-01
相关资源
最近更新 更多