【问题标题】:How to avoid duplicate records with user edits in a referential system?如何避免参考系统中用户编辑的重复记录?
【发布时间】:2018-06-28 06:32:53
【问题描述】:

PostgreSQL 10.1

我很想知道 SO 社区如何处理这个常见的数据库问题。

问题是这样的。我在 ICD_Descriptions 表(下面的中间框)中输入了桌面上各种问题的文字描述。一般来说,每个描述也会有一个代码。但是,随着时间的推移(即几年),特定文本短语/描述的代码会发生变化。因此,对于某些代码到描述,将存在一般的多对多关系。因此,第三个表 dx_log 用于允许代码和描述之间的多对多关系。最后,需要查看“代码描述”的特定组合的其他“子”表将被提供对 dx_log 的主键(recid)的引用。我相信这种安排是相当标准的数据库管理。

好的,现在解决问题。我希望 icd_code 表中的代码对该表是唯一的。我也希望 icd_description 表中的描述对于他们的表来说是唯一的。

问题。这是一个参考系统,对代码表的“数据”部分(代码)或描述(在描述表中)的更改将在子表中看到。

但是,如何正确管理用户对与相应表格的“唯一”规则相冲突的代码或描述的编辑

例如,假设描述的初始文本是“this is拼写错误”,而另一个描述文本有“this is拼写错误”。在某一时刻,这两个短语共存并且是独一无二的。但是,在稍后的时间点,错误的记录会被纠正(即拼写错误 ---> 拼写错误)。当试图将编辑内容保存到文件中时,将检测到正确的记录已经存在。

因此,如果 dx_log 表在 (icd_description_recid, icd_code_recid) 上也是唯一的,那么 简单地替换对 dx_log 中已经存在的正确拼写记录的引用将导致违反 dx_log 表的唯一性。 因此,我只能想到三个解决方案:

  1. 子表实际引用的表不能在其引用指针上有唯一性约束,
  2. 保留 dx_log 上的唯一性约束,但当冲突违反唯一性时,然后使用迁移过程将子表引用移动到现有记录(在 postgresql 中,这将大量使用目录)添加到“新记录”,然后在添加新记录之前删除现有记录。
  3. 在 dx_log 中添加一个额外的自引用指针,这样当记录与 dx_log 中已经存在的记录冲突时,不要更改它,而是 放置一个指向已经存在的“正确”记录的指针 在 dx_log 中。

我希望我已经很好地解释了我的问题。推荐的方法是什么?

感谢任何cmets。

【问题讨论】:

    标签: postgresql database-design


    【解决方案1】:

    我会说 2. 是正确的解决方案。

    是的,这要求在合并两个条目时必须更新 dx_log 中的所有相关记录,但无论如何您在 dx_log(icd_description_recid) 上都有索引,对吧?

    其他解决方案会损害数据一致性,并使系统上的所有查询更加复杂,并且可能更慢。

    【讨论】:

    • @LaurenzAlbe 这是我目前正在做的事情,但由于我可能不知道需要更新子表的时间,我需要使用 Postgresql 目录来查找所有引用dx_log。虽然对 postgresql 很好,但我想知道如何将这种方法用于其他数据库,例如 SQL,???或者如果 PostgreSQL 10.1 现在有更好的方法??
    • 这是我目前正在做的事情,但是由于我不提前知道哪些表将依赖于 dx_log,所以我不得不使用 PostgreSQL 目录来查找引用 dx_log 的表.所以我想知道 PostgreSQL 是否有“更新”的方法以及其他数据库(例如 MySQL)会采用什么方法。谢谢。
    • 我不明白。为什么需要知道外键引用dx_log 的表才能更改不是引用键的属性?
    • 我的设置可能有误。我所有表的主键是每个表的 recid(序列)。子表——现在和将来——都引用 dx_log 的 recid。不允许 dx_log on (icd_code_recid, icd_description_recid) 中的重复记录意味着如果 icd_code 或 icd_description 表中的一个条目已经存在,那么这意味着重复记录必须存在于 dx_log 表中。如果允许 dx_log 中的重复,则不必更改引用 dx_log 的表。
    • 我错过了(icd_code_recid, icd_description_recid) 的唯一性约束。诚然,这样的更改将需要对其他表中的所有孤立的相关行重新设置父项。我想你必须评估那是多么痛苦。这将是最干净的解决方案,但如果您无法付出代价,您将不得不接受更少。
    【解决方案2】:
    1. 将自然唯一约束的概念与键的概念分开。为参照完整性使用系统生成的代理键,为自然键使用唯一索引。这样您就不必重新父母。

    【讨论】:

    • 不太清楚你所说的“自然键”是什么意思,也不知道当两个索引冲突时它不会改变问题发生的位置?
    • 自然键与数据本身有关。类似于 UNIQUE(前缀、名字、姓氏、后缀)。代理键不相关(id bigserial 主键)。它们不应该发生碰撞。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-01-23
    • 1970-01-01
    • 1970-01-01
    • 2019-10-15
    相关资源
    最近更新 更多