在Oracle标准版中有什么功能可以像Oracle企业版中的分区一样使用
问题描述:
我只能访问oracle标准版,oracle标准版的哪些功能提供类似于分区的功能是否有任何逻辑合并表的概念那在MYSQL中。在Oracle标准版中有什么功能可以像Oracle企业版中的分区一样使用
答
唯一一件事就是有一个真正的表中的每个“分区”,然后比工会它们放在一起的视图。但是,每次添加或删除“分区”时,您都必须重新构建视图,并且可能存在性能问题以及除选择之外的任何其他任何可能的复杂问题 - 您可以使用程序执行插入/更新/删除相关的基础表。可能不会很容易创建或维护,或非常健壮。 Oracle为此收取额外费用是有原因的。
答
表分区是Oracle企业版的一个功能。据我所知,标准版没有这样的功能。
会很乐意被证明是错误的,你要知道...
想到的
答
Handmade Partitioning
- 为Oracle XE/SE
- 工作示例选择一个分区键,例如:DOC_DATE - 分区每年。
-
为分区创建行类型和表。
create type DOCS_ROW_TYPE as object ( doc_id NUMBER, doc_name VARCHAR2(100), doc_date DATE ); -- Create partition YOLD table (data from OLD years) create table DOCS_YOLD OF DOCS_ROW_TYPE; alter table DOCS_YOLD modify doc_id not null; alter table DOCS_YOLD modify doc_date not null; -- Create primary key alter table DOCS_YOLD add constraint DOCS_YOLD_PK primary key (DOC_ID) using index; -- Create indexes create index DOCS_YOLD_DATE_IDX on DOCS_YOLD (DOC_DATE); create index DOCS_YOLD_NAME_UPCASE_IDX on DOCS_YOLD (UPPER(DOC_NAME)); -- Create partition Y2014 table (data from 2014 years) create table DOCS_Y2014 OF DOCS_ROW_TYPE; alter table DOCS_Y2014 modify doc_id not null; alter table DOCS_Y2014 modify doc_date not null; -- Create primary key alter table DOCS_Y2014 add constraint DOCS_Y2014_PK primary key (DOC_ID) using index; -- Create indexes create index DOCS_Y2014_DATE_IDX on DOCS_Y2014 (DOC_DATE); create index DOCS_Y2014_NAME_UPCASE_IDX on DOCS_Y2014 (UPPER(DOC_NAME)); -- Create partition Y2015 table (data from 2015 years) create table DOCS_Y2015 OF DOCS_ROW_TYPE; alter table DOCS_Y2015 modify doc_id not null; alter table DOCS_Y2015 modify doc_date not null; -- Create primary key alter table DOCS_Y2015 add constraint DOCS_Y2015_PK primary key (DOC_ID) using index; -- Create indexes create index DOCS_Y2015_DATE_IDX on DOCS_Y2015 (DOC_DATE); create index DOCS_Y2015_NAME_UPCASE_IDX on DOCS_Y2015 (UPPER(DOC_NAME)); -- Create partition Y2016 table (data from 2016 years) create table DOCS_Y2016 OF DOCS_ROW_TYPE; alter table DOCS_Y2016 modify doc_id not null; alter table DOCS_Y2016 modify doc_date not null; -- Create primary key alter table DOCS_Y2016 add constraint DOCS_Y2016_PK primary key (DOC_ID) using index; -- Create indexes create index DOCS_Y2016_DATE_IDX on DOCS_Y2016 (DOC_DATE); create index DOCS_Y2016_NAME_UPCASE_IDX on DOCS_Y2016 (UPPER(DOC_NAME)); -- Create partition YNEW table (data from NEW years) create table DOCS_YNEW OF DOCS_ROW_TYPE; alter table DOCS_YNEW modify doc_id not null; alter table DOCS_YNEW modify doc_date not null; -- Create primary key alter table DOCS_YNEW add constraint DOCS_YNEW_PK primary key (DOC_ID) using index; -- Create indexes create index DOCS_YNEW_DATE_IDX on DOCS_YNEW (DOC_DATE); create index DOCS_YNEW_NAME_UPCASE_IDX on DOCS_YNEW (UPPER(DOC_NAME));
-
您必须定义正确的约束条件,Oracle才会在查询执行计划中使用过滤器!
alter table DOCS_YOLD add constraint DOCS_YOLD_KEY_CHECK check (DOC_DATE < to_date('2014-01-01','yyyy-mm-dd')); alter table DOCS_Y2014 add constraint DOCS_Y2014_KEY_CHECK check (DOC_DATE >= to_date('2014-01-01','yyyy-mm-dd') and DOC_DATE < to_date('2015-01-01','yyyy-mm-dd')); alter table DOCS_Y2015 add constraint DOCS_Y2015_KEY_CHECK check (DOC_DATE >= to_date('2015-01-01','yyyy-mm-dd') and DOC_DATE < to_date('2016-01-01','yyyy-mm-dd')); alter table DOCS_Y2016 add constraint DOCS_Y2016_KEY_CHECK check (DOC_DATE >= to_date('2016-01-01','yyyy-mm-dd') and DOC_DATE < to_date('2017-01-01','yyyy-mm-dd')); alter table DOCS_YNEW add constraint DOCS_YNEW_KEY_CHECK check (DOC_DATE >= to_date('2017-01-01','yyyy-mm-dd'));
-
创建一个视图DOCS_PARTITIONS所有分区工会
create or replace view docs_partitions as select * from docs_yold union all select * from docs_y2014 union all select * from docs_y2015 union all select * from docs_y2016 union all select * from docs_ynew
-
创建一个PK序列
create sequence DOCS_MASTER_PK_SEQ minvalue 1 maxvalue 1000000000 start with 1 increment by 1 cache 10;
-
创建 “而不是” 关于DOCS_PARTITIONS触发视图来重新分配数据
create or replace trigger docs_partitions_insert INSTEAD OF insert on docs_partitions for each row declare v_year number(4); v_doc_id docs_partitions.DOC_ID%type; begin v_doc_id := docs_master_pk_seq.nextval; v_year := to_number(to_char(:new.doc_date,'yyyy')); if (v_year < 2014) then insert into docs_yold (doc_id, doc_name, doc_date) values (v_doc_id, :new.doc_name, :new.doc_date); elsif (v_year = 2014) then insert into docs_y2014 (doc_id, doc_name, doc_date) values (v_doc_id, :new.doc_name, :new.doc_date); elsif (v_year = 2015) then insert into docs_y2015 (doc_id, doc_name, doc_date) values (v_doc_id, :new.doc_name, :new.doc_date); elsif (v_year = 2016) then insert into docs_y2016 (doc_id, doc_name, doc_date) values (v_doc_id, :new.doc_name, :new.doc_date); else insert into docs_ynew (doc_id, doc_name, doc_date) values (v_doc_id, :new.doc_name, :new.doc_date); end if; end docs_partitions_insert;
-
您还可以通过一个主表数据分发 - DOCS_MASTER
-- Create partition MASTER table (all data) create table DOCS_MASTER OF DOCS_ROW_TYPE; alter table DOCS_MASTER modify doc_id not null; alter table DOCS_MASTER modify doc_date not null; -- Create primary key alter table DOCS_MASTER add constraint DOCS_MASTER_PK primary key (DOC_ID) using index; -- Create indexes create index DOCS_MASTER_DATE_IDX on DOCS_MASTER (DOC_DATE); create index DOCS_MASTER_NAME_UPCASE_IDX on DOCS_MASTER (UPPER(DOC_NAME));
-
测试建立在DOCS_MASTER表的触发器来重新分配数据
create or replace trigger docs_master_insert before insert on docs_master for each row declare v_year number(4); begin :new.doc_id := docs_master_pk_seq.nextval; v_year := to_number(to_char(:new.doc_date,'yyyy')); if (v_year < 2014) then insert into docs_yold (doc_id, doc_name, doc_date) values (:new.doc_id, :new.doc_name, :new.doc_date); elsif (v_year = 2014) then insert into docs_y2014 (doc_id, doc_name, doc_date) values (:new.doc_id, :new.doc_name, :new.doc_date); elsif (v_year = 2015) then insert into docs_y2015 (doc_id, doc_name, doc_date) values (:new.doc_id, :new.doc_name, :new.doc_date); elsif (v_year = 2016) then insert into docs_y2016 (doc_id, doc_name, doc_date) values (:new.doc_id, :new.doc_name, :new.doc_date); else insert into docs_ynew (doc_id, doc_name, doc_date) values (:new.doc_id, :new.doc_name, :new.doc_date); end if; end docs_master_insert;
-
生成数据
declare v_i integer; v_count integer := 1000000; begin -- insert docs through the master table for v_i in 1..v_count loop insert into docs_master (doc_name, doc_date) values ( 'DOC-M-'||v_i, to_date(trunc(DBMS_RANDOM.VALUE(to_char(TO_DATE('2000-01-01','yyyy-mm-dd'),'J'),to_char(TO_DATE('2100-01-01','yyyy-mm-dd'),'J'))),'J') ); if mod(v_i,10000)=0 then commit; dbms_output.put_line('rows M inserted: '||v_i||', '||(round(100*v_i/v_count))||'%'); end if; end loop; commit; -- insert docs through the partitions view /* for v_i in 1..2 loop insert into docs_partitions (doc_name, doc_date) values ( 'DOC-P-'||v_i, to_date(trunc(DBMS_RANDOM.VALUE(to_char(TO_DATE('2000-01-01','yyyy-mm-dd'),'J'),to_char(TO_DATE('2100-01-01','yyyy-mm-dd'),'J'))),'J') ); if mod(v_i,1000)=0 then commit; dbms_output.put_line('rows P inserted: '||v_i); end if; end loop; commit; */ end;
-
从DOCS_PARTITIONS视图中选择数据
select dp.* from DOCS_PARTITIONS dp where dp.DOC_DATE between to_date('2014-02','yyyy-mm') and to_date('2014-03','yyyy-mm') -- SQL execution plan with filters!!! SELECT STATEMENT, GOAL = ALL_ROWS 0 1 78 VIEW PART_TEST DOCS_PARTITIONS 0 1 78 UNION-ALL FILTER TABLE ACCESS BY INDEX ROWID PART_TEST DOCS_YOLD 3 11 814 INDEX RANGE SCAN PART_TEST DOCS_YOLD_DATE_IDX 3 833 TABLE ACCESS BY INDEX ROWID PART_TEST DOCS_Y2014 1 750 55500 INDEX RANGE SCAN PART_TEST DOCS_Y2014_DATE_IDX 1 45 FILTER TABLE ACCESS BY INDEX ROWID PART_TEST DOCS_Y2015 1 1 74 INDEX RANGE SCAN PART_TEST DOCS_Y2015_DATE_IDX 1 44 FILTER TABLE ACCESS BY INDEX ROWID PART_TEST DOCS_Y2016 1 1 74 INDEX RANGE SCAN PART_TEST DOCS_Y2016_DATE_IDX 1 47 FILTER TABLE ACCESS BY INDEX ROWID PART_TEST DOCS_YNEW 14 61 4514 INDEX RANGE SCAN PART_TEST DOCS_YNEW_DATE_IDX 14 5565
没有什么被称为在Oracle SE逻辑合并,这使我们能够在逻辑上合并表,这样,当我在该逻辑表中查询它是被查询的基础表,使用观点是可能的,但观点有没有索引的缺点,如果我错了,请纠正我。 – 2011-04-28 11:03:08
其实我是从Postgresql迁移到Oracle和PostgresSql有功能称为有表Inhertiance和我的应用程序有两个相同的结构的表,唯一的区别是有名称基于一些时间相关的信息。 例如: 父表(Table1)有3个字段(名称,地点,日期) 子表(Table1_Jan)包含3个字段(名称,地点,日期) – 2011-04-28 11:03:30
因此,所有Jan记录都在Table1_Jan中,2月进入Table1_Feb但当我通过PostgresSQL查询,我查询父表Table1给where子句中的日期子句和postgres管理查询所需的表中的数据。 我知道在Oracle中使用Partionion可以实现类似的功能,但这是企业功能,因此我正在寻找标准版中的强大替代方案。 – 2011-04-28 11:04:16