Sql 为什么不';t数据库管理系统&x27;s的支持断言

Sql 为什么不';t数据库管理系统&x27;s的支持断言,sql,rdbms,database,Sql,Rdbms,Database,因此,我最近在数据库课程中学习了断言,我的教授指出,主要数据库不支持断言,即使它是在SQL-92标准中。我试图通过谷歌搜索找出原因,但似乎没有任何关于这个话题的讨论 那么,为什么绝大多数关系数据库包都不支持断言呢?这仅仅是一个性能问题,还是有一些本质上的困难 如果可以,请注意实现它的任何数据库包(例如:如果有学术/教学数据库)。还有,为什么关于这个问题的讨论如此之少;它甚至没有在维基百科的SQL或SQL-92页面中提到,但先回答主要问题,或者在评论中回答 我不是在寻找如何使用触发器或其他任何东

因此,我最近在数据库课程中学习了断言,我的教授指出,主要数据库不支持断言,即使它是在SQL-92标准中。我试图通过谷歌搜索找出原因,但似乎没有任何关于这个话题的讨论

那么,为什么绝大多数关系数据库包都不支持断言呢?这仅仅是一个性能问题,还是有一些本质上的困难



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


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

Oracle 10g中有一些基本的支持:

我敢肯定,其他具有存储过程支持的RDBMS都有类似的内置过程。。。显然,这不是任何SQL标准的一部分。该标准确实规定了:

<assertion definition> ::=
          CREATE ASSERTION <constraint name> <assertion check>
          [ <constraint attributes> ]

<assertion check> ::=
          CHECK <left paren> <search condition> <right paren>


我不确定
createassertion
语句。到目前为止,我还没有在任何RDBMS中遇到过它,而且我认为没有多少RDBMS真正实现了这一点。另一方面,单个表列上的
CHECK
子句也可以被视为断言。

是的,几个月前我在课堂上向我的老师问了这个问题。它可能在标准中,但许多DBMS供应商根本不遵守标准

DBMS不支持断言的原因可能是,这是一个非常昂贵的操作,因此没有人会使用它

为了提供一种方便的方法,DBMS实现了
TRIGGER
s和
CHECK
s。通过这种方式,没有人真正需要断言。

我的2便士:

  • 并发性:如果您采用SQL Server的“使用标量udf和表访问的检查约束”解决方案,那么它就是不安全的。在Sybase/SQL Server类型的引擎中,断言可能是相同的
编辑:我的意思在以下链接中描述:和

  • 性能:一个10k行插入需要10k udf样式的执行,每个执行都具有表访问权限。哎哟假设断言是每行的,那么这就是它的操作方式。如果它可以用于“插入中的所有行”,那么它作为触发器就更简单了,不是吗

  • 设计:有一些模式(超键、子类型表等)可以使用更简单的约束来维护相关表上的数据完整性。如果你需要检查一些随机表的数据完整性,我会说你有什么错误


(非SQL,通常被认为是学术性的,不称为断言)(又名教程D)具有约束,该约束可以是数据库上的任意约束。一个实现称为

约束有四个级别:列级别、行级别、表级别和模式级别

例如,表级别可能涉及一个目标表,而不是声明它的源表,但只有在源表更改时才会进行检查。理论上,模式级约束将针对模式中每个表中的每个更改进行检查,但在实践中,优化器将能够以更细粒度的方式检测更改;因此,如果您的DBMS支持模式级约束,那么在实践中您将不会发现表级约束有多大用处

当前的SQL产品都不支持模式级约束,即
创建断言
。显然,在DEC对其进行管理时,它确实支持了该计划,但现在情况已不是这样了更新:在一条私人消息中,我被告知Sybase的SQL Anywhere支持
创建断言
,但存在严重错误,有时会违反此类约束

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

可能由于这些原因,访问团队从未公开其
检查
约束功能(例如,访问帮助中仍然缺少该功能)。尽管如此,对于表内约束(例如,在一个有效状态的“历史”时态表中的顺序键),该功能运行良好,尤其是当您认为Access去年只得到触发器式功能(而不是基于SQL的)时,

SQL当然有
UNIQUE
约束和引用完整性约束,这些约束当然是表级别的,但它们是特殊情况。因此,“在野外”遇到的所有约束都是列级或行级约束

使用MySQL时一定要注意,尽管在SQL DDL中使用
CHECK()
可以正确解析,但不会产生任何效果。我无法理解用户如何能够容忍一个SQL产品完全没有任何
CHECK
约束!PostgreSQL有一个很好的约束模型,提示:)

那么,为什么表间约束很少得到支持呢?一个原因必须是历史环境造成的。正如@gbn正确指出的那样(在标题“并发性”下),Sybase/SQL Server系列SQL实现基于一个无法处理表间约束检查的模型,而且这种模型永远不会改变

考虑从另一个角度来看: