知识卡片
数据库约束的分类:元组约束与AND聚集表述法
内容
数据库约束按能否被”隔离检查”(是否只需要看单个元组、不需要看同一关系变量的
其他元组或数据库里其他关系变量)分类:能隔离检查的叫元组约束(SQL里也叫行
约束),例如”供应商状态必须落在[1,100]“(约束CX1);不能隔离检查的例子如
“{SNO}是S的键”(约束CX3,需要横向比较S里所有元组才能判断唯一性),或者涉及
两个及以上关系变量的多关系变量约束(如CX5”状态低于20的供应商不能供应P6”,
横跨S和SP两个关系变量)。这里的”元组约束”称呼其实是一种历史遗留的不严谨说法
——[[更新是集合级别的运算]]中已确立关系理论范畴内根本不存在元组级别的更新,
因此严格说也不该有”元组约束”这种叫法,但因为它读起来顺口,书中承认自己也会
偶尔沿用这个不太严谨的术语。表达元组约束有一种比”限制后判空”更直接的写法:
用[[SQL聚集运算符的三重缺陷]]里提到的AND聚集运算符,比如CX1可以写成
AND(S,STATUS>=1 AND STATUS<=100),直接陈述”对S的每个元组该表达式都为真”,
比等价的、需要用否定形式表达的IS_EMPTY版本(”不存在状态越界的行”)更直观。
SQL里AND的类比是EVERY,但EVERY在参数为空时错误地返回null而非TRUE(呼应
[[SQL聚集运算符的三重缺陷]]),加上SQL的”聚集”本质上是被套了两层型转的表
(先型转成单行单列的表,再型转成里面那个标量),导致SQL版本的EVERY约束表述
需要套一层COALESCE、再和TRUE显式比较才能可靠工作,远不如Tutorial D的AND
版本干净。
参考来源
- 位置:《SQL与关系数据库理论——如何编写健壮的SQL代码》第8章"SQL与约束"
8.3节"数据库约束"(源文件:OEBPS/text00091.html)
- 结论依据:原文明确"此约束可以仅仅针对某个指定的供应商元组进行隔离检查,
并不需要考虑同一关系变量中的其他元组……这种约束有时也被通俗地称为元组
约束……元组约束可以交替地使用聚集运算符AND进行表述……EVERY在没有参数
的情况下返回null而不是TRUE,所以需要使用COALESCE……SQL中的EVERY对于行
约束的表述方式并不像Tutorial D中的AND对于元组约束的表述方式那样好用"。
- 原始内容:此约束可以仅仅针对某个指定的供应商元组进行隔离检查……这种约束
有时也被通俗地称为元组约束……元组约束可以交替地使用聚集运算符AND进行
表述……SQL中的EVERY对于行约束的表述方式并不像Tutorial D中的AND那样好用。