zoukankan      html  css  js  c++  java
  • oracle之二表的几种类型

    Oracle中表的几种类型

    1、表的功能:存储、管理数据的基本单元(二维表:有行和列组成)
    2、表的类型:
    1)堆表:heap table :数据存储时,行是无序的,对它的访问采用全表扫描。
    2)分区表 表>2G
    3)索引组织表(IOT)
    4)簇表
    5)临时表
    6)压缩表
    7)嵌套表

    3、如何将普通表转换为分区表;
    11g以前,1)create 分区表, 2)insert into 分区表 select * from 普通表; 3)rename 分区表名; 4)重建约束、索引、触发器。
    11g以后,在线重定义分区表

    12.1 分区表及其种类(10g)

    1)Range Partitioning (范围分区)

    scott:

    SQL>create table sale(
    product_id varchar2(5),
    sales_count number(10,2)
    )
    partition by range(sales_count)
    (
    partition p1 values less than(1000),
    partition p2 values less than(2000),
    partition p3 values less than(3000)
    );
    查看信息:

    select * from user_tab_partitions where table_name='SALE';

    insert into sale values('1',600);
    insert into sale values('2',1000);
    insert into sale values('3',2300);
    insert into sale values('4',6000);
    commit;

    select * from sale partition(p1);
    select * from sale partition(p2);

    增加一个分区
    alter table sale add partition p4 values less than(maxvalue);

    再看一下, 可以插入6000值了
    select * from user_tab_partitions where table_name='SALE';
    insert into sale values('4',6000);

    看一下段的分配
    SQL> select segment_name,segment_type,partition_name from user_segments;

    12.1.1 默认情况下,如果对分区表的分区字段做超范围(跨段)update操作,会报错——ORA-14402: 。如果一定要改,可以通过打开表的row movement属性来完成。

    SQL> select rowid,t1.* from sale partition(p1) t1;

    ROWID PRODU SALES_COUNT
    ------------------ ----- -----------
    AAASvUAAEAAAAGVAAA 1 600

    SQL> update sale set sales_count=1200 where sales_count=600;
    update sale set sales_count=1200 where sales_count=600
    *
    第 1 行出现错误:
    ORA-14402: 更新分区关键字列将导致分区的更改

    SQL> alter table sale enable row movement;
    SQL> update sale set sales_count=1200 where sales_count=600;

    已更新 1 行。

    SQL> select rowid,t1.* from sale partition(p2) t1;

    ROWID PRODU SALES_COUNT
    ------------------ ----- -----------
    AAASvVAAEAAAAGdAAA 2 1000
    AAASvVAAEAAAAGdAAB 1 1200

    一般来说范围分区的分区字段使用数字类型或日期类型,使用字符类型的语法是可以的,实际工作中使用较少。这或许跟values less than
    子句有关。

    12.1.2 关于建立分区索引

    一般使用分区都会建立索引,分区索引有local与global之分。

    Local Parfixed Index
    |-----------------------------
    Local Partitioned Index |
    |-----------------------------|
    Partitioned Index | |Local Nonparfixed Index
    |----------------------------------| |------------------------------
    | |
    | |Global Partitioned Index
    | |------------------------------
    |
    |Nonpartitioned Index
    |------------------------

    1)local:一个索引分区对应一个表分区,分区key就是索引key,分区边界就是索引边界。更新一个表分区时仅仅影响该分区的索引。

    SQL>create index sale_idx on sale(sales_count) local;
    SQL>select * from user_ind_partitions;

    Local Parfixed Index,所谓前缀索引,是指组合索引中的first column使用的是分区key。

    global:全局索引:

    1)不分区的全局索引:等同于全表的普通索引,与不适用glocal关键字没有区别[不推荐]
    SQL>create index sale_global_idx on sale(sales_count) global;

    2)分区全局索引:索引分区不与表分区对应,分区key是索引key。另外一定要将maxvalue关键字做上限。
    create index sale_global_idx on sale(sales_count) global
    partition by range (sales_count)
    (
    partition p1 values less than(1500),
    partition p2 values less than(maxvalue)
    );

    SQL>select * from user_ind_partitions;

    12.1.3 删除一个分区,其中的数据全部清除,并且包括相关索引等
    SQL> alter table sale drop partition p3;


    12.1.4 Hash Partitioning (散列分区,也叫hash分区)

    实现均匀的负载值分配,增加HASH分区可以重新分布数据。

    create table my_emp(
    empno number, ename varchar2(10)
    )
    partition by hash(empno)
    (
    partition p1, partition p2
    );

    select * from user_tab_partitions where table_name='MY_EMP';

    插入几个值,看是否均匀插入。

    insert into my_emp values(1,'A');
    insert into my_emp values(2,'B');
    insert into my_emp values(3,'C');

    select * from my_emp partition(P1);
    select * from my_emp partition(P2);

    12.1.5 列表分区(list): 将不相关的数据组织在一起

    create table personcity(
    id number, name varchar2(10), city varchar2(10)
    )
    partition by list(city)
    (
    partition east values('tianjin','dalian'),
    partition west values('xian'),
    partition south values ('shanghai'),
    partition north values ('herbin'),
    partition other values (default)
    );

    insert into personcity values(1,'sohu','tianjin');
    insert into personcity values(2,'sina','herbin');
    insert into personcity values(3,'yahoo','dalian');
    insert into personcity values(4,'360','zhengzhou');
    insert into personcity values(5,'baidu','xian');

    看结果

    select * from personcity partition(east);

    12.1.6 Composite Partitioning(复合分区)

    把范围分区和散列分区相结合或者 范围分区和列表分区相结合。

    create table student(
    sno number, sname varchar2(10)
    )
    partition by range(sno)
    subpartition by hash(sname)
    subpartitions 4 \只需要定义range分区,hash分区只需要定义个数
    (
    partition p1 values less than(1000),
    partition p2 values less than(2000),
    partition p3 values less than(maxvalue)
    );

    有三个range分区,对每个分区会有4个hash分区,共有12个分区。

    SQL> select * from user_tab_partitions where table_name='STUDENT';

    SQL> select * from user_tab_subpartitions where table_name='STUDENT';

    用EM查看,看scott的student table子分区里的名字是由oracle取名。

    12.2 Oracle11g新增分区

    Partition(分区),一直是Oracle数据库引以为荣的一项技术,正是分区的存在让Oracle高效的处理海量数据成为可能。在Oracle11g在
    10g的分区技术基础上又有了新的发展,使分区技术在易用性和可扩展性上再次得到了增强。

    12.2.1 Interval Partitioning (间隔分区)

    实际上是由range分区引申而来,最终实现了range分区的自动化,分区自动创建,只需定义间隔
    scott:
    SQL>

    create table interval_sales (s_id int,d_1 date)
    partition by range(d_1)
    interval (numtoyminterval(1,'MONTH'))
    (
    partition p1 values less than ( to_date('2010-02-01','yyyy-mm-dd') )
    );

    //只需要定义起始位置,小于这个日期都保存在p1分区中

    SQL> insert into interval_sales values(1, to_date('2010-01-21','yyyy-mm-dd') );
    SQL> insert into interval_sales values(2, to_date('2010-02-01','yyyy-mm-dd') ); --越过p1分区上线,将自动建立一个分区
    SQL> select partition_name from user_tab_partitions;

    PARTITION_NAME
    ------------------------------
    P1
    SYS_P61

    注意:interval (numtoyminterval(1,'MONTH'))的意思就是每个月有一个分区,每当输入了新的月份的数据,这个分区就会自动建立,而
    不同年的相同月份是两个分区。

    12.2.2 System Partitioning (系统分区)

    这是一个人性化的分区类型,System Partitioning,在这个新的类型中,不需要指定任何分区键,数据会进入哪个分区完全由应用程序决
    定,即在Insert语句中决定记录行插入到哪个分区。

    先建立三个表空间 tbs1,tbs2,tbs3, 然后建立三个分区的system分区表,分布在三个表空间上。

    create table test (c1 int,c2 int)
    partition by system
    (
    partition p1 tablespace tbs1,
    partition p2 tablespace tbs2,
    partition p3 tablespace tbs3
    );

    现在由SQL语句来指定插入哪个分区:

    SQL> INSERT INTO test PARTITION (p1) VALUES (1,3);
    SQL> INSERT INTO test PARTITION (p3) VALUES (4,5);

    SQL> select * from test;

    C1 C2
    ---------- ----------
    1 3
    4 5

    注意:如果要删除以上表空间,必须先删除其上的分区表,否则会报错ORA-14404: 分区表包含不同表空间中的分区。

    12.2.3 Reference Partitioning (引用分区)

    当两个表是主外键约束关联时,我们可以利用父子关系对这两个表进行分区。只要对父表做形式上的分区,然后子表就可以继承父表的分
    区键。
    如果没有11g的引用分区,你想在两个表上都建立对应的分区,那么需要使两表分别有相同名称的键值列。引用分区的好处是避免了在子表
    上也建立父表同样的一个分区键列,父表上的任何分区维护操作都将自动的级联到子表上。

    例:
    SQL>
    CREATE TABLE purchase_orders
    (po_id NUMBER(4),
    po_date TIMESTAMP,
    supplier_id NUMBER(6),
    po_total NUMBER(8,2),
    CONSTRAINT order_pk PRIMARY KEY(po_id))
    PARTITION BY RANGE(po_date)
    (PARTITION Q1 VALUES LESS THAN (TO_DATE('2007-04-01','yyyy-mm-dd')),
    PARTITION Q2 VALUES LESS THAN (TO_DATE('2007-06-01','yyyy-mm-dd')),
    PARTITION Q3 VALUES LESS THAN (TO_DATE('2007-10-01','yyyy-mm-dd')),
    PARTITION Q4 VALUES LESS THAN (TO_DATE('2008-01-01','yyyy-mm-dd')));

    //父表做了一个Range分区(可对引用分区使用除间隔分区外的所有分区策略)

    SQL>
    CREATE TABLE purchase_order_items
    (po_id NUMBER(4) NOT NULL,
    product_id NUMBER(6) NOT NULL,
    unit_price NUMBER(8,2),
    quantity NUMBER(8),
    CONSTRAINT po_items_fk FOREIGN KEY (po_id) REFERENCES purchase_orders(po_id))
    PARTITION BY REFERENCE(po_items_fk);

    //主表使用po_date键值列做范围分区,子表中没有po_date列,也想做相应的分区,那么使用引用分区吧。
    //子表最后一句PARTITION BY REFERENCE()子句给出了引用分区约束名,使用的是子表的外键约束名。
    //子表的po_id列必须是NOT NULL。这与通常的外键可以是NULL是有区别的。

    SQL> select TABLE_NAME,PARTITION_NAME,HIGH_VALUE from user_tab_partitions;

    TABLE_NAME PARTITION_NAME HIGH_VALUE
    ------------------------------ ------------------------------ --------------------------------------------------------------------------------
    PURCHASE_ORDERS Q1 TIMESTAMP' 2007-04-01 00:00:00'
    PURCHASE_ORDERS Q2 TIMESTAMP' 2007-06-01 00:00:00'
    PURCHASE_ORDERS Q3 TIMESTAMP' 2007-10-01 00:00:00'
    PURCHASE_ORDERS Q4 TIMESTAMP' 2008-01-01 00:00:00'
    PURCHASE_ORDER_ITEMS Q1
    PURCHASE_ORDER_ITEMS Q2
    PURCHASE_ORDER_ITEMS Q3
    PURCHASE_ORDER_ITEMS Q4

    8 rows selected

    //子表purchase_order_items也自动产生了四个分区,Q1,Q2,Q3,Q4.高值为空,意味者此处边界由父表派生。

    SQL> select TABLE_NAME,PARTITIONING_TYPE,REF_PTN_CONSTRAINT_NAME from user_part_tables;

    TABLE_NAME PARTITIONING_TYPE REF_PTN_CONSTRAINT_NAME
    ------------------------------ ----------------- ------------------------------
    PURCHASE_ORDERS RANGE
    PURCHASE_ORDER_ITEMS REFERENCE PO_ITEMS_FK

    // PO_ITEMS_FK列是外键约束名称

    12.2.4 Virtual Column-Based Partitioning(虚拟列分区)

    先了解一下什么叫虚拟列。

    虚拟列是11g的新特性:

    1> 只能在堆组织表(普通表)上创建虚拟列
    2> 虚拟列的值并不是真实存在的,只有用到时,才根据表达式计算出虚拟列的值,磁盘上并不存放。
    3> 可在虚拟列上建立索引。
    4> 如果在已经创建的表中增加虚拟列时,若没有指定虚拟列的字段类型,ORACLE会根据 generated always as 后面的表达式计算的结
    果自动设置该字段的类型。
    5> 虚拟列的值由ORACLE根据表达式自动计算得出,不可以做UPDATE和INSERT操作,可以对虚拟列做DELETE 操作。
    6> 表达式中的所有列必须在同一张表。
    7> 表达式不能使用其他虚拟列。

    8> 可把虚拟列当做分区关键字建立虚拟列分区表,这正是我们要讲的虚拟列分区。

    create table emp1
    (empno number(4) primary key,
    ename char(10) not null,
    salary number(5) not null,
    bonus number(5) not null,
    total_sal AS (salary+bonus))
    partition by range (total_sal)
    (partition p1 values less than (5000),
    partition p2 values less than (maxvalue))
    enable row movement;

    insert into emp1(empno,ename,salary,bonus) values(7788,'SCOTT',3000,1000);
    insert into emp1(empno,ename,salary,bonus) values(7902,'FORD',4000,1500);
    insert into emp1(empno,ename,salary,bonus) values(7839,'KING',5000,3500);
    commit;

    SQL> select * from user_tab_partitions;
    SQL> select * from user_part_key_columns;

    SQL> select * from emp1 partition (p1);

    EMPNO ENAME SALARY BONUS TOTAL_SAL
    ---------- ---------- ---------- ---------- ----------
    7788 SCOTT 3000 1000 4000

    SQL> select * from emp1 partition (p2);

    EMPNO ENAME SALARY BONUS TOTAL_SAL
    ---------- ---------- ---------- ---------- ----------
    7902 FORD 4000 1500 5500
    7839 KING 5000 3500 8500

    SQL> update emp1 set bonus=500 where empno=7902;

    在建表时就使能了行移动(enable row movement),当更新分区键值时就不会报错(ORA-14402: 更新分区关键字列将导致分区
    的更改)

    12.2.5 More Composite Partitioning
    在10g中,我们知道复合分区只支持Range-List和Range-Hash,而在在11g中复合分区的类型大大增加,现在Range,List,Interval都可
    以作为Top level分区,而Second level则可以是Range,List,Hash,也就是在11g中可以有3*3=9种复合分区,满足更多的业务需求。

    12.3 Oracle11g 的联机重定义功能

    联机条件下把普通的堆表转换成分区表(11g新特性)

    例:联机创建分区表:将emp1表联机重定义,要求完成两个任务,使其按照 sal分区(以2500为界),并去掉comm列。这个过程需要建
    立一个临时分区表emp1_temp完成复制转换。

    sys下执行

    create table scott.emp1 as select * from scott.emp;

    alter table scott.emp1 add constraint pk_emp1 primary key(empno);

    1) 检查原始表是否具有在线重定义资格,(要求表自包含及之前没有建立实体化视图及日志)
    SQL>
    BEGIN
    DBMS_REDEFINITION.CAN_REDEF_TABLE('scott','emp1');
    END;
    /

    2) 创建一个临时分区表:emp1_temp, 含有7列(删去comm列),然后range分区,两个区以sal=2500为界。
    SQL>
    CREATE TABLE scott.emp1_temp
    (empno number(4) not null,
    ename varchar2(10),
    job varchar2(9),
    mgr number(4),
    hiredate date,
    sal number(7,2),
    deptno number(2))
    PARTITION BY RANGE(sal)
    (PARTITION sal_low VALUES LESS THAN(2500),
    PARTITION sal_high VALUES LESS THAN (maxvalue));

    3)启动联机重定义处理过程
    SQL>
    BEGIN
    dbms_redefinition.start_redef_table('scott','emp1','emp1_temp',
    'empno empno,
    ename ename,
    job job,
    mgr mgr,
    hiredate hiredate,
    sal sal,
    deptno deptno');
    END;
    /


    SQL> select count(*) from scott.emp1_temp;

    COUNT(*)
    ----------
    14

    SQL> select * from scott.emp1_temp partition(sal_low);

    EMPNO ENAME JOB MGR HIREDATE SAL DEPTNO
    ---------- ---------- --------- ---------- ------ ------------- ---------- ----------
    7369 SMITH CLERK 7902 1980-12-17 00:00:00 800 20
    7499 ALLEN SALESMAN 7698 1981-02-20 00:00:00 1600 30
    7521 WARD SALESMAN 7698 1981-02-22 00:00:00 1250 30
    7654 MARTIN SALESMAN 7698 1981-09-28 00:00:00 1250 30
    7782 CLARK MANAGER 7839 1981-06-09 00:00:00 2450 10
    7844 TURNER SALESMAN 7698 1981-09-08 00:00:00 1500 30
    7876 ADAMS CLERK 7788 1987-05-23 00:00:00 1100 20
    7900 JAMES CLERK 7698 1981-12-03 00:00:00 950 30
    7934 MILLER CLERK 7782 1982-01-23 00:00:00 1300 10

    已选择9行。

    SQL> select * from scott.emp1_temp partition(sal_high);

    EMPNO ENAME JOB MGR HIREDATE SAL DEPTNO
    ---------- ---------- --------- ---------- ------------------- ---------- ----------
    7566 JONES MANAGER 7839 1981-04-02 00:00:00 2975 20
    7698 BLAKE MANAGER 7839 1981-05-01 00:00:00 2850 30
    7788 SCOTT ANALYST 7566 1987-04-19 00:00:00 3000 20
    7839 KING PRESIDENT 1981-11-17 00:00:00 5000 10
    7902 FORD ANALYST 7566 1981-12-03 00:00:00 3000 20

    已选择5行。

    这个时候emp1_temp的主键,索引,触发器,授权等还没有从原始表继承过来,

    SQL> select constraint_name,constraint_type,table_name from user_constraints where table_name like 'EMP1%';

    CONSTRAINT_NAME CONSTRAINT_TYPE TABLE_NAME
    ------------------------------ --------------- ------------------------------
    PK_EMP1 P EMP1
    SYS_C009652 C EMP1_TEMP

    4) 复制依赖对象

    这一步的作用是:临时分区表emp1_temp继承原始表emp1的全部属性:包括索引、约束和授权以及触发器。

    SQL>
    DECLARE
    num_errors PLS_INTEGER;
    BEGIN
    DBMS_REDEFINITION.COPY_TABLE_DEPENDENTS('scott','emp1','emp1_temp',
    DBMS_REDEFINITION.CONS_ORIG_PARAMS,TRUE,TRUE,TRUE,TRUE,num_errors);
    END;
    /

    SQL> select constraint_name,constraint_type,table_name from user_constraints where table_name like 'EMP1%';

    CONSTRAINT_NAME CONSTRAINT_TYPE TABLE_NAME
    ------------------------------ --------------- ------------------------------
    PK_EMP1 P EMP1
    SYS_C009652 C EMP1_TEMP
    TMP$$_PK_EMP10 P EMP1_TEMP

    这时候原始表emp1还没有分区,

    SQL> select table_name,partition_name,high_value from user_tab_partitions;

    TABLE_NAME PARTITION_NAME HIGH_VALUE
    ------------------------------ ------------------------------ --------------------------------------------------------------
    EMP1_TEMP SAL_HIGH MAXVALUE
    EMP1_TEMP SAL_LOW 2500

    5) 完成重定义过程。

    SQL> EXECUTE dbms_redefinition.finish_redef_table('scott','emp1','emp1_temp');

    SQL> select table_name,partition_name,high_value from user_tab_partitions;

    TABLE_NAME PARTITION_NAME HIGH_VALUE
    ------------------------------ ------------------------------ --------------------------------------------------------------
    EMP1 SAL_HIGH MAXVALUE
    EMP1 SAL_LOW 2500

    最后一步发生了什么事情:原始表emp1与临时分区表emp1_temp互换名称。

    12.4 索引组织表(IOT表:如果表经常以主键查询,可以考虑建立索引组织表,加快表的访问速度,不适用于大表

    heap table 数据的存放是随机的,获取表中的数据时没有明确的先后之分,在进行全表扫描的时候,并不是先插入的数据就先获取。而IOT
    表是一个完全B_tree索引结构的表,表结构按照索引(主键)有序组织,因此数据存放在插入以前就已经确定了其位置。

    由于IOT表是把普通表和索引合二而一了,这样在进行查询的时候就可以少访问很多基表的blocks,但是插入和删除的时,速度比普通的表要
    慢一些。

    IOT表的叶子节点存储了所有表列,因为已按主键排序,所以叶子节点上不需要再存储rowid。

    表列较多时,设置溢出段将主键和其他字段数据分开来存储以提高效率。

    溢出段是个可选项,如果选择了溢出段,Oracle将为一个IOT表分配两个段,一个是索引段,另一个是溢出段。

    溢出段有两个子句pctthreshold和including

    说明:
    pctthreshold给出行大小和块大小的百分比,当行数据在叶子节点占用大小超出这个阈值时,就以这个阈值将索引entry一分为二,包含
    主键的一部分列值保留在索引段,而其他列值放入溢出段,即overflow到指定的存储空间去。

    including 后面指定一个或多个列名(不含主键列),将这些列都放入索引段。即让主键和一些常用的列在索引段,其余的列在溢出段。

    例:
    create table iot_timran(id int, name char(50), sal int,
    constraint pk_timran primary key (id))
    organization index pctthreshold 30 overflow tablespace users;

    使用select * from user_indexes 查看是否单独有索引。

    SQL> select index_name,index_type,table_name from user_indexes;

    INDEX_NAME INDEX_TYPE TABLE_NAME
    ------------------------------ --------------------------- ------------------------------
    PK_TIMRAN IOT - TOP IOT_TIMRAN
    PK_EMP NORMAL EMP
    PK_DEPT NORMAL DEPT

    通过user_segments视图查看产生了两个段。
    SQL> select segment_name,segment_type,partition_name from user_segments;

    12.5 簇表(cluster table):

    两个相互关联的表的列[两个表的关连列],物理上同时组织到一个簇块中,当以后进行关联读取时,只要扫描一个数据块就可以了,可以提高了IO效率

    建立簇表的三个步骤:

    1)建立簇段cluster segment
    2)基于簇,创建两个相关表,这两个表不建立单独的段,每个表都关联到cluster segment上。
    3)为簇创建索引,生成索引段[必须创建]。

    create cluster cluster1(code_key number);
    create table student(sno1 number, sname varchar2(10)) cluster cluster1(sno1);
    create table address(sno2 number,zz varchar2(10)) cluster cluster1(sno2);
    create index index1 on cluster cluster1;

    生成了cluster1段和index1段。

    查看簇的信息:
    select * from user_clusters;
    select * from user_clu_columns;

    删除簇:
    drop table student;
    drop table address;
    drop cluster cluster1;

    12.6 临时表 (Temporary Table)

    临时表存放在当前登录的临时表空间下,它被每个session单独使用,即隔离session间的数据,不同session看到的临时表中的数据不一样。

    每个session独立支持rollback,基于事务的临时段在事务结束后收回临时段,基于会话的临时段在会话结束后收回临时段,总之没有
    DML锁,没有约束,可以建索引,视图和触发器,由于会产生少量UNDO信息所以会产生少量redo,节省资源,访问数据快。

    两种模式:
    1)基于事务的临时段:在事务提交时,就会自动删除记录,on commit delete rows。
    2)基于会话的临时段:当用户退出session 时,才会自动删除记录, on commit preserve rows。

    例:scott:
    create global temporary table tmp_student01(sno int,sname varchar2(10), sage int) on commit delete rows;

    再用Scott开一个session
    两边插入记录看看, 你可以在两个session里插入同样的记录,井水不犯河水!

    要删除临时表,要所有session断开连接,再做删除。

    drop table tmp_table;

    12.7 只读表 (11g新特性)

    在以前版本中,有只读表空间但没有只读表。11g中增加了新特性----只读表。

    SQL> alter table emp read only;
    SQL> update t set id=2;
    update t set id=2
    *
    第 1 行出现错误:
    ORA-12081: 不允许对表 "SCOTT"."T" 进行更新操作

    SQL> alter table t read write;
    SQL> alter table t read write;


    考点:只读表可以drop,因为只需要在数据字典做标记,但是不能做DML,另外,truncate也不行,因为它们都在对只读表做写操作。

    12.8 压缩表 (11g新特性)

    目的:去掉表列中数据存储的重复值,提高空间利用率。对数据仓库类的OLAP有意义(频繁的DML操作的表可能不适用做压缩表)

    可以压缩:堆表(若指定表空间则压缩该表空间下所有表),索引表,分区表,物化视图。

    主要压缩形式有两种:

    Advanced 11gR2较之前版本在语法上有了变化

    1)Basic table compression 使用direct path loads(缺省),
    典型的是建立大批量的数据,如:create table as select...结构

    Basic对应的语法是:
    CREATE TABLE ... COMPRESS BASIC;
    替换
    COMPRESS FOR DIRECT_LOAD OPERATIONS(旧)

    2)Advanced row compression 针对OLTP的任何SQL操作。

    CREATE TABLE ... COMPRESS FOR OLTP...
    代替
    CREATE TABLE ... COMPRESS FOR ALL OPERATIONS(旧)

    两种压缩的原理类似(PPT-II-481-482):当insert达到pctfree=阀值(basic对应的pctfree=0, Advanced对应的是pctfree=10),触发
    compress,之后可以继续insert,再达到pctfree,再触发compress....直至compress数据填满block的pctfree以下部分。

    压缩的是block中的冗余数据,这对节省db buffer有益。例如一个表有7个columns,5 rows,其中的一些column有重复的行值

    2190,13770,25-NOV-00,S,9999,23,161
    2225,15720,28-NOV-00,S,9999,25,1450
    34005,120760,29-NOV-00,P,9999,44,2376
    9425,4750,29-NOV-00,I,9999,11,979
    1675,46750,29-NOV-00,S,9999,19,1121

    压缩这个表后,存储形式成为如下,重复值用符号替代。

    2190,13770,25-NOV-00,S,%,23,161
    2225,15720,28-NOV-00,S,%,25,1450
    34005,120760,*,P,%,44,2376
    9425,4750,*,I,%,11,979
    1675,46750,*,S,%,19,1121

    那么自然要对这些符号做些说明,相当于有个符号表

    Symbol Value Column Rows
    * 29-NOV-00 3 958-960
    % 9999 5 956-960

  • 相关阅读:
    Intent
    What should we do next in general after collecting relevant data
    NOTE FOR Secure Friend Discovery in Mobile Social Networks
    missing pcap.h
    after building Android Source code
    plot point(one column)
    When talking to someone else, don't infer that is has been talked with others at first. It may bring repulsion to the person who is talking with you.
    进程基本知识
    Python input和raw_input的区别
    强制 code review:reviewboard+svn 的方案
  • 原文地址:https://www.cnblogs.com/jinxf/p/9171288.html
Copyright © 2011-2022 走看看