9

我有一张桌子说:

CREATE TABLE "DataNode" (
   "ID" NUMBER(7,0),
   "TYPE" NUMBER(7,0),
   "NAME" VARCHAR2(100),
   "STATUS" NUMBER(7,0),
   "REVISION" NUMBER(4,0),
   "MODIFIEDAT" DATE
 );

 CREATE TABLE "DataNode_Revisions" (
   "ID" NUMBER(7,0),
   "NODEID" NUMBER(7,0),
   "TYPE" NUMBER(7,0),
   "NAME" VARCHAR2(100),
   "STATUS" NUMBER(7,0),
   "REVISION" NUMBER(4,0),
   "MODIFIEDAT" DATE
 ) COMPRESS;

所以我有这两张桌子。我从“DataNode”中读取所有内容,当发生更改时,我将当前条目写入“DataNode_Revisions”,然后修改我现有的“DataNode”记录。说得通?

这是最好的方法吗?我已经可以告诉我,当 Schema 发生变化时我会遇到问题。我没有看到更好的选择,但如果有,请告诉我!我认为将所有这些都放在一张表中会导致巨大的性能损失,不是吗?我的意思是我的记录数量会翻两番,而且已经有不少了。我认为 Drupal 存储节点修订是这样的,我很好奇它们是如何不遭受性能问题的。

“DataNode”不断被很多用户阅读。但是,很少发生写入。“DataNode_Revisions”只是偶尔读取。我只是担心维护这么多表。“DataNode”是与这个非常相似的约 25 个表之一。

4

4 回答 4

6

将旧行存储在 DataNode 表中是否会对性能产生任何影响取决于 DataNode 行的访问方式。如果读取都是当前行的单行查找,则表中的行数相对无关紧要——查找特定 ID 的当前行不会比获取该行花费更多的工作对于当前 DataNode 表中的那个 ID(我在这里假设 ID 是表的键)。另一方面,如果您有许多查询正在对 DataNode 表进行表扫描,那么将行数翻两番将增加运行这些查询所需的时间。

如果您想沿着将历史行放入 DataNode 表的路径,您可能需要添加一个 EXPIRATION_DATE 列,该列对于当前行为 NULL,并为过期行填充。然后,您可以基于 EXPIRATION_DATE 创建一个基于函数的索引,该索引仅包含当前行的数据,即

CREATE INDEX idx_current_ids
    ON DataNode( (CASE WHEN expiration_date IS NULL THEN id ELSE null END) );

这将用于类似的查询

SELECT *
  FROM DataNode
 WHERE (CASE WHEN expiration_date IS NULL THEN id ELSE null END) = <<some id>>

显然,您可能希望创建一个具有此条件的视图,而不是每次需要当前行时都重写它,即

CREATE VIEW CurrentDataNode
AS
SELECT (CASE WHEN expiration_date IS NULL THEN id ELSE null END) id,
       type,
       name,
       status
  FROM DataNode;

SELECT *
  FROM CurrentDataNode
 WHERE id = <<some value>>
于 2010-11-23T16:35:22.173 回答
5

我通常使用触发器来写入“修订”表。是的,架构更改会迫使您更新镜像表和触发器/存档功能。

我认为您会后悔将所有历史记录以及当前修订版保存在一个表格中,因此我认为您的想法是正确的。

如果您想尝试提出一个通用解决方案,不需要为每个事务表提供镜像表,您可能会考虑只使用一个修订表,您可以将记录转换为 XML 并将其存储在 clob 中。 . 如果您必须经常或快速访问它,这不是很有用,但如果您真的只是想存档所有内容,则很好。

于 2010-11-23T16:28:58.013 回答
2

你有几个选择。迫使您跟踪数据更改的业务需求是什么?

  • 如果您只需要在“短”时间段内保留更改,则可以使用闪回查询从 UNDO 读取数据.. select * from table as of timestamp (bla);

  • 如果您需要长期保留此信息,请查看名为 Oracle Total Recall 的功能。它与闪回查询相同​​,但会无限期地保留更改。

  • 如果您需要更简单的东西,请不要让应用程序插入“旧”版本的行。使用填充数据的触发器。

  • 如果系统非常繁忙,您可以通过将中间表用作“队列”来解耦这两个表

于 2010-11-23T16:30:02.287 回答
2

这将取决于应用程序。如果您使用的是 11g,则可能需要查看新的 Flashback Data Archive。我刚刚开始研究它以保留我们所有财务和其他关键数据的历史记录。

于 2010-11-23T16:30:02.257 回答