如何将某些标记为“历史”的Oracle表行隐藏/不可用?

时间:2013-02-18 08:29:53

标签: sql database oracle

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

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

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

  AND IS_HISTORICAL='FALSE'

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

注意: 现在表格大小不是很大,但最终我打算用IS_HISTORICAL对表格进行分区true / false。

3 个答案:

答案 0 :(得分: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)
    

答案 1 :(得分:2)

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

答案 2 :(得分:0)

如果用户只需要非历史记录,则可以选择创建ORDER_HIST表并在那里移动历史记录。 (删除并插入)

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