Kingbase-高级特性2-外键&事务

外键
确保在 cities 表中有相应项之前任何人都不能在 weather 表中插入行,叫做维持数据的引用完整性。
在过分简化的数据库系统中,可以通过检查 cities 表中是否有匹配的记录存在,然后决定应该接受还是
拒绝即将插入 weather 表的行。这种方法存在一些问题且并不方便,于是 KingbaseES 提出新的解决方案:
新的表定义如下:
CREATE TABLE cities (
city varchar( 80 ) primary key,
location point
);
CREATE TABLE weather (
city
varchar( 80 ) references cities(city),
temp_lo
int ,
temp_hi
int ,
prcp
real,
date
date
);
尝试插入一个非法的记录:
INSERT INTO weather VALUES ( 'Berkeley' , 45 , 53 , 0.0 , '1994-11-28' );
ERROR: insert or update on table "weather" violates foreign key constraint
"weather_city_fkey"
DETAIL: Key (city)=(Berkeley) is not present in table "cities".
外键的行为可以很好地根据应用来调整。可参考 数据定义 中相关信息。正确使用外键将提高数据库的应用
质量,建议用户熟练掌握外键的使用。
事务
事务是指访问并可能更新数据库中各种数据项的一个程序执行单元。在关系数据库中,一个事务可以是一条
SQL 语句,一组 SQL 语句或整个程序。它将多个步骤捆绑成了一个单一的、要么全完成要么全不完成的操
作。步骤之间的中间状态对于其他并发事务是不可见的,如果产生错误导致事务不能完成,则其中任何一个
步骤都不会对数据库造成实质影响。
在一个保存着多个客户账户余额和支行总存款额的银行数据库中。如需记录一笔从 Alice 的账户到 Bob 的账
户的额度为 100.00 美元的转账, SQL 命令为:
UPDATE accounts SET balance = balance - 100.00
WHERE name = 'Alice' ;
UPDATE branches SET balance = balance - 100.00
(continues on next page)
(continued from previous page)
WHERE name = (SELECT branch_name FROM accounts WHERE name = 'Alice' );
UPDATE accounts SET balance = balance + 100.00
WHERE name = 'Bob' ;
UPDATE branches SET balance = balance + 100.00
WHERE name = (SELECT branch_name FROM accounts WHERE name = 'Bob' );
在上述操作涉及到对数据库的多个独立更新,银行职员希望确保这些更新要么全部发生,或者全部不发生。
不能出现由于系统错误导致 Bob 收到 100 美元而 Alice 并未被扣款的情况,或者 Alice 被扣款而 Bob 未收到
转账的情况。因此,需要保证在操作中途发生错误时,已经执行的步骤不会产生效果。这就是事务的原子性
(一个事务是一个不可分割的工作单位,事务中包括的诸操作要么都做,要么都不做)。
银行职员同样希望能保证一旦一个事务被数据库系统完成并认可,它就被永久地记录下来且即便其后发生崩
溃也不会被丢失。例如,需要永久保留 Bob 的现金提款记录。
一个事务内部的操作及使用的数据对并发的其他事务是隔离的,并发执行的各个事务之间不能互相干扰。当
多个事务并发运行时,每一个事务都不能看到其他事务未完成的修改。例如,如果一个事务为统计所有支行
的余额,它不会只包括 Alice 的支行的扣款而不包括 Bob 的支行的存款,或者反之。所以事务的全做或全不
做并不只体现在它们对数据库的持久影响,也体现在它们发生时的可见性。一个事务所做的更新在它完成之
前对于其他事务是不可见的,而之后所有的更新将同时变得可见。
KingbaseES 中,使用 SQL 命令 BEGIN COMMIT 开启一个事务:
BEGIN;
UPDATE accounts SET balance = balance - 100.00
WHERE name = 'Alice' ;
-- etc etc
COMMIT;
在事务执行中若不想提交(若 Alice 的余额不足),可以以 ROLLBACK 命令代替 COMMIT 命令,当前的更新
即被取消。
实际上, KingbaseES 将每一个 SQL 语句都作为一个事务来执行。如果未发出 BEGIN 命令,则每个独立的语
句都会被加上一个隐式的 BEGIN 以及 COMMIT 。一组被 BEGIN COMMIT 包围的语句也被称为一个事
务块。
Note: 由于某些客户端库会自动发出 BEGIN COMMIT 命令,因此可能会在不被告知的情况下得到事务
块的效果。具体情况请查看对应接口文档。
可以利用保存点来以更细的粒度控制事务中的语句。保存点允许有选择性地放弃事务的一部分而提交剩下的
部分。使用 SAVEPOINT 定义一个保存点后,可以在必要时利用 ROLLBACK TO 回滚到该保存点。该事务
中位于保存点和回滚点之间的数据库修改都会被放弃,但是早于该保存点的修改则会被保存。
在回滚到保存点之后,它的定义依然存在,因此可以多次回滚到它。反之,如果确定不再需要回滚到特定的
保存点,它可以被释放以便系统释放一些资源。不管是释放保存点还是回滚到保存点都会释放定义在该保存
点之前的所有其他保存点。
由于上述操作发生在一个事务块内,因此这些操作对于其他数据库会话来说都不可见。当提交整个事务块
时,被提交的动作将作为一个单元变得对其他会话可见,而被回滚的动作则永远不会变得可见。
在银行数据库中,假设从 Alice 的账户扣款 100 美元,然后存款到 Bob 的账户,但直至最终才发现应该存在
Wally 的账户中。可以通过使用保存点来做这件事:
BEGIN;
UPDATE accounts SET balance = balance - 100.00
WHERE name = 'Alice' ;
SAVEPOINT my_savepoint;
(continues on next page)
(continued from previous page)
UPDATE accounts SET balance = balance + 100.00
WHERE name = 'Bob' ;
-- oops ... forget that and use Wally 's account
ROLLBACK TO my_savepoint;
UPDATE accounts SET balance = balance + 100.00
WHERE name = 'Wally' ;
COMMIT;
ROLLBACK TO 是重新控制一个由于错误被系统置为中断状态的事务块的唯一的途径,而不是完全回滚它并
重新启动
  • 16
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值