【问题标题】:database for enterprise level using oracle - normalization and duplication使用 oracle 的企业级数据库 - 规范化和复制
【发布时间】:2012-07-11 21:02:18
【问题描述】:

我正在使用 Oracle 后端开发企业应用程序。我现在正在设计数据库架构的核心部分,对此我有一些疑问。

  1. 首先也是最重要的一点是,我的大多数表都需要保留旧数据。例如

考虑一个包含字段的表格

合同编号、合同名称、合同人员、合同电子邮件

我有类似的记录

12, xxx, yyy, xxx@zzz.ccc

有人将其修改为

12, xxx, zzz, xxx@zzz.ccc

在任何时候,我都需要显示新记录,同时仍保留旧记录的副本。

所以我的想法是放置旧数据的重复记录并更新已更改的字段,并有一个标志来跟踪活动记录,例如“处于活动状态”为 1。

缺点是这会在表格中产生冗余,并且看起来是一个糟糕的设计。但是任何其他模型似乎都不必要地复杂,这对我来说似乎更干净。此外,我也没有看到任何具有重复记录的性能问题。所以请让我知道这是否可以,或者我在这里遗漏了什么。

  1. 有时存在一对多关系,我的假设是有一个映射表,我通过在每个记录中重复主 ID 和更改子 ID 来映射单个记录中的多个实体。这是正确的方法还是有更好的方法。

  2. 有没有关于数据库最佳实践的书。

谢谢。

我正在处理的数据库是两节点 RAC 集群上的 Oracle 11g

【问题讨论】:

标签: oracle oracle11g duplicates normalization


【解决方案1】:

我也没有看到任何重复记录的性能问题。

假设您有一行,随着时间的推移,它有 15 次更新。如果您不存储任何时间数据(如果您不存储该行的不同版本),那么您最终会存储一行。如果您确实存储时态数据,则最终会存储 15 行。

您还需要更多索引,因为 id 号已不足以识别单行。

如果您只有相对较小的表,您可能不会看到任何性能差异。 (将会有一个,但用户可能不会注意到它。)但是具有 1000 万行的表与具有 1.5 亿行的表的性能不同。 (每行 15 个版本,乘以 1000 万行。)

有时我的假设是一对多的关系 有一个映射表,我在其中映射多个实体 通过在每条记录中重复主 ID 和更改子 ID 来记录。 这是正确的方法还是有更好的方法。

您可能需要知道哪些子行属于哪些父行。因此,您需要多个主 ID 作为密钥。单独的主 ID 不会告诉您父表中该行的哪个版本适用于给定的子行。

有没有关于数据库最佳实践的书。

有关于时态数据库的书籍。我知道的第一个是Snodgrass 的Developing Time-Oriented Database Applications in SQL。它有多种格式,而且是免费的。它也有点老了,但其中的信息对于了解您是否要构建时态数据库很重要。另外,请考虑阅读 Date 的书Temporal Data and the Relational Model

维基百科有一篇文章总结了ideas behind temporal databases

标准化是完全强制性的吗?

这是一个毫无意义的问题。标准化为 2NF 的表格与标准化为 5NF 或 6NF 的表格相比,您会遇到不同的问题。

【讨论】:

  • 好的,很抱歉被最后一个问题冲昏了头脑。因此,如果有 1.5 亿行实际上应该是 1000 万行,那么性能就会受到影响。那么我们可以在另一个表中移动旧数据,并且只在活动表中拥有活动行
  • 现在您正在谈论将桌子数量增加一倍。参照约束是一个问题。旧子表中的一行引用了哪一行?它是引用活动父表中的一行还是旧父表中的一行?选择最近的两个行(当您试图找出为什么出现损坏时的常见查询)需要在活动表和非活动表之间使用 UNION,或者将通常返回的列数加倍。
  • 这是我的解决方案,如果有一个名为“policies”的表,我将有另一个名为“policies_history”的表。现在,每当我进行更新时,我将首先将整行插入到表历史表中,并引用策略表的主键并更新策略表中的记录。这样我就不会丢失任何关键引用,因为我只是更新原始表并将旧数据放入历史表中,如果我想查询我所做的最后 5 次更改,我仍然可以得到它。这听起来怎么样?
  • 听起来像是policies_history 是您的第一个想法(一个表对每个更改都有一行),加上另一个表(策略)用于当前行。您是否考虑过使用Oracle Workspace Manager
【解决方案2】:

我会将旧/历史记录保存在单独的表中。创建一个 upd/del 触发器来为您填充您的审计/历史记录表,并在您的主表中只保留最新的数据。

有关示例,请参阅 here。 SO中还有很多类似的例子。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-03-29
    • 2011-06-09
    • 2012-04-27
    • 2018-02-10
    • 1970-01-01
    • 1970-01-01
    • 2010-12-25
    • 1970-01-01
    相关资源
    最近更新 更多