在大型的企业应用或企业级的数据库应用中,要处理的数据量通常可以达到几十到几百GB,有的甚至可以到TB级。虽然存储介质和数据处理技术的发展也很快,但是仍然不能满足用户的需求,为了使用户的大量的数据在读写操作和查询中速度更快,Oracle提供了对表和索引进行分区的技术,以改善大型应用系统的性能。 

   使用分区的优点: 

   ·增强可用性:如果表的某个分区出现故障,表在其他分区的数据仍然可用; 

   ·维护方便:如果表的某个分区出现故障,需要修复数据,只修复该分区即可; 

   ·均衡I/O:可以把不同的分区映射到磁盘以平衡I/O,改善整个系统性能; 

   ·改善查询性能:对分区对象的查询可以仅搜索自己关心的分区,提高检索速度。 

Rnage分区 => 基于分区键值的范围将数据映射到所建立的分区上。
例如,将销售数据区分到月。
CREATE TABLE sales_range
(
  salesman_id NUMBER(5),
  salesman_name VARCHAR2(30),
  sales_amount NUMBER(10),
  sales_date DATE
)
PARTITION BY RANGE(sales_date)
(
  PARTITION sales_jan2010 VALUES LESS THAN(TO_DATE('01/02/2010','DD/MM/YYYY')),
  PARTITION sales_feb2010 VALUES LESS THAN(TO_DATE('01/03/2010','DD/MM/YYYY')),
  PARTITION sales_mar2010 VALUES LESS THAN(TO_DATE('01/04/2010','DD/MM/YYYY'))
);

Interval分区 => 前面介绍的Range分区需要手动添加和控制分区段,设置Interval段可以解决这个问题
  CREATE TABLE sales
  (
        item# INTEGER,
        quantity INTEGER,
        store_name VARCHAR(30),
        state_code  VARCHAR(2),
        sale_date DATE
  )
  PARTITION BY RANGE(sal_date)
  INTERVAL(NUMTOYMINTERVAL(1,'MONTH'))
  (
        PARTITION olddate VALUES LESS THAN (TO_DATE('01-JAN-2008','DD-MON-YYYY'))
  );
List分区 => 可以控制如何将行映射到分区中。可以为每个分区的键上定义离散的值。
例如,下例使用低于地域对销售数据分区。
CREATE TABLE sales_list
(
    salesman_id NUMBER(5),
    salesman_name VARCHAR2(30),
    sales_state VARCHAR2(20),
    sales_amount NUMBER(10),
    sales_date DATE
)
PARTITION BY LIST(sales_state)
(
    PARTITION sales_west VALUES ('XiZang','SiChuan') COMPRESS,
    PARTITION sales_east VALUES ('FuJian','XiaMen'),
    PARTITION sales_central VALUES ('HuNan')
);
Hash分区 => 散列分区为通过指定分区编号来均匀分布数据的一种分区类型,因为通过在I/O设备上进行散列分区,使得这些分区大小一致。

CREATE TABLE sales_hash
(
   salesman_id NUMBER(5),
   salesman_name VARCHAR2(30),
   sales_amount NUMBER(10),
   week_no NUMBER(2)
)
PARTITION BY HASH(salesman_id)
(
    PARTITION sale1,
    PARTITION sale2,
    PARTITION sale3,
    PARTITION sale4
);
合成分区 => 当表很大,分区可能很多或者过大难于管理时,合成分区可以将分区按其他的准则进一步划分。
例如:将销售表先按月份划分,然后再按地区进行划分。
CREATE TABLE sales
(
      SalesID NUMBER(5),
      Quantity NUMBER(5),
      ProvinceID NUMBER(2),
      Sale_Date DATE
)
PARTITION BY RANGE (sale_date)
INTERVAL(NUMTOYMINTERVAL(1,'MONTH'))
SUBPARTITION BY list(ProvinceID)
(
      PARTITION olddate VALUES LESS THAN(TODATE('01-JAN-2008','DD-MON-YYYY'))
      (
            SUBPARTITION BeiJing VALUES(1),
            SUBPARTITION ShangHai VALUES(2),
            SUBPARTITION GuangZhou VALUES(3),
      )
)
引用分区 => 对外键引用表和主表进行相同方式的分区。
例如:有Order 和 OrderDetail两个表,对Order表进行按时间的Range分区,同时对OrderDetail也采用同Order相同方式的Range分区,即使OrderDetail没有OrderDate。
CREATE TABLE Orders
(
     OrderID NUMBER(5),
     CustID   NUMBER(3),
     OrderDate DATE,
     ShipDate   DATE,
     CONSTRAINT Orders_PK PRIMARY KEY(OrderID),
     CONSTRAINT Orders_FK_Cust FOREIGN KEY (CustID) REFERENCES Customers
)
PARTITION BY RANGE (OrderDate)
INTERVAL(NUMTOYMINTERVAL(1,'MONTH'))
(
        PARTITION olddate VALUES LESS THAN (TO_DATE('01-JAN-2008','DD-MON-YYYY'))
);

CREATE TABLE OrderDetail
(
      OrderDetailID NUMBER(5),
      OrderID          NUMBER(5) NOT NULL,
      StockID           NUMBER(5),
      Quantity         NUMBER(6,2) NOT NULL,
      DIscount         NUMBER(4,2),
      CONSTRAINT OrderDetail_PK PRIMARY KEY(OrderDetailID),
      CONSTRAINT OrderDetail_FK_Stock FOREIGN KEY(StockID) REFERENCES Stock,
      CONSTRAINT OrderDetail_FK_Order FOREIGN KEY(OrderID) REFERENCES Order,
)
PARTITION BY REFERENCE(OrderDetail_FK_Order)

 

分区的局部索引和全局索引
建立了分区后,我们可以为分区建立索引。

局部索引 => 查询仅限定于某个分区内部。

全局索引 => 查询在各个分区间进行查询。

CREATE INDEX Sale_IDX ON Sales (Sale_Date) LOCAL;

CREATE INDEX Sale_IDX  ON Sales (Sale_Date) LOCAL
(

    PARTITION sale1,

    PARTITION sale2,
    PARTITION sale3 ,
    PARTITION sale4

);