【问题标题】:Oracle - cannot create the desired foreign key constraintOracle - 无法创建所需的外键约束
【发布时间】:2013-12-11 16:52:39
【问题描述】:

假设以下 Oracle 表:

table master (
  name    number(18) not null,
  version number(5)  not null,
  constraint master_uq unique(name,version)
)

table child1 (
  master_name not null,
  ....
)

table child2 (
  master_name not null,
  ....
)
.
.
.
table childN (
  master_name not null,
  ....
)

childX 表中的 master_name 列是指主表名列。

规则是:

  • 保证主表中的每个名称都有一行 版本 = 1
  • 主表中的每个名称也可能有其他版本,即。 2,3 等
  • childX 表引用了名称,但对版本不特别感兴趣。

这意味着在每个表N中,可以在逻辑上为主表创建以下外键...

foreign key childX_fk(master_name,1) references master(name,version)

不幸的是,虽然childX中的外键引用master中唯一的列组合的Oracle规则得到了满足,但Oracle不喜欢childX_fk外键中的版本硬编码1值。

如果能够创建从各个子表到主表的外键,这对参照完整性来说非常有用,但我看不到实现这一点的方法。

有人可能有什么想法吗?

【问题讨论】:

  • 如果子表不关心版本,是否有理由将历史记录存储在master 表中,而不是填充单独的历史记录表(即master_history)?跨度>
  • 您缺少一个 master_master 表,其中 master_name 是唯一的
  • @Vincent - 谢谢,是的,通常我会选择以下内容:
  • @Vincent - 谢谢,是的,通常我会选择类似以下的内容:childN -> master
  • @Justin - 谢谢。我可能没有很好地解释,因为这与历史数据无关。这一切都非常流行。例如,任何时候查询都可能会说 select .... from childN c join master m on (m.name = c.master_name) where m.version =

标签: database oracle foreign-key-relationship


【解决方案1】:

您可以使用虚拟 Column 并使用它来引用 master:

create table child1 (
  name    number(18) not null,
  alwaysone number generated always as (case when name1 = name1 then 1 end) virtual,
  foreign key (name,alwaysone) references master(name,version)
);

【讨论】:

  • 感谢@Dieter,这是一种非常有趣的方法,而且肯定会奏效——无需物理存储冗余数据的开销。如果我没有“解决”这个问题,我已经将它作为我可能会采取的方法,但是由于它仍然会在表格中引入噪音,我的第一奖仍然是实现“外键(名称,1)引用的能力……”。也许有一天甲骨文会促进这一点! :o)
猜你喜欢
  • 2013-05-04
  • 2014-02-26
  • 1970-01-01
  • 1970-01-01
  • 2014-10-20
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多