深入解析partition-hash分区_partition by hash-程序员宅基地

依据惯例,先看官网对hash partition的解释

    Hash partitioning enables easy partitioning of data that does not lend itself to range or list partitioning. It does this with a simple syntax and is easy to implement. It is a  better choice than range partitioning when: 
■ You do not know beforehand how much data maps into a given range
■ The sizes of range partitions would differ quite substantially or would be difficult to balance manually 
■ Range partitioning would cause the data to be undesirably clustered
■ Performance features such as parallel DML, partition pruning, and partition-wise
joins are important
    The concepts of splitting, dropping or merging partitions do not apply to hash partitions. Instead, hash partitions can be added and coalesced.
1、创建hash partition
语法如下:
3
语法看起来比range partition复杂,实际要简单的多。
column: 分区依赖列 ( 支持多个,中间以逗号分隔 );
partition: 指定分区,有两种方式:
    直接指定分区名,分区所在表空间等信息。
    只指定分区数量,和可供使用的表空间。
例:
--创建hash分区表
SQL> create table t_partition_hash(id number,name varchar2(20))
  2 partition by hash(id)(
  3 partition t_hash_p1 tablespace tbs01,
  4 partition t_hash_p2 tablespace tbs02,
  5 partition t_hash_p3 tablespace tbs03);
 
表已创建。
--查看hash分区表分区信息
SQL> edit
已写入 file afiedt.buf
 
  1 select partition_name,high_value,tablespace_name from user_tab_partitions
  2* where table_name='T_PARTITION_HASH'
SQL> /
 
PARTITION_NAME HIGH_VALUE TABLESPACE_NAME
------------------------------ ---------------------------------------------------------------------
T_HASH_P1     TBS01
T_HASH_P2     TBS02
T_HASH_P3     TBS03
--指定分区数量及表空间,创建相同的hash分区表
SQL> drop table t_partition_hash;
 
表已删除。
 
SQL> edit
已写入 file afiedt.buf
 
  1 create table t_partition_hash(id number,name varchar2(20))
  2 partition by hash(id)
  3* partitions 3 store in(tbs01,tbs02,tbs03)
SQL> /
 
表已创建。
 
SQL> select partition_name,tablespace_name from user_tab_partitions
  2 where table_name='T_PARTITION_HASH';
 
PARTITION_NAME TABLESPACE_NAME
------------------------------ ------------------------------
SYS_P21     TBS01
SYS_P22     TBS02
SYS_P23     TBS03
提示: 这里分区数量和可供使用的表空间数量之间没有直接对应关系。 分区数并不一定要等于表 空间数。
例如:
--指定分区数量<指定表空间数量
SQL> edit
已写入 file afiedt.buf
 
  1 create table t_partition_hash(id number,name varchar2(20))
  2 partition by hash(id)
  3* partitions 3 store in(tbs01,tbs02,tbs03,jjjg)
SQL> /
 
表已创建。
 
SQL> select partition_name,tablespace_name from user_tab_partitions
  2 where table_name='T_PARTITION_HASH';
 
PARTITION_NAME TABLESPACE_NAME
------------------------------ ------------------------------
SYS_P24     TBS01
SYS_P25     TBS02
SYS_P26     TBS03
--指定分区数量>指定表空间数量
SQL> edit
已写入 file afiedt.buf
 
  1 create table t_partition_hash(id number,name varchar2(20))
  2 partition by hash(id)
  3* partitions 3 store in(tbs01,tbs02)
SQL> /
 
表已创建。
 
SQL> select partition_name,tablespace_name from user_tab_partitions
  2 where table_name='T_PARTITION_HASH';
 
PARTITION_NAME TABLESPACE_NAME
------------------------------ ------------------------------
SYS_P27 TBS01
SYS_P28 TBS02
SYS_P29 TBS01
2、hash分区表上创建索引
2.1、创建global分区索引
SQL> create index idx_part_hash_id on t_partition_hash(id)
  2 global partition by hash(id)
  3 partitions 3 store in(tbs01,tbs02,tbs03);
 
索引已创建。
SQL> edit
已写入 file afiedt.buf
 
  1 select partition_name,tablespace_name from user_ind_partitions
  2* where index_name='IDX_PART_HASH_ID'
SQL> /
 
