PostgreSQL 9.3新特性:多列ON UPDATE行为改变

需积分: 9 0 下载量 157 浏览量 更新于2024-07-17 收藏 5.98MB PDF 举报
"这篇文章是关于PostgreSQL 9.3版本的新特性提取,由Digoal.zhou在2013年的PostgreSQL中国会议上分享。主要介绍了多列ON UPDATE SET NULL/SET DEFAULT外键行为的改变,以及如何在psql环境下进行相关操作的示例。" 在PostgreSQL 9.3版本中,一个显著的新特性是对多列外键约束的`ON UPDATE SET NULL`和`ON UPDATE SET DEFAULT`行为进行了调整。在此之前,当执行`UPDATE`语句时,外键更新仅会影响与被更新列相对应的引用列。但根据更现代的SQL标准,这种行为已经发生了变化。 以前,如果有一个包含多个列的外键约束,只有那些在`UPDATE`语句中实际被修改的列的引用会被设置为`NULL`或使用默认值。例如,假设我们有两张表`a`和`b`,`b`表是主键,`a`表有一个引用`b`表的外键。如果`b`表的`c1`和`c2`两列构成主键,`a`表也有对应的外键约束,并且设置了`ON UPDATE SET NULL`,那么当更新`b`表的`c1`列时,只有`a`表中对应的`c1`列会变为`NULL`,而`c2`列保持不变。这是符合SQL-92标准的行为。 然而,在PostgreSQL 9.3版本之后,遵循了更近的SQL标准,当执行`UPDATE`语句影响到多列外键的一部分时,所有受该外键约束的列都会受到影响。这意味着如果`b`表的`c1`列被更新,即使`c2`列没有被显式更新,`a`表中与`b`表对应的`c1`和`c2`两列都会被设置为`NULL`。 以下是在psql环境中演示这个新特性的示例: 首先创建两个表`b`和`a`,`b`表为主键表,`a`表为外键表: ``` digoal=# create table b (c1 int, c2 int, c3 text, primary key (c1, c2)); digoal=# create table a (c1 int, c2 int, c3 text, foreign key (c1, c2) references b (c1, c2) on update set null); ``` 接着向两个表中插入数据: ``` digoal=# insert into b values (1, 2, 3); digoal=# insert into a values (1, 2, 3); ``` 然后尝试更新`b`表的`c1`列: ``` digoal=# update b set c1 = 2; ``` 在旧的行为中,`a`表中的`c1`列会被设为`NULL`,但`c2`列保持不变。然而在新版本中,`a`表的`c1`和`c2`两列都会被设为`NULL`: ``` digoal=# select * from a; c1 | c2 | c3 ---+----+----- | | 2 | 3 ``` 同样,如果使用`ON UPDATE SET DEFAULT`,所有受影响的列都会用其各自的默认值替换,而不仅仅是被`UPDATE`语句更改的列。 这个新特性使得开发者在处理多列外键时可以更加灵活,同时也更符合SQL标准的最新规定,提高了数据库的一致性和完整性。在升级到PostgreSQL 9.3后,需要注意这个变更可能对已有的应用程序逻辑产生的影响。