为什么DBMS不支持ASSERTION

for*_*all 28 sql database rdbms

所以我最近在我的数据库课程中学到了ASSERTION,而我的教授指出主要数据库不支持它,即使它是在SQL-92标准中.我试图谷歌搜索找出原因,但似乎没有任何关于该主题的讨论.

那么,为什么绝大多数关系数据库包都不支持ASSERTION呢?它是一个性能问题还是存在一些本质上难以解决的问题?


如果可以的话,请注意任何实现它的数据库包(例如:如果有学术/教学数据库).另外,为什么关于这个问题的讨论很少; 它甚至没有在维基百科页面中提到SQL或SQL-92)但是首先回答主要问题,或者在评论中回答.

不是在寻找如何使用触发器或其他任何东西来实现它.

one*_*hen 28

有四个级别的约束:列级,行级,表级和模式级.

例如,表级可以涉及除声明它之外的源表之外的目标表,但只有在源表更改时才会检查它.理论上,将检查模式中每个表中的每个更改的模式级约束,但实际上,优化器将能够以更精细的方式检测更改.因此,如果您的DBMS支持模式级约束,那么在实践中您不会发现表级约束的用处.

当前没有SQL产品支持模式级约束,即CREATE ASSERTION.显然,当它被DEC照看时,Rdb确实支持它但不再是这种情况.- 更新:在私人消息中,我被告知Sybase的SQL Anywhere支持CREATE ASSERTION但有严重错误,有时会违反这些约束!

我使用的唯一类似SQL的产品目前支持CHECK约束中的子查询,它支持表级约束,是Access数据库引擎(ACE,Jet,等等).但它有问题.首先,不支持SQL-92功能(或等效功能)来推迟约束检查.其次,对每个受影响的行检查表级约束,而不是根据SQL-92标准的要求完成语句的完成.毋庸置疑,解决方法非常笨重,例如删除约束,这样做会锁定表,执行更新,重新创建约束.可以通过向所涉及的所有表添加相同约束来实现的模式级约束实际上是不可行的.

可能由于这些原因,访问团队从未Jet 4.0的初始公告之外公布其CHECK约束功能(例如,它仍然缺少Access帮助).总而言之,对于表内约束(例如,有效状态'历史'时态表中的顺序键),该功能运行良好,尤其是当您认为Access仅获得类似触发器的功能(尽管不是基于SQL)时年.

SQL当然有UNIQUE约束和引用完整性约束,当然是表级但这些都是特殊情况.因此,您将在"野外"遇到的所有约束将是列级或行级.

请注意MySQL,虽然CHECK()在SQL DDL中使用将解析没有错误,但它将没有任何效果.用户如何能够容忍没有任何CHECK约束的SQL产品超出我的范围!PostgreSQL有一个很好的约束模型,提示提示:)

那么为什么支持表间限制呢?一个原因必然是由于历史情况.正如@gbn正确识别(在并发标题下),Sybase/SQL Server SQL实现系列基于一个无法应对表间约束检查的模型,而且这种模型不会发生变化.

考虑另一种方式:如果你今天要创建一个SQL产品,你会包括CREATE ASSERTION吗?如果你这样做,你肯定还必须实现DEFERRABLE约束(即使多个赋值可以说是更好的模型).但是,如果您沿着构建"传统"优化器的路线前进,您将能够获得更多的研究和经验.也许你会发现对模式级约束没有商业需求(如果没有CHECK约束,MySQL无论如何都可以得到......)如果PostgreSQL不这样做,我认为没有人会这样做.

我认为真正的显示阻碍是大多数工业级产品已经开发了触发功能,允许用户编写任意复杂性的"约束"(还可以更多,例如发送电子邮件来讲述发生的事情).当然,它们是程序性的而不是声明性的,编码器必须做很多额外的工作,系统会用真正的约束来处理,并且性能往往不是那么大.但事实是,它们存在于今天的实际产品中,并为供应商提供了"免于入狱"的卡.如果客户没有为他们敲桌子,他们为什么要打扰实施有价值的功能呢?

关于学术/教学语言,正如@Damien_The_Unbeliever正确识别的那样,教程D CONSTRAINT总是"模式"级别,因此允许根据定义对任意复杂性进行全局约束.如果您希望使用此类功能设计自己的DBMS(!!),则应考虑在使用现有SQL DBMS进行存储时实现D规范,如Dataphor所做的那样.


一个问题一直困扰着我:鉴于现有的"工业强度"SQL DBMS支持触发器,为什么它们不能简单地将声明映射CREATE ASSERTION到触发器下?我一直怀疑答案是因为他们知道鉴于他们的传统技术,性能会令人震惊.

数据专业人员应用数学提供了一个更令人满意的答案作者:Lex de Haan,Toon Koppelaars,第11章.它们定义了在使用触发器来强制执行多元组约束时要使用的各种执行模型.最复杂(但仍然非常可行)的模型,他们称之为EM6,涉及以下步骤:

  1. 将形式规范转换为约束验证查询.
  2. 开发代码以保持过渡效果.
  3. 设计过渡效果(TE)查询,确保仅在必要时运行约束验证查询[例如,我可以将检查限制为仅更新的行吗?DELETE是否会违反此约束?是否只有UPDATE必须涉及的特定列才能要求检查约束?等等]
  4. 通过让TE查询提供可在验证查询中使用的值,发现优化约束验证查询的方法.
  5. 为数据完整性(DI)代码设计并添加序列化策略.[即解决交易无法读取另一个交易正在编写的'坏'数据的并发问题].

然后他们断言(没有双关语!):

因为我们认为DBMS供应商不可能编程接受任意复杂谓词的算法,然后计算有效的转换效果(TE)查询,最小的验证查询和实现执行模型EM6的最佳序列化代码,我们应该不希望未来可以从这些供应商那里以实用,可用和可接受的方式全面支持多元组约束.我们所能期望的最好的是数据库研究人员首先提出了更常见的约束类,并为这些约束开发了方便的缩写.反过来,DBMS供应商应该为我们提供与这些简介一致的新的声明性构造,以便轻松地向DBMS陈述这些常见的约束类.鉴于这样一个通用的类声明,DBMS供应商应该能够编写一个算法,为我们提供类似EM6的执行模型,以实现约束.

一种这样的通用类数据库约束是外键,当然已经广泛实现了.

  • MySQL 8.0.16终于实现了CHECK约束:https://dev.mysql.com/doc/refman/8.0/en/create-table-check-constraints.html (2认同)

归档时间:

查看次数:

8169 次

最近记录:

7 年,8 月 前