PARTITION_NAME TABLESPACE_NAME
------------------------------ ------------------------------
SYS_P30     TBS01
SYS_P31     TBS02
SYS_P32     TBS03
2.2、创建local分区索引
SQL> drop index idx_part_hash_id;
 
索引已删除。
 
SQL> create index idx_part_hash_id on t_partition_hash(id) local;
 
索引已创建。
 
SQL> select partition_name,tablespace_name from user_ind_partitions
  2 where index_name='IDX_PART_HASH_ID';
 
PARTITION_NAME TABLESPACE_NAME
------------------------------ ------------------------------
SYS_P27     TBS01
SYS_P28     TBS02
SYS_P29     TBS01
由此可见,hash分区的local索引与range 分区的local索引一样,其local 索引的分区完全继承表的分区的属性。
综上提示:
1、对于 global 索引分区而言,在 10g 中只能支持 range 分区和 hash 分区。
2、对于 local 索引分区而言,其分区形式完全依赖于索引所在表的分区形式。
3、注意,在创建索引时如果不显式指定 global 或 local ,则默认是 global 。
4、注意,在创建 global 索引时如果不显式指定分区子句,则默认不分区 。
3、分区表的管理
3.1增加表分区(add partition)
语法:alter table tbname add partition ptname……
例:
SQL> alter table t_partition_hash add partition t_hash_p4 tablespace tbs03;
 
表已更改。
 
SQL> select partition_name,tablespace_name from user_tab_partitions
  2 where table_name='T_PARTITION_HASH';
 
PARTITION_NAME TABLESPACE_NAME
------------------------------ ------------------------------
SYS_P27 TBS01
SYS_P28 TBS02
SYS_P29 TBS01
T_HASH_P4 TBS03
注意: 
1 、对于 hash 分区,当你执行 add partition 操作的时候, oracle 会自动选择一个分区,并重新分配部分
记录到新建的分区,这也意味着有可能带来一些 IO 操作。
2 、执行 alter table 时未指定 update indexes 子句:
如果是 range/list 分区,其 local 索引和 global 索引不会受影响 ;
如果是 hash 分区,新加分区及有数据移动的分区的 local 索引和 glocal 索引会被置为 unuseable ,需要重新编译。
3.2、收缩表分区(coalesce partitions)
Coalesce partition 仅能被应用于 hash 分区或复合分区的 hash 子分区,执行 之后,会自动收缩当前的表分区,一次只能减少一个分区,
不能指定减少partitoin的名称,当表只剩一个分区时,再执行coalesce patition会报错。此功能相当于range 和ist分区表的merge partition
例:
SQL> select partition_name,tablespace_name from user_tab_partitions
  2 where table_name='T_PARTITION_HASH';
 
PARTITION_NAME TABLESPACE_NAME
------------------------------ ------------------------------
SYS_P27 TBS01
SYS_P28 TBS02
SYS_P29 TBS01
T_HASH_P4 TBS03
 
SQL> alter table t_partition_hash coalesce partition sys_p27;
alter table t_partition_hash coalesce partition sys_p27
                                                *
第 1 行出现错误:
ORA-14174: 仅 <并行子句> 可以跟在 COALESCE PARTITION|SUBPARTITION 之后
 
 
SQL> alter table t_partition_hash coalesce partition;
 
表已更改。
 
SQL> select partition_name,tablespace_name from user_tab_partitions
  2 where table_name='T_PARTITION_HASH';
 
PARTITION_NAME TABLESPACE_NAME
------------------------------ ------------------------------
SYS_P27 TBS01
SYS_P28 TBS02
SYS_P29 TBS01
--再执行一次coalesce partition
SQL> alter table t_partition_hash coalesce partition;
 
表已更改。
 
SQL> select partition_name,tablespace_name from user_tab_partitions
  2 where table_name='T_PARTITION_HASH';
 
PARTITION_NAME TABLESPACE_NAME
------------------------------ ------------------------------
SYS_P27 TBS01
SYS_P28 TBS02
 
