【发布时间】:2011-08-01 19:51:00
【问题描述】:
请在 Oracle 上考虑以下表结构:
create table DOCS
(
DOC_NO NUMBER not null,
DOC_TYPE VARCHAR2(5) not null,
PMT_NO NUMBER not null
);
在此表中,PMT_NO 列必须是唯一的,除非 DOC_NO 相同且 DOC_TYPE 不同:
DOC_NO DOC_TYPE PMT_NO
---------- -------- ----------
1 A 10 <-- good
1 B 10 <-- good, DOC_NO is the same
2 C 10 <-- NOT good, DOC_NO is different
PMT_NO 不能重复,也不能有“孔”(即 1、2、3、5),因此序列不起作用。并且有很多用户同时插入数据。
有没有办法为该条件创建唯一键/唯一索引/基于函数的索引?
谢谢!
【问题讨论】:
-
只是让你知道,不允许“漏洞”只是要求将来失败。没有任何充分的理由不允许空洞,然后序列将非常适合生成您的下一个 PMT_NO。即便如此,你并没有像@Randy 建议的那样被标准化;用 DOC_NO,DOC_TYPE 和 DOC_NO,PMT_NO 把它分成两个表,你的问题就消失了。
-
Randy 和 Kerri,谢谢你们的帮助!兰迪,我同意这没有正确规范化。但是,这是一个在整个系统中广泛使用的现有表,现在更改它会非常昂贵和危险。 Kerri,我们真的不能允许这个专栏有漏洞,这是我们系统中的基本业务规则。
-
另外,澄清一下,今天我们通过在提交之前查找重复值并更新它们来控制它。但这并不是 100% 有效的,我们需要在此之前强制执行表锁定,这会导致严重的性能问题。这就是为什么约束会是一个更好的选择。
-
@ricsmania 即使您保留此非规范化表,您仍然可以创建另一个正确规范化的链接表,并在更新此表时使用触发器插入到帽子。然后约束将进行检查,并防止不良记录...