我有一个庞大的现有订单管理应用程序。
现在,在主ORDER表中,我添加了一个新列:IS_HISTORICAL。如果其值为:TRUE,则表示订单现在为历史,并且不应显示在应用程序中。
现在,我必须修改现有应用程序中的许多SQL查询,以便它们只选择那些IS_HISTORICAL为“FALSE”的订单 - 即在WHERE子句中添加以下内容:
AND IS_HISTORICAL='FALSE'
问题: *是否有更简单的方法 - 这样我就不必修改那么多应用程序查询(隐藏历史订单)? 基本上所有标记为IS_HISTORICAL ='TRUE'的ORDERS都应该变得不可见/不可用于读取/更新!! *
注意: 现在表格大小不是很大,但最终我打算用IS_HISTORICAL对表格进行分区true / false。
答案 0 :(得分:3)
如果您只是使用历史数据进行分析,那么我更喜欢Florin的解决方案,因为每个查询需要查看的数据量仍然较小。它使得分析查询更加困难,因为你需要UNION ALL,但其他一切都会“更快”地运行(可能不是很明显)。
如果某些应用程序/用户需要访问历史数据,则更好的解决方案是重命名表并使用您需要的查询在其上创建视图。
重写所有查询的问题在于,无论是现在还是将来,您都会忘记一个或弄错一个。由于查询是静态的,因此视图会为您删除该问题,每次查询视图时,都会自动添加您需要的其他条件。
类似的东西:
rename orders to order_history;
create or replace view orders as
select *
from order_history
where is_historical = 'FALSE';
还有两点。
TRUE
/ FALSE
,如果表变大,则需要扫描大量额外数据。将您的列创建为VARCHAR2(1)并使用T
/ F
或Y
/ N
,它们显而易见但更小。或者,使用NUMBER(1,0)和1
/ 0
。不要忘记在表上设置约束,以便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表并在那里移动历史记录。 (删除并插入)
如果某些用户/应用程序需要两种类型的记录,那么分区方法是最好的。