注意,收缩的只是分区,并不会影响到数据,但是视被收缩分区中数据的多少,收缩表分区也会涉及 到 IO 操作。 另外如果你在执行该语句时没有指定 update indexes 子句,收缩过程中有数据改动的分区其 local 索引 和 glocal 索引都会失效,需要重新编译。
3.3、交换表分区(Exchange partition)
上一章节讲range分区中提到exchange partition,其实就是数据迁移。hash partition可以与非分区表及range分区表(注意必须是range的组合分区range-hash,而且必须是range-hash与hash进行交换,即alter table tb_partiotn_range_hash exchange partition ptname with table tb_partition_hash,后面会有实例详细演示)进行exchange partition。
3.3.1 range partition与hash partition相互exchange partition(不支持)
--hash partition insert 
SQL> insert into t_partition_hash values(1,'a');
 
已创建 1 行。
 
SQL> insert into t_partition_hash values(11,'b');
 
已创建 1 行。
 
SQL> insert into t_partition_hash values(21,'c');
 
已创建 1 行。
 
SQL> commit;
提交完成。
 
SQL> select * from t_partition_hash;
 
        ID NAME
---------- --------------------
        11 b
         1 a
        21 c
 
SQL> select * from t_partition_hash partition(t_hash_p1);
 
        ID NAME
---------- --------------------
        11 b
 
SQL> select * from t_partition_hash partition(t_hash_p2);
 
        ID NAME
---------- --------------------
         1 a
 
SQL> select * from t_partition_hash partition(t_hash_p3);
 
        ID NAME
---------- --------------------
        21 c
通过以上insert 语句可以看出,hash partition表中分区内的数据存储无规律,人为无法识别新插入的数据将存放于哪个分区。
--range partition insert 
SQL> insert into t_partition_range values(11,'a');
 
已创建 1 行。
 
SQL> insert into t_partition_range values(21,'b');
 
已创建 1 行。
 
SQL> commit;
--hash partition table exchange partition with range partition table
SQL> alter table t_partition_hash exchange partition t_hash_p1
  2 with table t_partition_range;
with table t_partition_range
           *
第 2 行出现错误:
ORA-14095: ALTER TABLE EXCHANGE 要求非分区, 非聚簇的表
 
--range partition table exchange partition with  hash partition table
SQL> alter table t_partition_range exchange partition p2
  2 with table t_partition_hash;
with table t_partition_hash
           *
第 2 行出现错误:
ORA-14095: ALTER TABLE EXCHANGE 要求非分区, 非聚簇的表
结论:由此可见hash分区表与range分区表无法进行exchange partition操作
 
3.3.2 range-hash partition exchange partition hash partition(支持,反过来交换则不支持)
--创建range-hash表
SQL> create table t_partition_range_hash(id number,name varchar2(20))
  2 partition by range(id) subpartition by hash(name)
  3 subpartitions 3 store in(tbs01,tbs02,tbs03)(
  4 partition t_range_p1 values less than(10) tablespace tbs01,
  5 partition t_range_p2 values less than(20) tablespace tbs02,
  6 partition t_range_p3 values less than(30) tablespace tbs03,
  7 partition t_range_pmax values less than(maxvalue) tablespace tbs03);
 
表已创建。
SQL> edit
已写入 file afiedt.buf
 
  1 alter table t_partition_range_hash exchange partition t_range_p2
  2* with table t_partition_hash
SQL> /
alter table t_partition_range_hash exchange partition t_range_p2
*
第 1 行出现错误:
ORA-14295: 分区列和子分区列之间的列的类型或大小不匹配
注意:range-hash分区表与hash分区表进行exchange partition操作时,hash分区依赖字段和类型必须一致,上例中报错是因为
t_partition_range_hash表是根据name进行subpartition的hash分区,但t_partition_hash表是根据id进行hash分区。所以会报上面的
ora-14295错误。
--创建根据name进行hash分区的t_partition_hash_tmp表,如下:
SQL> create table t_partition_hash_tmp(id number,name varchar2(20))
  2 partition by hash(name)
  3 partitions 3 store in(tbs01,tbs02,tbs03);
 
表已创建。
 
SQL> insert into t_partition_hash_tmp values(1,'a');
 
已创建 1 行。
 
SQL> insert into t_partition_hash_tmp values(12,'b');
 
已创建 1 行。
 
SQL> commit;
 
提交完成。
--执行range-hash exchange partition with hash 
SQL> edit
已写入 file afiedt.buf
 
  1 alter table t_partition_range_hash exchange partition t_range_p2
  2* with table t_partition_hash_tmp
