触发器,断言和检查之间的区别是什么(在数据库中)

Am1*_*3zA 22 sql database triggers assertions

任何人都可以解释(或建议一个网站或论文)触发器,断言和检查之间的确切区别,还描述我应该在哪里使用它们吗?

编辑:我的意思是在数据库中,而不是在任何其他系统或编程语言.

jel*_*key 57

触发器 - 触发器是在数据库中更新,插入或删除之前或之后执行的一段SQL.简单英语触发器的示例可能类似于:在更新客户记录之前,保存当前记录的副本.看起来像这样:

CREATE TRIGGER triggerName
AFTER UPDATE
    INSERT INTO CustomerLog (blah, blah, blah)
    SELECT blah, blah, blah FROM deleted
Run Code Online (Sandbox Code Playgroud)

断言和检查之间的区别更加模糊,许多数据库甚至不支持断言.

检查约束 - 检查是一段SQL,它确保在对记录执行操作之前满足条件.简单来说,这就是:所有客户的账户余额必须至少为100美元.看起来像这样:

ALTER TABLE accounts 
ADD CONSTRAINT CK_minimumBalance
CHECK (balance >= 100)
Run Code Online (Sandbox Code Playgroud)

任何在balance列中插入小于100的值的尝试都会引发错误.

断言 - 断言是一段SQL,它确保满足条件或停止对数据库对象采取的操作.这可能意味着锁定整个表甚至整个数据库.

使问题更加混乱 - 可以使用触发器来强制执行检查约束,并且在某些DB中可以取代断言(通过允许您运行与正在修改的表无关的代码).初学者的一个常见错误是在需要触发时使用检查约束,或者在需要检查约束时使用触发器.

例如:所有开户的新客户必须有100美元的余额; 但是,一旦开立账户,其余额可能会低于该金额.在这种情况下,您必须使用触发器,因为您只希望在插入新记录时评估条件.


Erw*_*out 11

在SQL标准中,ASSERTIONS和CHECK CONSTRAINTS都是关系理论所称的"约束":数据库中实际包含的数据必须符合的规则.

两者之间的区别在于CHECK CONSTRAINTS在某种意义上更"简单":它们是仅与一行相关的规则,而ASSERTION可以包含任意数量的其他表,或者同一行中的任意数量的其他行表.这显然使DBMS构建者支持它(更多!)更复杂,反过来,他们之所以不这样做:他们只是不知道如何去做.

TRIGGER是可执行代码的一部分,可以向DBMS声明每次在某个表上完成某种更新操作(插入/删除/更新)时应该执行这些代码.因为触发器可以引发异常,所以它们是实现与ASSERTION相同的东西的手段.然而,对于触发器,它仍然是程序员必须完成所有编码,而不是犯任何错误.

编辑

Onedaywhen的评论重新开始.ASSERTION/CHECK cnstr.是正确的.差异更加微妙(令人困惑).该标准确实允许CHECK约束中的子查询.(大多数产品不支持它,所以我的"与单行相关"对大多数SQL产品都适用,但不适用于标准.)那么仍然存在差异吗?是的还有.不止一个.

第一种情况:TABLE MEN(ID:INTEGER)和TABLE WOMEN(ID:INTEGER).现在想象一个规则,即"在MEN和WOMEN表中都不会出现ID值".这是一条规则.ASSERTION的目的恰恰是数据库设计者会说出这个单一的规则[并且用它来完成],而DBMS将知道如何有效地处理这个问题,以及如何执行这个规则,无论具体是什么更新完成到数据库.在该示例中,DBMS将知道它必须在INSERT INTO MEN,INSERT INTO WOMEN,而不是DELETE FROM MEN/WOMEN或INSERT INTO <anyothertable>时检查此规则.

但DBMS并不够聪明,无法做到这一切.那么需要做些什么呢?数据库设计者必须向他的数据库添加两个CHECK约束,一个添加到MEN表(检查新插入的MEN ID对WOMEN表),一个添加到WOMAN表(反过来检查).这是你的第一个区别:一个规则,一个ASSERTION,两个 CHECK约束.CHECK约束是比ASSERTION更低的抽象级别,因为它们要求设计者更多地思考(a)可能导致他的ASSERTION被违反的所有类型的更新,以及(b)应该进行什么特定的检查他在(a)中找到的任何具体的"更新类型".(虽然我不喜欢对仍然是"什么"以及什么是"如何"做出"绝对"陈述,但我总结说,CHECK约束需要数据库设计者更多"如何"思考(程序性),而ASSERTIONs允许数据库设计者专注于"WHAT"(声明性).)

第二种情况(虽然我不完全确定这一点 - 所以需要一点点盐):只是你的平均RI规则.当然,您习惯使用一些REFERENCES子句来指定它.但想象一下REFERENCES条款不可用.像"每个ORDER必须由一个已知​​的CUSTOMER放置"之类的规则实际上只是一个规则,因此:单个ASSERTION.但是,我们都知道可以通过两种方式违反这样的规则:插入ORDER(在此示例中),并删除CUSTOMER.现在,根据前面的MAN/WOMEN示例,如果我们想要使用CHECK约束来实现这个单一规则/ ASSERTION,那么我们必须编写一个CHECK约束,在插入ORDER时检查CUSTOMER是否存在,但是CHECK约束可以我们写的是从CUSTOMER 删除所需的一切吗?据我所知,它们根本就不是为此目的而设计的.您的第二个区别是:CHECK约束仅与INSERT绑定,ASSERTIONS可以定义也将在DELETE上检查的规则.

第三种情况:想象一下表COMPOS(componentID:... percentage:INTEGER),以及"所有百分比之和必须始终等于100"的效果规则.这是一条规则,ASSERTION能够指定.但是试着想象一下如何使用CHECK约束强制执行这样的规则...如果你有一个有效的表,例如,三个非零行加上一百个,你将如何应用任何可以存活的表的更改你的CHECK约束?您无法删除或更新(减少)任何行,而无需添加其他替换行,或更新总计相同百分比的剩余行.同样地插入或更新(增加).你至少需要延迟约束检查,然后你要检查什么?第三个区别是:CHECK约束针对单个行,而ASSERTIONs也可以定义/表达"跨越"多行的规则(即关于行聚合的规则).


Moh*_*del 6

断言不会修改数据,它们只检查某些条件

触发器更强大,因为它可以检查条件并修改数据

-------------------------------------------------- ------------------------------

断言未链接到数据库中的特定表,也未链接到特定事件

触发器链接到特定表和特定事件