什么是 Key Preserved Table 概念?

par*_*and 12 oracle

我在更新连接视图部分中阅读了有关密钥保留表的 Oracle 文档。

但是,我没有找到任何简单的方法来理解它。

我希望收到一些简单的概念细节,而不是 Oracle 官方文档。

Jac*_*las 9

您已经阅读过的文档说得很好。进一步解释:

键保留表的概念是理解修改连接视图的限制的基础。

通常 anupdate作用于单个表。为了避免过滤器中出现曲折的子查询,Oracle 允许您update使用视图(或子查询),只要它仍然能够轻松地将您所做的更改映射到表中真实的底层行。如果该set子句仅修改“保留键”表中的列,则这是可能的:

如果表的每个键也可以是连接结果的键,则该表是键保留的。因此,保留键的表通过连接保留了它的键。

例如:

create table foo( foo_id integer primary key, foo_val integer not null );
create table bar( bar_id integer primary key, bar_val integer not null, 
                  foo_id integer not null references foo );

update (select * from foo join bar using(foo_id)) set foo_val=1;
ORA-01779: cannot modify a column which maps to a non key-preserved table

update (select * from foo join bar using(foo_id)) set bar_val=1;
0 rows updated.
Run Code Online (Sandbox Code Playgroud)

第一次更新失败,因为 Oraclefoo_val在查询中无法1:1 映射到foo_valin foo- 相反,第二次更新成功,因为 Oracle 可以 1:1 将每个映射bar_valbar_valin bar。重要的是foo_idin 是唯一的foo- 所以对于 in 的每一行,inbar中最多只能有一个对应的行foo(在这个例子中实际上正好是1,但同样适用于可为空的外键 - 重点是从来没有不止一排)。


Ati*_*gur 7

键保留意味着 1 个键值进入 1 个表。给出反例可以帮助你更好地理解这个概念。

示例 1:

您的视图包含聚合。假设您有以下视图结构。

GroupID, AverageSalary
1 , 10000
2, 12000
3, 14000
Run Code Online (Sandbox Code Playgroud)

在此示例中:您的值来自多个行。如果您尝试在此视图中更新 AverageSalary,数据库将无法找到要更新的行。

示例 2: 您的视图显示来自多个表的值。您的视图显示来自 PERSON 和 PERSON_CONTACT_DETAILS(ID,PersonID,ContactType,ContactValue) 表的值。

示例行:

 1,1,email,ddd@example.com
 1,1,phone,898-98-99
Run Code Online (Sandbox Code Playgroud)

您加入这个 2 表并在视图中显示更多业务友好信息。

人员 ID、姓名、姓氏、电话 1、电子邮件 1

在这里,您要更新 Phone1 和 Email1。但是你的 personID 映射到两个不同的行,在这个例子中可能是更多的行。在此视图中,数据库再次无法找到要更新的行。

注意:如果您限制查看 sql 并明确查找要更新的行,则它可能会起作用。

这两个例子是我想到的第一个例子。它们可以增加。但概念很明确。数据库需要将 1 个键值映射到 1 个表。例如,您有一对一的 PERSON、PERSON_DETAILS 表。在这里查看和更新​​将起作用,因为它是一对一的。