SQL> /
with table t_partition_hash_tmp
           *
第 2 行出现错误:
ORA-14099: 未对指定分区限定表中的所有行
 
注意:因为t_partition_hash_tmp表中数据id=1的记录,不在t_partition_range_hash中t_range_p2分区范围内,所以会报错,如上节讲到的
,可利用without validation强制执行交换。如下所示:
 
SQL> edit
已写入 file afiedt.buf
 
  1 alter table t_partition_range_hash exchange partition t_range_p2
  2* with table t_partition_hash_tmp without validation
SQL> /
 
表已更改。
--查询交换后的 t_partition_range_hash表数据
SQL> select * from t_partition_range_hash;
 
        ID NAME
---------- --------------------
         1 a
        12 b
3.3.3 range-hash partition与range partition进行exchange partition(不支持)
SQL> edit
已写入 file afiedt.buf
 
  1 alter table t_partition_range exchange partition p2
  2* with table t_partition_range_hash
SQL> /
with table t_partition_range_hash
           *
第 2 行出现错误:
ORA-14095: ALTER TABLE EXCHANGE 要求非分区, 非聚簇的表
3.3.4 range-hash partition与非分区表进行exchange partition(不支持)
SQL> alter table t_partition_range_hash exchange partition t_range_p2
  2 with table t_partition_range_tmp;
with table t_partition_range_tmp
           *
第 2 行出现错误:
ORA-14291: 不能用非分区表 EXCHANGE 组合分区
SQL> select * from t_partition_hash;
 
        ID NAME
---------- --------------------
        11 b
 
SQL> insert into t_partition_hash values(1,'a');
 
已创建 1 行。
 
SQL> insert into t_partition_hash values(31,'c');
 
已创建 1 行。
 
SQL> commit;
 
提交完成。
 
3.3.5 hash partition exchange partition with range-hash partition(不支持)
SQL> alter table t_partition_hash exchange partition t_hash_p1
  2 with table t_partition_range_hash;
with table t_partition_range_hash
           *
第 2 行出现错误:
ORA-14095: ALTER TABLE EXCHANGE 要求非分区, 非聚簇的表
3.4、截断表分区(Truncate partition)
同上一篇range分区的truncate partition用法功能一样。
语法简单:alter table tbname truncate partition/subpartition ptname;
例:
SQL> select * from t_partition_hash;
 
        ID NAME
---------- --------------------
        11 b
        12 c
         1 a
 
SQL> select * from t_partition_hash partition(t_hash_p1);
 
        ID NAME
---------- --------------------
        11 b
 
SQL> alter table t_partition_hash truncate partition t_hash_p1;
 
表被截断。
 
SQL> select * from t_partition_hash partition(t_hash_p1);
 
未选定行
3.5、移动表分区(Move Partition)
同上一篇range分区的move partition用法功能一样,主要用来修改表分区所在的表空间。
语法:alter table tbname move partition/subpartition ptname……。
例:
SQL> EDIT
已写入 file afiedt.buf
 
  1 select partition_name,tablespace_name from user_tab_partitions
  2* where table_name='T_PARTITION_HASH'
SQL> /
 
PARTITION_NAME TABLESPACE_NAME
------------------------------ ------------------------------
T_HASH_P1 TBS01
T_HASH_P2 TBS02
T_HASH_P3 TBS03
 
SQL> alter table t_partition_hash move partition t_hash_p1 tablespace jjjg;
 
表已更改。
 
SQL> select partition_name,tablespace_name from user_tab_partitions
  2 where table_name='T_PARTITION_HASH';
 
PARTITION_NAME TABLESPACE_NAME
------------------------------ ------------------------------
T_HASH_P1 JJJG
T_HASH_P2 TBS02
T_HASH_P3 TBS03
3.6、重命名表分区(Rename Partition)
语法:alter table tbname rename partition ptname to newptname;
语法和用法都简单,上一篇也讲到过,在此不多说。直接看例子:
SQL> select partition_name,tablespace_name from user_tab_partitions
  2 where table_name='T_PARTITION_HASH';
 
PARTITION_NAME TABLESPACE_NAME
------------------------------ ------------------------------
T_HASH_P1 JJJG
T_HASH_P2 TBS02
T_HASH_P3 TBS03
 
