什么是数据库表分区
数据库表分区(Partitioning),即将一个大的数据表(Table)及其索引(Index)切分更小的部分。这些分区可以有不同的名字,甚至是存储方式。
为什么要做分区
- 存储均衡:可以分摊大量数据到不同存储介质中。
- 方便管理:方便DBA管理数据表,进行各种操作,比如删除陈旧的数据。
- 直接定位查询快:根据分区策略查询数据时,可直接定位到目标分区,减少查询时间。
- 并行查询提高效率:做聚合查询时,多个分区(磁盘)并行查询,可以提高效率。
怎么做分区
分区策略
- Range:分区规则是一段段连续区间。
- List:分区规则是一个个List。
- Hash:给定分区数目,将元素均匀分配到各个分区。
分区方式
- Single-Level Partitioning(单级分区):只有一层分区。
- Composite Partitioning(多级分区):可以有多层分区,即在分区之上,再次进行分区(Sub-Partition)。
分区实例
Range Partitioning
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_jan2000 VALUES LESS THAN(TO_DATE(‘02/01/2000‘,‘MM/DD/YYYY‘)),
PARTITION sales_feb2000 VALUES LESS THAN(TO_DATE(‘03/01/2000‘,‘MM/DD/YYYY‘)),
PARTITION sales_mar2000 VALUES LESS THAN(TO_DATE(‘04/01/2000‘,‘MM/DD/YYYY‘)),
PARTITION sales_apr2000 VALUES LESS THAN(TO_DATE(‘05/01/2000‘,‘MM/DD/YYYY‘))
);
List Partitioning
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(‘California‘, ‘Hawaii‘),
PARTITION sales_east VALUES (‘New York‘, ‘Virginia‘, ‘Florida‘),
PARTITION sales_central VALUES(‘Texas‘, ‘Illinois‘),
PARTITION sales_other VALUES(DEFAULT)
);
Hash Partitioning
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)
PARTITIONS 4
STORE IN (ts1, ts2, ts3, ts4);
删除分区
要想删除分区,可以使用如下SQL:
ALTER TABLE table-name DROP PARTITION partition-name;
进一步,可以写一个函数来删除数据表陈旧的数据,如下:
-- delete the partition older than INPUT_DAYS days (exclusive) in INPUT_TABLE
create or replace procedure do_delete_old_partition
(
INPUT_TABLE IN VARCHAR,
INPUT_DAYS IN NUMBER
) AS
BEGIN
FOR P IN (SELECT PARTITION_NAME, HIGH_VALUE FROM USER_TAB_PARTITIONS WHERE TABLE_NAME = INPUT_TABLE)
LOOP
EXECUTE IMMEDIATE
‘BEGIN
IF TO_DATE(‘ || P.HIGH_VALUE || ‘,‘‘YYYYMMDD‘‘) <= (SYSDATE-‘ || INPUT_DAYS || ‘) THEN
EXECUTE IMMEDIATE
‘‘ALTER TABLE ‘ || INPUT_TABLE || ‘ DROP PARTITION ‘ || P.PARTITION_NAME || ‘‘‘;
END IF;
END;‘;
END LOOP;
END;
/