2

我有一个庞大的现有订单管理应用程序。

现在,在主 ORDER 表中,我添加了一个新列:IS_HISTORICAL。如果其值为:TRUE,则表示订单现在是历史订单,不应显示在应用程序中。

现在,我必须在现有应用程序中修改许多 SQL 查询,以便它们只选择那些 IS_HISTORICAL 为“FALSE”的订单 - 即在 WHERE 子句中添加以下内容:

  AND IS_HISTORICAL='FALSE'

问题: *有没有更简单的方法——这样我就不必修改这么多应用程序查询(隐藏历史订单)?
基本上所有标记为 IS_HISTORICAL='TRUE' 的订单都应该变得不可见/不可用于读取/更新!!*

注意:目前表大小不是很大,但最终我打算通过 IS_HISTORICAL true/false 对表进行分区。

4

3 回答 3

3

如果您只想使用历史数据进行分析,那么我更喜欢 Florin 的解决方案,因为您需要为每个查询查看的数据量仍然较小。它使分析查询更加困难,因为您需要 UNION ALL 但其他一切都会“更快”运行(可能不明显)。

如果某些应用程序/用户需要访问历史数据,更好的解决方案是重命名您的表并使用您需要的查询在其之上创建一个视图。

重写所有查询的问题在于,您现在或将来都会忘记一个或得到一个不正确的查询。视图为您消除了该问题,因为查询是静态的,每次查询视图时,都会自动添加所需的附加条件。

就像是:

rename orders to order_history;

create or replace view orders as
  select *
    from order_history
   where is_historical = 'FALSE';

还有两点。

  1. 我不会打扰TRUE/ FALSE,如果表变大,需要扫描很多额外的数据。将您的列创建为 VARCHAR2(1) 并使用T/FY/ N,它们很明显但更小。或者使用 NUMBER(1,0) 和1/ 0
  2. 不要忘记对您的表施加约束,以便 IS_HISTORICAL 列只能具有您选择的值。

    如果您只想拥有这两个值,那么您可能需要考虑使用CHECK CONSTRAINT

    alter table order_history 
      add constraint chk_order_history_historical
    check ( is_historical in ('T','F') );
    

    否则,也许你应该这样做,使用FOREIGN KEY CONSTRAINT。定义一个额外的表,ORDER_HISTORY_TYPES

    create table order_history_types ( 
         id varchar2(1)
       , description varchar2(4000)
       , constraint pk_order_history_types primary key (id)
         );
    

    用您的值填充它,然后添加外键:

    alter table order_history 
       add constraint fk_order_history_historical
    foreign key (is_historical)
    references order_history_types (id)
    
于 2013-02-18T08:52:27.547 回答
2

您可以考虑使用Virtual Private Database/row-level security。这可用于在is_historical = 'FALSE'满足某些条件时自动添加谓词(例如,您作为应用程序用户连接)。

于 2013-02-18T09:03:45.937 回答
0

如果用户只需要非历史记录,一个选项是创建一个 ORDER_HIST 表并将历史记录移到那里。(删除并插入)

如果某些用户/应用程序需要这两种类型的记录,那么分区方法是最好的。

于 2013-02-18T08:41:03.583 回答