SQL> alter table t_partition_hash rename partition t_hash_p1 to t_hash_p1_new;
 
表已更改。
 
SQL> select partition_name,tablespace_name from user_tab_partitions
  2 where table_name='T_PARTITION_HASH';
 
PARTITION_NAME TABLESPACE_NAME
------------------------------ ------------------------------
T_HASH_P1_NEW JJJG
T_HASH_P2 TBS02
T_HASH_P3 TBS03
3.7、hash分区表无法进行drop、merge、split分区操作
与range分区不同,hash分区不能进行drop partition、merge partition(hash分区可用coalesce partition代替)、split partition(hash分区可用add partition代替)操作。详见下面例子
SQL> select partition_name,tablespace_name from user_tab_partitions
  2 where table_name='T_PARTITION_HASH';
 
PARTITION_NAME TABLESPACE_NAME
------------------------------ ------------------------------
T_HASH_P1_NEW JJJG
T_HASH_P2 TBS02
T_HASH_P3 TBS03
 
--测试执行drop partition
  1* alter table t_partition_hash drop partition t_hash_p1_new
SQL> /
alter table t_partition_hash drop partition t_hash_p1_new
                                            *
第 1 行出现错误:
ORA-14255: 未按范围, 组合范围或列表方法对表进行分区
 
--测试执行merge partition
SQL> alter table t_partition_hash merge partitions t_hash_p2,t_hash_p3 into partition t_has
alter table t_partition_hash merge partitions t_hash_p2,t_hash_p3 into partition t_hash_new
            *
第 1 行出现错误:
ORA-14255: 未按范围, 组合范围或列表方法对表进行分区
 
--测试执行split partition
SQL> edit
已写入 file afiedt.buf
 
  1 alter table t_partition_hash split partition t_hash_p2 at(20) into(
  2 partition t_hash_p2_1 tablespace tbs01,
  3* partition t_hash_p2_2 tablespace tbs02)
