0

我的数据库中有近 300 万条金融交易记录。这些记录是从包含映射到表列的以下字段的外部文件加载的。

Account, Date, Amount, Particulars/Description/Details/Narration

现在需要保持已加载和未来记录的唯一性。

由于已经加载的外部文件没有唯一性,所以我认为,我们必须通过使用给定字段创建唯一键来更新现有记录,但是很明显,外部文件中的字段可能会重复。

如何保持我们可以从文件中识别交易的唯一性已经加载。欢迎所有类型的建议。

编辑 1

当前加载的记录被确认是有效的,由于从旧文件或丢失文件中加载了一些丢失的记录,因此需要保持唯一性

编辑 2

根据给定的 4 个字段,现有记录可能具有重复记录,即两个或多个有效交易的帐户、日期、金额和详细信息的相同值,但可以肯定,即使具有重复值,这些记录也是有效的。

现在为了加载丢失的记录,我们需要确定一条记录是否已经加载,这样我们就不会加载已经加载的记录。所以,对我来说,很难知道是否已经根据这些字段加载了记录。我认为它超出了这些领域的限制

编辑 3

现在情况发生了变化,这不再是一个有效的问题,但最好把它留在这里给其他人。已同意在记录中添加唯一键,因此检查此键是否重复

4

3 回答 3

1

“现有记录可能具有基于给定 4 个字段的重复记录,即两个或多个有效交易的帐户、日期、金额和详细信息的相同值,但可以肯定这些记录即使具有重复值也是有效的。”

但是,如果加载的数据或源文件中没有唯一性标记,那么任何人都怎么知道呢?有效性甚至意味着什么?

“现在为了加载丢失的记录,我们需要确定一条记录是否已经加载,这样我们就不会加载已经加载的记录。”

如果没有现有的独特性来源,您将无法做到这一点。因为它对于给定的组合有两行,(Account, Date, Amount, Particulars)没关系,确定(帐户,日期,金额,详细信息)的第三个实例是已经加载的记录的规则是什么,因此无效,或者记录尚未加载,因此有效。

“所以,对我来说,很难知道是否已经根据这些字段加载了记录。我认为它超出了这些字段的限制”

您说得对,在您描述的数据中找不到解决方案。但解决方案其实很简单。你去找那些断言加载记录的有效性的人,并向他们提供这些附加记录的列表。他们将能够使用他们的技能和判断力告诉您哪些记录是有效的,然后您加载这些记录。


“找到解决办法是我的职责”

不,这不是你的职责。目前,数据所有者肩负着准确定义其数据集的责任,其中包括识别业务密钥。他们是那些取消他们的责任的人。

在这种情况下,您有三个选择:

  1. 在数据所有者履行职责之前,拒绝加载任何进一步的记录。
  2. 加载提供给您的所有记录以供加载,无需任何验证。
  3. 使用可怕的 NOVALIDATE 语法。

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 描述为可怕,因为它确实如此。它将数据损坏烘焙到数据库中。但这是最接近解决方案的事情。

这种方法完全忽略了“有效性”的概念。因此它将拒绝可能应该加载的记录,因为它们代表“有效”第 n 次出现 (Account, Date, Amount, Particulars). 这是不可避免的。好消息是,没有人能说出来,因为没有明确的规则来确定有效性。

无论您选择什么选项,您都必须向您的老板、数据所有者、数据所有者的老板以及您认为合适的任何其他人清楚地解释清楚,并获得他们的书面同意继续进行,这一点至关重要。否则,有时人们会发现数据库中充满了重复的行,或者有人会抱怨没有加载“有效”记录,这都是你的错......除非你有一个签名的获得相应上层黄铜授权的纸张。

祝你好运


Haki 使用 MERGE 的建议与 NOVALIDATE 具有相同的效果,因为它会加载新记录并抑制所有重复项。然而,它更像是一个杂牌:它根本没有解决唯一性的概念。任何拥有 INSERT 或 UPDATE 访问权限的人仍然可以拥有他们喜欢的任何行。因此,这种方法只有在您可以完全锁定该表的权限以便其数据只能通过 MERGE 而不能通过其他 DML 操作时才有效。取决于持续的独特性是否重要。再次,商业决策。

于 2013-07-09T07:40:31.407 回答
1

注意 - 在 OP 的一些澄清之后,这个答案与他们的场景无关。问题是政治或商业问题,而不是技术问题。我将把这个答案作为一个假设问题的解决方案,因为它可能仍然对一些未来的寻求者有用。

我的另一个回应 是针对 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 子句查找重复的行。您将使用一个特殊的表来捕获约束违规。 了解更多

于 2013-07-09T07:04:53.163 回答
0

听起来你需要一个 upsert - 或者像 oracle 所说的那样MERGE

两个表之间的MERGE操作允许您处理两种常见情况 -

  1. 记录已经存在于目标表中,我需要对它做点什么——要么更新,要么什么都不做。

  2. 目标表中不存在该记录 - 插入它。

于 2013-07-09T07:44:14.273 回答