《视图更新与关系数据库理论》——1.3 仅限基表:补偿性操作

1.3 仅限基表:补偿性操作

现在,为了确保之前章节提到的约束在后续的某些特定更新升级完成后依然有效,就需要进行相应的补偿性操作。通常情况下,补偿性操作也称为补偿操作,是一种由数据库管理系统自动执行的额外更新(不包括用户自行请求的更新),其目的就是为了避免完整性冲突的发生[5]。级联删除就是一个典型的例子[6]。事实上,有一点我们要明确,对于现在手上这个例子来说,我们很需要在进行DELETE操作时应用级联方式。具体来说,不管是从表LS,还是表NLS中,删除数据都需要级联以使得表S中相同的数据行也能够被删除。于是我们可以设想一些补偿性操作,其实就是级联删除规则,观察以下伪代码。

ON DELETE d FROM LS : DELETE d FROM S ;

ON DELETE d FROM NLS : DELETE d FROM S ;

同样,从表S中删除行也需要级联以使表LS或表NLS中同样的行一并被删除。

ON DELETE d FROM S : DELETE ( d WHERE CITY = ‘London’ ) FROM LS ,
                         DELETE ( d WHERE CITY <> ‘London’ ) FROM NLS ;

这里我要特别提醒的是,任何想对并不存在的行进行删除的尝试都是无效的,因此我们可以将圆括号内的表达式直接替换为d。不过从定义方式的角度来讲,圆括号内的定义表达方式更好,因为它们对变量的定义更加具体明确。

类似地,我们也需要为INSERT操作设定补偿性操作,即级联插入规则。

ON INSERT i INTO LS : INSERT i INTO S ;
ON INSERT i INTO NLS : INSERT i INTO S ;
ON INSERT i INTO S : INSERT ( i WHERE CITY = ‘London’ ) INTO LS ,
                         INSERT ( i WHERE CITY <> ‘London’ ) INTO NLS ;
 ```  

当然,级联插入的概念并不经常与外键约束联系在一起,但这个概念并没有问题。重要的是我们要认清补偿性操作并不总是以简单级联的形式出现。我们在本章中所讨论的仅仅是个简单的例子,以便大家理解概念,在实际工作中则需要根据具体情况来应用各种更复杂的形式,在后面的章节我们也会有一些案例给大家展示。
在当前的范例中,UPDATE操作可以被看作DELETE和INSERT的结合。因此,简单地说,对本范例的必要的补偿性操作就是对DELETE和INSERT操作规则设定的总和。例如,考虑下面表S上面的UPDATE操作。
```javascript
UPDATE S
SET        CITY = ‘Oslo’
WHERE   SNO = ‘S1’ ;

产生的结果如下。

1.表S中供应商S1现有的行被删除,CITY值为Oslo的新行被插入到这个表中。

2.表LS中供应商S1现有的行同样被删除,这是因为从表S到表LS的级联删除规则。同时因为CITY值为OSlo,这个供应商的新行被插入到表NLS,这次则是应用了级联插入规则。换句话说,供应商S1的行从表LS迁移到了表NLS(当然,这只是笼统来看)。

现在我们假设原来的UPDATE操作是在表LS中执行,而不是在表S中执行的。

UPDATE LS
SET        CITY = ‘Oslo’
WHERE   SNO = ‘S1’ ;

产生的结果如下。

1.供应商S1现有的行从表LS中删除。

2.尝试向表LS插入供应商为S1的新行,CITY值为Oslo。但是该尝试会失败,因为它违反了表LS中CITY值必须为London的约束。因此这次UPDATE操作整体失败,之前已经完成的步骤(在表LS中删除供应商S1的行)被撤销,最后的结果就是数据库保持不变。

时间: 2024-08-04 06:41:48

《视图更新与关系数据库理论》——1.3 仅限基表:补偿性操作的相关文章

《视图更新与关系数据库理论》导读

前言 视图更新与关系数据库理论本书是这个系列的第3本书,它的两位"前辈"是: <SQL and Relational Theory: How to Write Accurate SQL Code>(第2版) <Database Design and Relational Theory: Normal Forms and All That Jazz> 以上两本书于2012年由O'Reilly出版发行.第1本书的目标读者是所有种类数据库的从业人员,书中解释了关系理论

《视图更新与关系数据库理论》——第2章 技术背景

