zoukankan      html  css  js  c++  java
  • 【Oracle11g】11_表分区


    表分区:

    • 表分区是指允许用户将一个表分成多个分区
    • 用户可以执行查询,只访问表中的特定分区
    • 将不同的分区存储在不同的磁盘,提高访问性能和安全性。
    • 可以独立的备份和恢复每个分区

    1.传统的表分区类型

    1.1 范围分区

    概念:以表中的一个列或一组列的值的范围分区
    语法:

    PARTITION BY RANGE (column_name)
    (
      PARTITION part1 VALUE LESS THAN(range1),
      PARTITION part2 VALUE LESS THAN(range2),
      ...
      [PARTITION partN VALUE LESS THAN(MAXVALUE)]
    );
    
    

    实战演练

    -- 创建范围分区表
    create table person(
     p_id varchar2(10)
    ,p_name varchar2(10)
    ,p_age number)
    partition by range(p_age)
    (
    	partition p1 values less than(18),
    	partition p2 values less than(30),
    	partition p3 values less than(35)
    );
    
    -- 插入数据(在范围分区内可以成功插入)
    insert into person values('p001','Jack',17);
    insert into person values('p002','Lucy',18);
    insert into person values('p003','Alice',32);
    commit;
    
    

    上述代码中的三条insert 语句可以正常插入,但是如果插入一条超出范围的语句,则无法插入,例如:

    -- 插入一条超出范围语句
    insert into person values('p004','Tom',60);
    

    报错如下:

    那么要想插入这条记录,该如何办呢?答案是:新增分区
    新增分区的语句为:

    -- 添加分区,此处的maxvalue表示无穷大
    alter table person add partition p4 values less than(maxvalue);
    

    查看分区表的数据

    SQL> select * from person partition(p1);
    
    P_ID       P_NAME          P_AGE
    ---------- ---------- ----------
    p001       Jack               17
    
    SQL> select * from person partition(p2);
    
    P_ID       P_NAME          P_AGE
    ---------- ---------- ----------
    p002       Lucy               18
    

    查询分区信息

    select  * from user_tab_partitions u where u.table_name='PERSON'
    

    1.2 散列分区

    概念:

    • 允许用户对不具有逻辑范围的数据进行分区
    • 通过在分区键上执行HASH函数决定存储的分区
    • 将数据平均地分布到不同的分区
      语法:
    PARTITION BY HASH (column_name)
    PARTITIONS number_of_partitions;
    或
    PARTITION BY HASH (column_name)
    ( PARTITION part1 [TABLESPACE tbs1],
      PARTITION part2 [TABLESPACE tbs2],
      ...
      PARTITION partN [TABLESPACE tbsN]);
    

    实战演练

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

    1.3 列表分区

    概念:允许用户将不相关的数据组织在一起。
    语法:

    PARTITION BY LIST (column_name)
    (
      PARTITION part1 VALUES (values_list1),
      PARTITION part2 VALUES (values_list2),
      ...
      PARTITION partN VALUES (DEFAULT)
    );
    

    实战演练

    -- 建表
    create table area(
    id number,area_name varchar(10)
    )
    partition by list(area_name)
    (
    	partition Yunnan values('曲靖','昆明','红河'),
    	partition Beijing values('房山区','西城区','门头沟'),
    	partition Shanghai values('黄浦区','徐汇区','杨浦沟'),
    	partition Shandong values('青岛','烟台','菏泽')
    );
    
    -- 插入数据
    insert into area values(1,'昆明');
    insert into area values(2,'房山区');
    insert into area values(3,'青岛');
    
    --查询数据
    select * from area partition(Beijing);
    

    1.4 复合分区

    概念:
    只有2种组合:(1)范围-散列分区组合 ;(2)范围-列表分区组合
    语法:

    PARTITION BY RANGE (column_name1)
    SUBPARTITION BY HASH (column_name2)
    SUBPARTITIONS number_of_partitions
    (
      PARTITION part1 VALUE LESS THAN(range1),
      PARTITION part2 VALUE LESS THAN(range2),
      ...
      PARTITION partN VALUE LESS THAN(MAXVALUE)
    );
    
    

    实战演练

    create table studentInfo(
    	sno number,sname varchar(100)
    )
    partition by range(sno)
    subpartition by hash(sname)
    subpartitions 4 --表示每一个范围分区后再划分为4个小分区,该表总共有12个分区
    (
    	partition p1 values less than(1000),
    	partition p2 values less than(2000),
    	partition p3 values less than(maxvalue)
    )
    
    

    通过em控制台可以查看所有的分区:进入em -->> 方案 -->> 表 -->> 输入方案名 -->> 找到表

    从上图可以看到总共有12个分区

    2.Oracle 11g新增的分区

    新增的分区有:

    • 引用分区
    • 间隔分区
    • 基于虚拟列的分区
    • 系统分区

    2.1 引用分区

    引用分区:基于由外键引用的父表的分区的方法,它依赖已有的父表子表的关系,子表通过外键关联到父表,进而继承了父表的分区方式而不需自己创建,子表还继承了父表的维护操作。

    • 主表是范围分区,子表是引用分区
    • 主表是列表分区,子表是引用分区
    • 主表是散列分区,子表是引用分区

    实战演练

    
    --------学生表
    create table student(
    	stu_id number primary key, stu_name varchar2(10),grade varchar2(100)
    )
    partition by range(stu_id)
    (
    	partition par_stu1 values less than(1000),
    	partition par_stu2 values less than(2000),
    	partition par_stu3 values less than(maxvalue)
    );
    
    ---成绩表
    create table score(
    	id number primary key, 
    	stu_id number not null,
    	course_name varchar2(20),
    	score number,
    	constraint fk_score foreign key(stu_id) references student(stu_id)
    )
    partition by reference(fk_score);
    

    通过以下案例分析下引用分区原理

    
    ---学生表插入数据并查看delete 
    insert into student values(1,'AA','三年级');
    insert into student values(10,'BB','五年级');
    commit;
    select * from student partition(par_stu1);
    
    ---成绩表插入数据并查看
    insert into score values(1,1,'数学',90);
    insert into score values(2,10,'语文',85);
    commit;
    select * from score partition(par_stu1);
    

    查询分区表的语法基本一致,只需要替换表名即可

    2.2 间隔分区

    间隔分区:可以完全自动地根据间隔阈值创建范围分区,它是范围分区的扩展 。 (一般是根据时间间隔分区)
    在数据仓库中有广泛的应用。

    create table sale_info(
    	s_id number,s_name varchar2(10),s_no number,s_date date
    )
    partition by range(s_date)
    interval(numtoyminterval(1,'MONTH'))
    (
    	partition p_200906 values less than (to_date('20090601','yyyymmdd'))
    );
    

    插入数据测试:

    insert into sale_info values(1,100,20,to_date('20090331','yyyymmdd'));
    insert into sale_info values(2,100,20,to_date('20090602','yyyymmdd'));
    insert into sale_info values(3,100,20,to_date('20090702','yyyymmdd'));
    commit;
    

    查看分区后发现,新建了2个新的分区,上述建立分区的意思表示的是:当间隔时间大于1个月则新建分区。

    假如我此时插入的日期是20091202,那么新增的分区,它的上界是20091201

    2.3 基于虚拟列的分区

    基于虚拟列的分区:把分区建立在某个虚拟列上,即建立在函数或表达式的计算结果上,来完成某种任务。

    实战演练

    create table goods(
     g_id number,
     g_name varchar(200),
     g_price number,
     g_num number,
     total_price as (g_price * g_num) virtual
    )
    partition by range(total_price)
    (
    	partition p_1000 values less than (1000),
    	partition p_2000 values less than (2000),
    	partition p_max  values less than (maxvalue)
    );
    
    insert into goods(g_id,g_name,g_price,g_num) values(1,'啤酒',4,20); -- 进入分区p_1000
    insert into goods(g_id,g_name,g_price,g_num) values(2,'洗衣机',3000,10); -- 进入分区p_max
    commit;
    

    2.4 系统分区

    系统分区:不指定分区列,由ORACLE来完成分区的控制和管理,它没有了范围分区或列表分区的界限。

    实战演练

    
    create table cust_info(
    	id number,name varchar2(100)
    )
    partition by system
    (
    	partition p1,partition p2,partition p3
    );
    

    3.总结

    3.1 增删查分区表

    • 在已分区的表中插入数据与操作普通表完全相同,Oracle会自动将数据保存到对应的分区
    • 查询、修改和删除分区表时可以显式指定要操作的分区
    -- 插入
    INSERT INTO SALES3 VALUES (‘P001’, ’02-3月-2001', 2000);
    INSERT INTO SALES3 VALUES (‘P002’, ’10-5月-2001', 2508);
    INSERT INTO SALES3 VALUES (‘P003’, ’05-7月-2001', 780);
    INSERT INTO SALES3 VALUES (‘P004’, ’12-9月-2001', 1080);
    --查询
    SELECT * FROM SALES3 PARTITION (P3);
    --删除
    DELETE FROM SALES3 PARTITION (P2);
    

    3.2 分区的维护

    添加分区 -在最后一个分区之后添加新分区

    SQL> ALTER TABLE SALESADD PARTITION P4 VALUES LESS THAN (4000);
    

    删除分区 – 删除一个指定的分区,分区的数据也随之删除

    SQL> ALTER TABLE SALES DROP PARTITION P4;
    

    **截断分区 – 删除指定分区中的所有记录 **

    SQL> ALTER TABLE SALES TRUNCATE PARTITION P3;
    

    合并分区 - 将范围分区或复合分区的两个相邻分区连接起来

    SQL> ALTER TABLE SALES MERGE PARTITIONS S1, S2 INTO PARTITION S2;
    

    拆分分区 - 将一个大分区中的记录拆分到两个分区中

    SQL> ALTER TABLE SALES SPLIT PARTITION P2 AT (1500) INTO (PARTITION P21, PARTITION P22);
    
  • 相关阅读:
    布隆过滤器
    string.ToString("X")的含义,转换为16进制
    Stream.Write()和Stream.Read(), Stream.Flush的作用,待学习
    linux查看CPU,内存使用情况
    HttpContext.Current.Request.InputStream
    程序员常去的10个顶级开发社区
    JavaScript 对象初探
    PHP – 架構設計 Data Access Layer 篇
    如何用 JavaScript 动态呼叫函数
    PHP – EasyUI DataGrid 资料存的方式
  • 原文地址:https://www.cnblogs.com/OliverQin/p/12663659.html
Copyright © 2011-2022 走看看