首页 > Linux操作系统 > Linux操作系统 > 转贴的有关分区的文章
http://www.oracle.com/global/cn/oramag/oracle/02-jul/o42expert.html
现在有四种对表进行分区的方法。
自发明关系数据库以来,人们所遇到的最大的性能问题就是超大型表的问题。每家企业至少拥有一个超大型表,每次访问它的时候都会给系统造成性能问题。这就是为什么在Oracle8引入了表分区,以使用户将大型表分成更小的、更易于管理的块的原因。
在其中添加了列表分区以后,Oracle9i就具备了四种对数据进行划分的主要方法,用以满足任何可以预料到的业务需要。另外三种分区的方式是按范围分区(range)、哈希分区(harsh)和复合分区(Composite,复合分区需要通过使用子分区来将按范围分区和哈希分区结合起来)。下面让我们一起来看一看这些分区方法。
按范围分区的表
最早和最经常使用的分区方法就是按范围分区:也就是按数据值的范围把表中数据进行划分。当数据在每个范围内分布均匀时,性能就会最佳,因此对数据的了解程度非常重要。下面的例子显示了如何将数据简单地按部门数字范围进行分区。第一个分区--D1,包含了所有小于10的部门数字。第二个分区--D2,包含了所有小于20而大于等于10的部门。第三个分区包含了所有大于等于20的部门。
create table dept (deptno number(2), dept_name varchar2(30)) partition by range(deptno) (partition d1 values less than (10) tablespace dept1, partition d2 values less than (20) tablespace dept2, partition d3 values less than (maxvalue) tablespace dept3);
请插入数据看看是如何分区的:
insert into dept values (1, 'SALES'); insert into dept values (7, 'ACCOUNTING'); insert into dept values (10, 'ADMIN'); insert into dept values (15, 'SERVICE'); insert into dept values (22, 'MANAGEMENT');
此表被分区成D1、D2和D3,但您仍旧可以通过对数据的查询而浏览所有分区中的数据。
select * from dept; DEPTNO DEPT ------- -------- 1 SALES 7 ACCOUNTING 10 ADMIN 15 SERVICE 22 MANAGEMENT您也可以查询一个单独的分区,以便只看该分区的数据。
select * from dept partition (d1); DEPTNO DEPT ------- -------- 1 SALES 7 ACCOUNTING
每当您查询该范围内的数据时,Oracle数据库可以排除您不需要访问的那些分区的数据(称为分区排除)。当您欲从一个表中删除大量的数据的时候,使用分区的另一个美妙的好处很明显。如果把数划到各个分区,则您就可以去掉或者截去单独的分区,而无需费力去做删除操作。
alter table dept truncate partition d3; Table altered.
截去D3分区后,对该表进行的查询就只返回D1和D2分区中的数据。
按范围分区(多列)
除了使用单列对数据进行按范围分区以外,您还可以使用多列,而这更能反映通常的业务流程。下面的例子说明了如何将简单的按范围分区扩展到构成季度数据的多个列,这是对多列按范围分区的一个绝好的应用。sale_yr、sale_mth以及sale_day各列是一些用来说明某个给定季度的数值范围。
create table cust_sales ( acct_no number(5), cust_name char(30), sale_day integer not null, sale_mth integer not null, sale_yr integer not null) partition by range (sale_yr, sale_mth, sale_day) (partition cust_sales_q1 values less than (1998, 04, 01) tablespace users1, partition cust_sales_q2 values less than (1998, 07, 01) tablespace users2, partition cust_sales_q3 values less than (1998, 10, 01) tablespace users3, partition cust_sales_q4 values less than (1999, 01, 01) tablespace users4);
哈希分区
对于哈希分区,您只需指定分区数和您希望存储这些分区的物理位置即可。Oracle数据库将根据分区键值的哈希函数,自动地将各行插入到各分区中。有一点很重要,那就是哈希分区的数量应为2的乘方(定义2n个分区);否则就无法均匀分配各行。您还可以为整个表指定一个存储容量,并为该分区指定表空间。本地索引总是被等同分区的(equipartitioned)。(按相同的分区键值和相同的分区断点)。下面就是一个哈希分区的表的例子,该表按分区键acct_no哈希函数被划分成了四个部分。
create table cust_sales_hash ( acct_no number(5), cust_name char(30)) partition by hash (acct_no) partitions 4 store in (users1, users2, users3, users4);
复合分区
复合分区就是将按范围分区和哈希分区结合起来使用的一种分区方法。复合分区可以提供更加细粒化的数据分区消除。首先,您可以使用一组列作为按范围分区的键(时间或者地理位置通常是很好的选择);不同组中的列尽可能均匀分配。接着,根据不同的列组计算出一个哈希值(最好使用主键)。下述例子显示了根据entry_data按范围分区再根据item_id进行哈希分区的方法。它还进一步将 q3_2001和q4_2001分区进行了子分区。
create table items (item_id integer, deptno
number, entry_date date)
partition by range (entry_date)
subpartition by hash(item_id)
subpartitions 4
store in (item_tbs1, item_tbs2,
item_tbs3, item_tbs4)
(partition q1_2001
values less than (to_date('01-apr-2001',
'dd-mon-yyyy')),
partition q2_2001 values less than (to_date('01-jul-2001',
'dd-mon-yyyy')),
partition q3_2001 values less than (to_date('01-oct-2001',
'dd-mon-yyyy'))
(subpartition q3_2001_s1 tablespace
q3_tbs1,
subpartition q3_2001_s2 tablespace
q3_tbs2),
partition q4_2001 values less than
(to_date('01-jan-2002', 'dd-mon-yyyy'))
subpartitions 8
store in (q4_tbs1, q4_tbs2, q4_tbs3,
q4_tbs4, q4_tbs5, q4_tbs6, q4_tbs7,
q4_tbs8));
在此例子当中,数据按照entry_date值被按范围分区。(基于该年的季度)。在每个分区中,数据再按照item_id值被哈希分区。您可以在子分区级别上指定存储容量,这样,您就能够进一步为表分配I/O活动。
列表分区,Oracle9i的新功能
列表分区是Oracle9i的一个新功能。如果您能够很好地了解您的数据,并能够通过将数据分割成数个值列表而把它们均衡的分布在这些列表中,那么您就能够使用Oracle9i为您提供的更多的和更灵活的分区方式。下述例子显示了按部门名称列表将表进行分区的方法。
create table dept_part
(deptno number(2),
dname varchar2(14),
loc varchar2(13))
partition by list (dname)
(partition d1_east values ('NEW YORK'),
partition d2_west values ('SAN FRANCISCO',
'LOS ANGELES'),
partition d3_south values ('ATLANTA',
'DALLAS', 'HOUSTON'),
partition d4_north values ('CHICAGO',
'DETROIT'));
列表分区与按范围分区很相似。但是值得注意的是,这里没有"最大值(maxvalue)"选项。如果要插入了一个与该列表中指定值的不同的值,则Oracle数据库将会拒绝这一记录。
对索引进行分区
除了对表分区以外,您还可以将索引进行分区。Oracle数据库支持三种类型的索引分区:
局部前缀索引、局部非前缀索引,以及全局前缀索引。下面是在一个上例中的按范围分区deptno列上创建局部前缀索引的例子。
create index dept_index on dept (deptno) local (partition d11 tablespace dept2, partition d12 tablespace dept3, partition d13 tablespace dept1);
在一个局部分区的索引中,每个索引分区都为一个分区存储索引数据。在表分区和索引分区之间存在着一个1对1的关系。您还可以创建一个跨多个分区的全局索引:
drop index dept_index; create index dept_global_index on dept(deptno) global;
总之,局部索引比全局索引易于管理。对一个全局索引的维护会影响整个表。而对于一个局部索引的维护只会影响与其相关的分区。
在一个局部索引中,索引分区中的所有键仅涉及该表的一个分区的各行。Oracle数据库在作为基础表格分区键的相同列上对索引进行分区,并在添加、撤销或者分割基础表格时自动维护索引分区。
在一个前缀索引当中,前端(索引定义的第一部分,它包含最经常被访问的那些列)就是分区键,但是在非前缀的索引当中,却并非如此了。在一个全局索引当中,当执行任何表维护操作时,都可能需要重新构建索引(索引变得无效),即使那些操作仅仅影响了一个分区也是如此。
了解您的数据
通过分区获取更高的性能的关键就是要了解您的数据。然后,借助您对数据的了解进行分区,对数据进行划分,以最大限度地提高访问效率。
Rich Niemiec是TUSC公司的首席执行官(www.tusc.com),他还是International Oracle User Group ()的总裁。
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/51862/viewspace-180579/ ,如需转载,请注明出处,否则将追究法律责任。