我有一张桌子说:
CREATE TABLE "Datanode" ( "ID" NUMBER(7,0),"TYPE" NUMBER(7,"NAME" VARCHAR2(100),"STATUS" NUMBER(7,"REVISION" NUMBER(4,"MODIFIEDAT" DATE ); CREATE TABLE "Datanode_Revisions" ( "ID" NUMBER(7,"NODEID" NUMBER(7,"MODIFIEDAT" DATE ) COMPRESS;
所以我有这两张桌子.我从“Datanode”读取所有内容,当发生更改时,我将当前条目写入“Datanode_Revisions”,然后修改现有的“Datanode”记录.说得通?
这是最好的方式吗?我已经可以告诉我,当Schema改变时我会遇到问题.我没有看到更好的选择,但如果有,请告诉我!我假设将这一切保留在一个表中会导致巨大的性能损失吗?我的意思是我的记录数量会增加四倍,而且已经有不少了.我认为Drupal存储了这样的节点修订,我很好奇它们如何不会遇到性能问题.
许多用户经常阅读“Datanode”.但是,很少有写入. “Datanode_Revisions”仅在有时读取.我只是担心要保留这么多桌子. “Datanode”是与此非常相似的~25个表中的一个.
解决方法
将旧行存储在Datanode表中是否会产生任何性能影响取决于Datanode行的访问方式.如果读取都是当前行的单行查找,则表中的行数相对无关紧要 – 找到特定ID的当前行不会比获取行更多的工作来自当前Datanode表的那个ID(我假设ID是表的关键).另一方面,如果您有许多查询正在对Datanode表进行表扫描,那么将行数增加四倍将增加运行这些查询所需的时间.
如果您想沿着将历史行放入Datanode表的路径,您可能希望为当前行添加一个为空的EXPIRATION_DATE列,并为过期的行填充.然后,您可以基于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>>