第2章 技术背景 视图更新与关系数据库理论适合我的一切也应该能适合你. --Walt Whitman<Leaves of Grass>(1885) 上一章的讨论是基于SQL的,因为大家对它都很熟悉.但实际上很可惜,SQL并不适合作为这种探究的基础,也无法满足目前手上课题对细节技术讨论的要求.一方面来讲,我们需要检验的概念很多时候完全无法用SQL语句表达:从另一方面来看,即使是可以表达的时候,SQL通常也会引入一大堆与之毫无关系而又没有必要的复杂内容,很容易使人一叶障目,不见森林.由于以上原因,

《视图更新与关系数据库理论》——第1章 抛砖引玉

第1章 抛砖引玉视图更新与关系数据库理论身教胜于言教. --Samuel Johnson<Rasselas>(1759) 本书中所涉及的大多数范例都是基于我们耳熟能详的(可别说是老掉牙的)"供应商与零部件"数据库而来的.我为再一次把这个老生常谈的例子拿出来表示歉意,但正如我在其他地方所说,我认为在各种不同的出版物上使用同样的例子对于学习而言是有利无害的.就SQL来说[1],数据库包含3张表,更确切地说,是3张基表,分别称为供应商表S("suppliers"

《视图更新与关系数据库理论》——1.6 小结

1.6 小结 抛砖引玉到此就要告一段落了.我们所用到的这个例子非常简单,从中得出的结论也是显而易见的.而其实我是想通过这个例子引出下面的理念,就是根据实际的定义把视图看作与特定的表相附生的基表,这对于整体考虑如何解决视图更新的问题是很有建设性的.我认为它不仅具有建设性,而且是一种"逻辑上正确"的方法.[8]总体思路如下. 1.视图定义表达式包含了某些特定的约束.例如,视图LS("London suppliers")的视图定义表达式表明了LS等同于表S中CITY值为L

《视图更新与关系数据库理论》——1.4 视图:约束和补偿性操作

1.4 视图:约束和补偿性操作 现在我要开始讨论本章的核心概念.如果前面两段中所涉及的表中有一部分或者全部都是视图的话,那么我们讨论的所有结论依旧成立,没有改变.例如,像之前一样,假设S是表,LS和NLS是视图. CREATE TABLE S ( .............. , UNIQUE ( SNO ) ) ; CREATE VIEW LS AS ( SELECT ... WHERE CITY = 'London' ) ; CREATE VIEW NLS AS ( SELECT ... W

《视图更新与关系数据库理论》——2.3 一致性约束

2.3 一致性约束 每个关系变量都受制于一系列一致性约束,我们也可以把它们简称为约束.首先,我们在"关系和关系变量"这一节中已经知道,任何一个给定的关系变量都被约束为一个确定的类型(具体来说,是一个确定的关系类型),也就是说,在定义关系变量的时候,这个类型也就确定了.例如,我们再来看看供应商关系变量S的定义.11[11] VAR S BASE RELATION { SNO CHAR , SNAME CHAR , STATUS INTEGER , CITY CHAR } KEY { SN

《视图更新与关系数据库理论》——1.5 规则至上

1.5 规则至上 现在我们假设用户只能看到视图LS(而不是视图NLS和基表S).可以想见这个用户仍然希望可以将视图LS当作基表一样操作.当然,这个用户知道表的语义. LS:供应商SNO是已经签约的,名称为SNAME,状态值为STATUS且位于城市CITY中(London). 并且了解如下约束. {SNO}是LS的键. LS中的每一行CITY值为London. 很明显,这个用户无法向这个表插入新行,也不能更新表中的供应商编码,因为这样的操作很可能违反约束规则,而用户并不知道这些约束(必须不知道)[

《视图更新与关系数据库理论》——2.2 关系赋值

2.2 关系赋值 Tutorial D中的关系赋值语法,不是像INSERT或DELETE一样的缩写,而是使用如下的通用格式. R := rx 在这里"R"是一个关系变量(从语法上来说,其实就是一个关系变量的名字),"rx"是一个关系表达式,表示关系"r"和关系变量"R"是同一类型的.现在显而易见的是(这里要感谢David McGoveran的观察)任何这类赋值都在逻辑上等价于下列格式之一. R := ( r MINUS d )

《视图更新与关系数据库理论》——2.1 关系和关系变量

2.1 关系和关系变量 每一个关系都有一个"关系头"和一个"关系体",其中关系头是一系列状态和特征,而关系体则是符合关系头的一系列数组.让我们再次使用"供应商与零部件"数据库(如图2.1所示,与第1章的图1.1完全一样),供应商关系的关系头是{SNO CHAR, SNAME CHAR, STATUS INTEGER, CITY CHAR}的集合,我们假设在这里确定属性SNO.SNAME.STATUS和CITY分别被定义为CHAR.CHAR.INT