SQL> /
alter table t_partition_hash split partition t_hash_p2 at(20) into(
            *
第 1 行出现错误:

ORA-14255: 未按范围, 组合范围或列表方法对表进行分区

文章出处:http://www.cnblogs.com/ledemi/p/6321939.html

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/meng_shangjy/article/details/79799363

智能推荐

c++保留到小数点后n位_保留n位有效数字_c++保留小数点后几位怎么弄-程序员宅基地

文章浏览阅读2k次,点赞17次,收藏14次。结果自动的进行了四舍五入分别详细讲解上面的四种方法,包括它们的原理、异同以及推荐使用的情况。fixedfixedsetf()综上所述,为了确保输出的一致性和准确性,推荐使用第一种或第二种方法,因为它们明确指定了固定点表示法和精度,能够更好地控制输出的格式。_c++保留小数点后几位怎么弄

RK3568驱动指南|第七期-设备树-第57章 实例分析:中断_rk interrupts-程序员宅基地

文章浏览阅读496次。在gpio0的中断控制器为gic,在gic节点中#interrupt-cells属性被设置为3,这也就是为什么在gpio0节点中interrupts 属性有三个值,而ft5x06的中断控制器为gpio0,在gpio0节点中#interrupt-cells属性被设置为2,所以ft5x06节点的interrupts 属性只有两个值。中断信号源节点(例如设备节点或其他中断源节点)中的 interrupt-parent 属性用于指定中断信号源所属的中断控制器节点。中断信号源是产生中断的设备或其他中断源节点。_rk interrupts

Linux0.11 信号(十二)_linux0.11 do_signal-程序员宅基地

文章浏览阅读482次。信号机制是 Linux 0.11 为进程提供的一套"局部的类中断机制",即在进程执行的过程中,如果系统发现某个进程接收到了信号,就暂时打断进程的执行,转而去执行该进程的信号处理程序,处理完毕后,再从进程"被打断"之处继续执行。_linux0.11 do_signal

NUC980编译错误,arm-linux-gcc: Command not found_arm-linux-gcc未找到命令怎么解决-程序员宅基地

文章浏览阅读843次。arm-linux-gcc: Command not found_arm-linux-gcc未找到命令怎么解决

11 1 块元素div的定义 2 常见的块元素 3 块元素的用途 4 内联元素,行内元素,span 5 内联元素和块元素的用途 6 a元素超链接的用法 7 p元素不可以包含任何其他的块元素...-程序员宅基地

文章浏览阅读98次。123456下列写法错误7下列写法错误转载于:https://www.cnblogs.com/anvivi/p/9695592.html_元素另外一个常见的用途是

软件测试周刊(第15期):将军赶路 不追小兔-程序员宅基地

文章浏览阅读1.9k次。这里记录过去一周我们看到的软件测试及周边的行业动态,周五发布。本周刊开源(GitHub: SoftwareTestingWeekly ),欢迎提交 issue,投稿或推荐软件测试相关的内容。科普将军赶路 不追小兔前几天在网上看到一句话,「将军赶路,不追小兔」,言简意赅,余音绕梁,发人深省。类似的还有:将军赶路,不打野兔。 将军赶路,不打小鬼。 将军有剑,不斩苍蝇。将军好忙。「将军」是一种身份的象征,他带领着军队是要打硬仗的,有远大的目标,「赶路」才是当前..

随便推点

C++ for_each_c++ foreach (var item, pcfg->cloud_cfg)-程序员宅基地

文章浏览阅读57次。#include<vector>#include<string>#include<iostream>#include<algorithm>using namespace std;struct show{ int count; show (): count(0){} void operator()(const char& c){ cout << c; count ++; }};int main(){ vec_c++ foreach (var item, pcfg->cloud_cfg)

顺序表的创建;往顺序表的指定位置插入元素;从顺序表的指定位置删除元素_在顺序表的指定位置插入元素-程序员宅基地

文章浏览阅读5.8k次,点赞10次,收藏58次。顺序表的存储结构如下:typedef struct{ ElemType *elem; int length; int listsize;}SqList;顺序表的初始化如下:void InitList_Sq(SqList &L){ //构造一个空的线性表L L.elem = (ElemType *)malloc(LIST_..._在顺序表的指定位置插入元素

c# datetime._C#| DateTime.Year属性与示例-程序员宅基地

文章浏览阅读1k次。c# datetime. DateTime.Month属性 (DateTime.Month Property)DateTime.Month Property is used to get the year component of this object. It's a GET property of DateTime class. DateTime.Month属性用于获取此对象的年份组成部分..._datetime,.year()

matlab 求倾斜边缘,MTF的倾斜边缘法计算方法-程序员宅基地

文章浏览阅读1.2k次。MTF的倾斜边缘法计算方法简介光学系统性能的衡量方法有很多,常见的有点扩散函数法、瑞利判断法、点列图法、光学传递函数(MTF)法等,其中MTF法在光学系统和镜头加工制造中使用最为广泛。MTF曲线真实的反映了成像系统将物方信息传递到像方的能力。MTF曲线的横坐标一般是cycle/mm或者linepair/mm[1][11],纵坐标是反映对比度传递特性的像/物方调制度的比值。MTF的计算方法有很多,比..._matlab斜边超采样得到esf

RT-Smart ELF 应用程序加载运行过程分析-程序员宅基地

文章浏览阅读493次。在用户态应用程序处理的任务中,elf 加载运行是一个比较重要的步骤,下面就分析一下在 rt-smart 操作系统中,想要将一个应用程序运行起来要经过哪些步骤。ELF 格式介绍ELF 代表 Executable and Linkable Format。它是一种对可执行文件、目标文件和库使用的文件格式。它在 Linux 下成为标准格式已经很长时间,ELF 一个特别的优点在于,同一文件格式可以用于内核支..._rtt5.0 elf文件

Android动态设置约束布局的链条关系_android动态设置constraintset-程序员宅基地

文章浏览阅读460次,点赞9次,收藏9次。今天项目有需要动态设置ConstrainLayout这个布局的需求,在网上搜了一下,记录一下大致的流程和可能出现问题的点startID:要约束的目标控件id。startSide:要约束的目标控件的边界。endID:约束条件控件的id。endSide:endID的边界。int margin:间距。举个例子比如将view_divider的左边约束于tv_company_name的左边,就可以写成如果要相对父布局设置约束,可以写成要设置间距,添加一个margin参数即可其他方向的约束同理。 constra_android动态设置constraintset

推荐文章

热门文章

相关标签