知识卡片

数据库约束的分类:元组约束与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那样好用。