我的数据库中有近300万条金融交易记录。这些记录是从包含以下字段的外部文件加载的,这些字段映射到表的列。
Account, Date, Amount, Particulars/Description/Details/Narration
现在需要保持已加载和未来记录的唯一性。
由于已经加载的外部文件没有唯一性,我认为,我们必须通过使用给定字段创建唯一键来更新现有记录,但是,很明显外部文件中的字段可能会重复。 / p>
如何保持我们可以识别文件中的事务的唯一性已加载。欢迎所有类型的建议。
修改1
目前已加载的记录已确认有效,由于从旧文件或丢失的文件中加载了一些丢失的记录,因此需要保持唯一性
修改2
现有记录可能具有基于给定4个字段的重复记录,即两个或更多有效交易的账户,日期,金额和详细信息的相同值,但是即使具有重复值,也确保这些记录有效。
现在要加载丢失的记录,我们需要确定是否已加载记录,以便我们不加载已加载的记录。所以,对我来说,看起来很难知道是否已根据这些字段加载了记录。我认为它超出了这些领域的限制
编辑3
现在情况发生了变化,这不再是一个有效的问题,但最好还是留在其他地方。已同意在记录中添加唯一密钥,因此检查此密钥是否有重复
答案 0 :(得分:1)
注意 - 根据OP的一些说明,这个答案与他们的情景无关。问题是政治或商业问题而不是技术问题。我将这个答案留作一个假设性问题的解决方案,因为它可能对未来的一些寻求者仍然有用。
My other response解决OP的实际情况。
您似乎需要复合唯一键:
alter table your_table add constraint your_table_uk
unique (Account, Date, Amount, Particulars)
using index
particulars
似乎有点愚蠢作为唯一性的来源,但可能一个帐户在任何一天都可以有相同数量的多个交易,因此您需要所有四列来保证该行的唯一性。
或者,正如@ypercube建议的那样,只需要(Account, Date, Particulars)
。
我建议使用唯一键而不是主键约束,因为复合主键在强制执行外键时是个坏消息。在这种情况下,我建议你添加一个合成主键,填充序列。
您说加载的记录具有经过验证的有效性,但如果不是这种情况,请更改ALTER TABLE语句以使用EXCEPTIONS INTO子句查找重复的行。您将获得一个特殊的表来捕获约束违规。 Find out more。
答案 1 :(得分:1)
“现有记录可能具有基于给定4个字段的重复记录 即两个或两个账户,日期,金额和详情的相同值 更有效的交易,但可以肯定这些记录是有效的 即使有重复的值。“
但是,如果加载的数据或源文件中没有唯一性标记,那么怎么能告诉谁?有效性甚至意味着什么?
“现在要加载丢失的记录,我们需要确定记录是否存在 已加载或未加载,以便我们不加载已经存在的记录 装“。
如果没有现有的唯一性来源,则无法执行此操作。因为对于(Account, Date, Amount, Particulars)
的给定组合,你有两行,这没关系,确定(帐户,日期,金额,详细信息)的第三个实例是已经加载的记录的规则是什么,因此无效,或未加载的记录,因此有效。
“所以,对我来说,看起来很难知道记录是否已经加载 基于这些领域。我认为它超出了这些领域的限制“
您说的是,在您描述的数据中无法找到解决方案。但解决方案实际上非常简单。您将找到已声明已加载记录有效性的人员,并向他们提供这些附加记录的列表。他们将能够利用他们的技能和判断力来告诉您哪些记录是有效的,然后加载这些记录。
“我有责任找到解决方案”
不,这不是你的职责。现在,责任在于数据所有者的肩膀,以准确地定义他们的数据集,并且包括识别业务密钥。他们是废除责任的人。
在这种情况下,您有三种选择:
NOVALIDATE是一种为未来行强制执行验证规则但忽略现有数据中的违规行为的方法。基本上它是解决政治问题的技术手段。
SQL> select * from t23
/
COL1 COL2
---------- --------------------
1 MR KNOX
1 MR KNOX
2 FOX IN SOCKS
2 FOX IN SOCKS
SQL> create index t23_idx on t23(col1,col2)
/
Index created.
SQL> alter table t23 add constraint t23_uk
unique (col1,col2) novalidate
/
Table altered.
SQL> insert into t23 values (2, 'FOX IN SOCKS')
/
insert into t23 values (2, 'FOX IN SOCKS')
*
ERROR at line 1:
ORA-00001: unique constraint (APC.T23_UK) violated
SQL>
请注意,您需要在添加约束之前预先创建非唯一索引。如果不这样做,数据库将构建一个唯一索引,并将覆盖NOVALIDATE子句。
我将NOVALIDATE描述为可怕,因为它是。它将数据损坏加入数据库。但这是你最接近解决方案的事情。
这种方法完全忽略了“有效性”的概念。因此它会拒绝可能应该加载的记录,因为它们代表(Account, Date, Amount, Particulars)
的“有效”第n次出现。这是不可避免的。好消息是,没有人能够说出来,因为没有明确的规则来确定有效性。
无论您选择哪种方式,都必须向您的老板,数据所有者,数据所有者的老板以及您认为合适的其他人清楚地解释,并获得他们的书面同意继续。否则,有时候人们会发现数据库中有重复的行,或者有人会抱怨没有加载“有效”记录,这都是你的错...除非你有一个签名的经适当的高级管理人员授权的纸张。
祝你好运Haki's suggestion of using MERGE与NOVALIDATE具有相同的效果,因为它会加载新记录并抑制所有重复项。然而,它更像是一种愚蠢的东西:它根本没有解决唯一性的概念。任何拥有INSERT或UPDATE访问权限的人仍然可以拥有他们喜欢的任何行。因此,只有在您可以完全锁定该表的权限以使其数据只能通过MERGE而不是其他DML进行操作时,此方法才有效。取决于持续的独特性是否重要。同样,一个商业决策。
答案 2 :(得分:0)
听起来你需要一个upsert - 或者oracle称之为MERGE
两个表之间的MERGE
操作允许您处理两种常见情况 -
记录已存在于目标表中,我需要这样做 与它有关 - 无论是更新还是什么都不做。
目标表中不存在记录 - 插入它。