大数据培训之旅——Oracle-7(控制文件,日志文件,表管理)

    我们登录Oracle的时候会新建一个回话,这个会话在v$session中可以查询到

——————————————————————————————————————————————————————

    这些用户名为空的是Oracle自动生成的进程,我们不可以操作,如果杀掉进程或者会话,会影响数据库的使用。

这些进程里就有DBWn,也就是昨天体系结构的进程,这个进程满足一定条件的时候,会将缓存中的数据写入到硬盘中。checkpoint这是条件之一,是Oracle自动进行的,还有一种就是无空闲数据内存的时候,当然我们也可以启动多个DBW进程,不过会影响CPU,比如alter system set db_writer_processes=3 scope=spfile;这样我们就修改了进程,当我们重新启动数据库的时候,再使用show parameter db_writer_proecsses就可以发现变成了三个,当然查询进程也可以。

——————————————————————————————————————————————————————

    来看看其他进程:LGWR这是用来写日志的进程,这个进程当日志进程写满1/3或者写满1M或者3S会就自动写入,当然写的时候还会告诉dbwn,让dbwn及时的也写入数据。我们需要看一些日志的问题:

(1)在线日志文件记录所有数据变化信息
利用日志文件快速写功能提升数据库写入性能(写100W行数据,写磁盘要10分钟,写日志只要1分钟,库认为日志写完了,数据就写完了。)

(2)为实例失败与介质失败提供恢复机制

日志建立的2种方式(库中什么时候产生日志):
 1、按物理条件:只要块发生变化,就把块记录到日志中(记录内容多,还原速度快)
 2、逻辑操作:操作动作,你做了哪些操作动作(记录的少,还原慢)

oracle是怎么记录的?监控块变化,记录块上的操作动作。
1个块8K,假设记录100行,一次插入,只记录一条,动作是按块记录的。


insert 100W行,改变了10W个块,产生10W条日志记录。


delete操作6M数据,产生日志量可能会大于6M,可能是块分布的不均匀。每个块的操作步骤都记录下来。

oracle这种,能保证还原速度,又能保证记录数据时,减少服务器压力,oracle做了个折中。

    日志主要完成的就是让数据库在突然停止工作的时候通过日志将数据回滚。

来看看scn号:

(1)数据发生变化了,SCN值增加。为了保证数据是同步的,集群有2节点,都能改数据,第1节点改完了,SCN +1。第2节点同步数据,对比两个节点SCN号。
    比如:节点1的SCN是 101       
          节点2的SCN是 100【以大的为准,将节点1的数据同步到节点2】
          
在oracle中也一样,每做一次改变,SCN号就会+1,或者你不做数据改变,它也会按时间增长,你数据库跑了1小时,时间发生变化了,库的SCN号也会变化。


SCN的作用?
你在启动时,是不是要自动恢复,你没有正常关机,第2次启动库时,它怎么知道你数据库的完整性有问题,它不可能扫描所有文件,不可能扫描所有文件下所有数据。
如果你扫描所有文件,一个生产库至少100G,那你全扫描一下,得多长时间啊?那怎么办?
它会看每个文件的SCN号,发果发现SCN号有不匹配,肯定丢数据的了,怎么办?

例:

控制文件中记录:                             非正常关机 

        数据文件的位置                          库中数据文件
              system SCN:10000                     system SCN:9990
           数据文件1 SCN:10000                数据文件1 SCN:10000      
           数据文件N SCN:10000                数据文件N SCN:10000
           
        日志文件的位置


当你再次重启库时,两边的同一个数据文件的SCN号不同,你肯定丢动作了。这样呢,它有针对性的去查询,这样可以提高恢复速度。

在系统中呢,方便还原,库文件上有SCN号,每个对象上也有SCN号。


SCN的概念 
SCN是顺序递增的一个数字,在Oracle中用来标识数据库的每一次改动,及其先后顺序。SCN的最大值是0xffff.ffffffff。

1、系统检查点scn
当一个检查点动作完成之后(check point),Oracle就把系统检查点的SCN存储到控制文件中。
select checkpoint_change# from v$database;

2、数据文件检查点scn
当一个检查点动作完成后,Oracle就把每个数据文件的scn单独存放在控制文件中。
select name,checkpoint_change# from v$datafile;


create table haha as select * from scott.emp;【创建了一个haha表,库发生改变】

select name,checkpoint_change# from v$datafile; 【没有变化】
select checkpoint_change# from v$database; 【没有变化】


总结:没有变化,但是你的SCN号肯定是增加了,但是没有更新到数据文件上,也没有更新到控制文件上。
在日志中更新了,为什么不往数据文件、控制文件上更新呢?
因为SCN号是按着时间点和改变次数来变的,变得太频繁了,每变一次,更新一次,每变一次,更新一次,服务器压力太大了。
只有在 输入 alter system checkpoint;  后会把检查点的SCN更新过去。

select name,checkpoint_change# from v$datafile; 【有变化】
select checkpoint_change# from v$database; 【有变化】


3、启动scn
Oracle把这个检查点的scn存储在每个数据文件的文件头中,这个值称为启动scn,
因为它用于在数据库实例启动时,检查是否需要执行数据库恢复。
select name,checkpoint_change# from v$datafile_header;【更新】


4、终止scn【关库的时候,触发记录一个结束的SCN号,也进行一次同步,正常关库也记录一份SCN,保证所有SCN号相同,当你再重启库时,就不用恢复操作了】
每个数据文件的终止scn都存储在控制文件中。
select name,last_change# from v$datafile;
在正常的数据库操作过程中,所有正处于联机读写模式下的数据文件的终止scn都为null.

shutdown immediate;
startup mount;
select name,last_change# from v$datafile;


 alter database open;【又查询不到了,只能在mount状态查询】

来看看日志的切换:

select * from v$log;
drop table haha;
create table haha as select * from all_objects;
insert into haha select * from haha;
commit;
delete from haha;
select * from v$log;
alter system switch logfile;
select * from v$log;【不产生数据,手工切换日志】

INACTIVE:同步完成      ACTIVE:有数据未同步完成

切换日志时,切换到ACTIVE状态的日志时,触发check point,把活动的写完了,或者变成同步完成状态,然后才能切换,等十几秒切换,所以切换有点慢。

十几秒对于我们来说,这时间很有短暂,但对于生产库,访问量大的话,十几秒太可怕了。
你想像一下,所有数据库都是先写日志后操作,意味你在切换日志时,外部的操作不能执行,因为你现在 正在切换日志组
你没法往日志组里写,操作动作都得等,等日志组正常,等切换完日志才可以,
想像一下生产库,写满50M等十几秒钟,再写满50M等十几秒钟,生产环境中50M太好写完了,一会就写完了,所以你在做数据库维护时还有一块,
日志大小的调整,一定要满足,公司的业务不要太频繁的切换日志。假如1分钟切换1次,每过1分钟等十几秒钟,领导肯定怒,体验效果非常差。
把日志组调得大点,根据业务来调整,一般情况下,保证1小时切换一次最好。
我见过最大的日志组2G大小,这属于大库,日志产生2G,是不是数据也产生2G?数据可能大于2G,也可能小于2G【增删改】。

在公司中到底设置多大好,需要你自己去监控,维护数据库,隔段时查询一下。

比如:
   在业务峰值时,查询当前查 最大序列号4,过了1小时后,再次查询 最大序列号14,这证明你1小时内切换了10次日志。那你可以把日志大小调大10倍。
   第2天你再继续在业务高峰监控,如果当前最大序列是15,过了1小时再查询是最大16了,那正常了。如果还不正常,继续调整。
   
 
 
这个日志切换太频繁不好,不切换也不好。为什么不让你设置成无限大?因为你要设置太大了,总也不切换了,带来一个问题,很少产生归档。
如果当前日志坏了,这段时间内你的数据全没了。

所以,峰值时最好1小时切换1次。2小时强制切换。   

    来看看如何创建表空间:创建xwiki用户密码xwiki 5g空间

 create tablespace xwiki datafile '/oracle/app/oradata/ecom/xwiki.dbf' size 5120M AUTOEXTEND OFF;

 create tablespace xwiki datafile '/oracle/app/oradata/ecom/xwiki.dbf' size 5M AUTOEXTEND OFF;(这里5M为了以后的演示)


 create user xwiki identified by xwiki default tablespace xwiki;

 alter user xwiki account unlock;

 grant connect,resource to xwiki;

   我们先创建表空间,之后新建用户设置默认调控将,在解锁用户,给用户授权即可。

表空间过高该如何处理?

SELECT UPPER(F.TABLESPACE_NAME) "表空间名",
D.TOT_GROOTTE_MB "表空间大小(M)",
D.TOT_GROOTTE_MB - F.TOTAL_BYTES "已使用空间(M)",
TO_CHAR(ROUND((D.TOT_GROOTTE_MB - F.TOTAL_BYTES) / D.TOT_GROOTTE_MB * 100,2),'990.99') || '%' "使用比",
F.TOTAL_BYTES "空闲空间(M)",
F.MAX_BYTES "最大块(M)"
FROM (SELECT TABLESPACE_NAME,
ROUND(SUM(BYTES) / (1024 * 1024), 2) TOTAL_BYTES,
ROUND(MAX(BYTES) / (1024 * 1024), 2) MAX_BYTES
FROM SYS.DBA_FREE_SPACE
GROUP BY TABLESPACE_NAME) F,
(SELECT DD.TABLESPACE_NAME,
ROUND(SUM(DD.BYTES) / (1024 * 1024), 2) TOT_GROOTTE_MB
FROM SYS.DBA_DATA_FILES DD
GROUP BY DD.TABLESPACE_NAME) D
WHERE D.TABLESPACE_NAME = F.TABLESPACE_NAME
ORDER BY 4 desc ;

——————————————————————————————————————————————————————

     前两个是系统表空间会自动扩大。模拟xwiki用户表空间过高,创建八个表。
create table haha1 as select * from all_objects where rownum<100;

create table haha2 as select * from all_objects where rownum<1000;

create table haha3 as select * from all_objects where rownum<2000;

create table haha4 as select * from all_objects where rownum<3000;

create table haha5 as select * from all_objects where rownum<4000;

create table haha6 as select * from all_objects where rownum<5000;

create table haha7 as select * from all_objects where rownum<10000;

create table haha8 as select * from all_objects where rownum<6000;

——————————————————————————————————————————————————————

    一般阀值设为70%左右,高于就需要进行处理。我们需要查询xwiki为什么会这么高。

通过上面的查询指定使用率过高的表空间,找出此表空间中最占空间的前20个对象

Select OWNER||','||SEGMENT_NAME||','||SEGMENT_TYPE||','||total from 
(select OWNER,SEGMENT_NAME,SEGMENT_TYPE,bytes/1024/1024 total from dba_segments 
where TABLESPACE_NAME='指定表空间的名字' order by bytes/1024/1024 desc ) where rownum <前几个;


Select OWNER||','||SEGMENT_NAME||','||SEGMENT_TYPE||','||total from 
(select OWNER,SEGMENT_NAME,SEGMENT_TYPE,bytes/1024/1024 total from dba_segments 
where TABLESPACE_NAME='XWIKI' order by bytes/1024/1024 desc ) where rownum <4;

    之后就可以针对的进行修改了。

接下来看看Oracle的数据类型

char(n)           n=1 to 2000字节
定长字符串,n字节长,如果不指定长度,缺省为1个字节长(一个汉字为2字节)


varchar2(n)      n=1 to 4000字节 
可变长的字符串,具体定义时指明最大长度n, 这种数据类型可以放数字、字母以及ASCII码字符集。


number(m,n)     m=1 to 38 n=-84 to 127 可变长的数值列
允许0、正值及负值,m是所有有效数字的位数,n是小数点以后的位数。 
如:number(5,2),则这个字段的最大值是999.99,如果数值超出了位数限制就会被截取多余的位数。 
如:number(5,2),但在一行数据中的这个字段输入575.316,则真正保存到字段中的数值是575.32。 
如:number(3,0),输入575.316,真正保存的数据是575。
如:number(3),输入575.316,真正保存的数据是575
如:number(3,2),输入5真正保存的数据是5.00


date
从公元前4712年1月1日到公元4712年12月31日的所有合法日期, 
缺省格式为DD-MON-YY,如07-11月-00 表示2000年11月7日。


LONG类型在java中是长整型,在oracle中是可变长字符列,最大长度限制是2GB【oracle官方明确声明,不推荐使用此类型,已经过期】
LONG是一种较老的数据类型,将来会逐渐被BLOB、CLOB、NCLOB等大的对象数据类型所取代。

LOB数据类型(最大存储大小都为4gb) ----mysql text
LOB又称为“大对象”数据类型:主要有CLOB,BLOB,BFILE,NCLOB 

BFILE  二进制文件,存储在数据库外的操作系统文件,只读的。把此文件当二进制处理。
BLOB 二进制大对象。存储在数据库里的大对象,一般是图像声音等文件。
CLOB 字符型大对象。一般存储大数量文本信息。存储单字节,固定宽度的数据。
NCLOB 字节字符大对象。存储单字节大块,多字节固定宽度

    Oracle的表中有两个伪列rowid和rownum

rownum:每一行的唯一的行号

rowid:用于寻址定位【索引扫描】

rowid组成 = 对象号(6位)+文件号(3位)+块号(6位)+行号(3位)

——————————————————————————————————————————————————————

在日常管理中rowid什么用?
1、判断行迁移
2、对于大表的快速更新
3、去掉重复数据
4、数据块坏了,可以做块级恢复(rman)

    来说个分页查询者就用到了rownum:

分页查询,就是将过多的结果在有限的界面上分好多页来显示,这个是很多网站常用的功能,也是最基本的功能。
分页查询格式:

SELECT *
  FROM (SELECT A.*, ROWNUM RN FROM emp A WHERE ROWNUM <= 10)
 WHERE RN >= 6;

 

SELECT * FROM (SELECT A.*, ROWNUM RN FROM emp A) WHERE RN BETWEEN 6 AND 10

——————————————————————————————————————————————————————

    我们来看看表分类:

1、堆组织表,就是普通的标准数据库表,数据以堆的方式管理。堆其实就是一个很大的空间,会一种随机的方式管理数据,数据会放在合适的地方。

例如建立一张表

create table t(id int,name varchar2(20));

插入三条记录

insert into t values(1,'a');

insert into t values(2,'b');

insert into t values(3,'c');


之后删除记录b;

delete from t where id=2;

再插入记录d

insert into t(4,'d');

d记录就可能放在记录b的位置。

2、索引组织表(IOT)不仅可以存储数据,还可以存储为表建立的索引。
索引组织表的数据是根据主键排序后的顺序进行排列数据的,这样就提高了访问的速度。
但是这是由牺牲插入和更新性能为代价的(每次写入和更新后都要重新进行重新排序)。

  
创建索引组织表(organization index)
SQL> create table t_iot(id int primary key,name varchar2(100))organization index;
创建普通表
SQL> create table t_h(id int,name varchar2(100));    {创建同样列的普通表}
往两个表中插入数据

set timing on

SQL> insert into t_iot select object_id,owner from all_objects where rownum<10000;
SQL> insert into t_h select object_id,owner from all_objects where rownum<10000;

——————————————————————————————————————————————————————

分析下两个表的差异
1、查看表
SQL> select table_name, tablespace_name,blocks from user_tables where table_name in ('T_IOT','T_H');

结果分析:
首先Oracle承认IOT是一个数据表,其次,从段结构来看,Oracle明确不承认存在T_IOT段。因为如果有段segment对象,就意味有空间分配。但是数据表有数据,是存放在哪里呢?保存在索引段中
我们知道,给数据表添加主键的时候,Oracle会自动的添加一个唯一索引。那么我们去检查一下这部分的结构情况。

查看索引
SQL> select index_name||','||index_type||','|| table_name from user_indexes where table_name in ('T_IOT','T_H');


    注意两点:
    ● 创建IOT时,必须要设定主键,否则报错。
    ● 索引组织表实际上将所有数据都放入了索引中。
    

举例:
       1.一个客户有很多地址信息,客户是一个表,客户地址信息是另外一个表。
       读取一个客户地址信息的时候,如果这个客户的所有地址信息都存放在相邻的地方,读取速度就会快一些。
       这个时候,客户地址信息表适合创建成IOT。
       
       2. 经常查看一支股票的最近几天的信息,股票信息一般是千万级别的数据,如果能够把最近几天的信息存放在一起就会快很多。


3、索引聚簇表,聚簇是指一个或多个表的组。有相同聚簇值的行会相邻的物理存储。oracle数据字典就大量使用这种表,这样可以将表、字典信息存储在一起,提高访问效率。如果数据只要用于读,需要频繁地把一些表的信息连结在一起访问,可以考虑索引聚簇表。但注意:聚簇会导致dml、全表扫描的效率底下,还有就是索引聚簇表是不能分区的。

 

4、临时表,临时表用来保存事务、会话中间结果集。临时表值对当前会话可见,可以创建基于会话的临时表,也可以创建基于事务的临时表。

1)、基于会话的临时表:【会话结束后,表还在,但是数据没了】

create global temporary table temp_s(id int,name varchar2(20)) on commit preserve rows;

insert into temp_s values(1,'yi');

select * from temp_s;

commit;

select * from temp_s;

——————————————————————————————————————————————————————

——————————————————————————————————————————————————————


2)、基于事务的临时表:【执行commit后,表还在,但是数据没了】

create global temporary table temp_t(id int,name varchar2(20)) on commit delete rows;

insert into temp_t values(1,'yi');

select * from temp_t;

commit;

select * from temp_t;

如果应用中需要临时存储一个行集合供其他表处理,可以考虑临时表。

——————————————————————————————————————————————————————

5、分区表:       【一般超过2G大小的表,就可以用分区表。举例租碟部,最开始碟比较少,后来碟越来越多】
(1). 分区表的概念
 
分区表: 
当表中的数据量不断增大,查询数据的速度就会变慢,应用程序的性能就会下降,这时就应该考虑对表进行分区。
表进行分区后,逻辑上表仍然是一张完整的表,只是将表中的数据在物理上存放到多个表空间(物理文件上),这样查询数据时,不至于每次都扫描整张表。
表每个分区都产生一个segments,不同的segments存放在不同的表空间,不同表空间存放不同磁盘,可以减少I/O。
 
 
(2)表分区的具体作用
Oracle的表分区功能通过改善可管理性、性能和可用性,从而为各式应用程序带来了极大的好处。
通常,分区可以使某些查询以及维护操作的性能大大提高。
此外,分区还可以极大简化常见的管理任务,分区是构建千兆字节数据系统或超高可用性系统的关键工具。


 
分区功能能够将表、索引或索引组织表进一步细分为段,这些数据库对象的段叫做分区。
每个分区有自己的名称,还可以选择自己的存储特性。
从数据库 管理员的角度来看,一个分区后的对象具有多个段,这些段既可进行集体管理,也可单独管理,
这就使数据库管理员在管理分区后的对象时有相当大的灵活性。
但是,从应用程序的角度来看,分区后的表与非分区表完全相同,使用 SQL DML 命令访问分区后的表时,无需任何修改。
 
 

什么时候使用分区表????
    1、表的大小超过2GB。
    2、表中包含历史数据,新的数据被增加都新的分区中。
 
 
 
(3).表分区的优缺点
 
优点: 
1、改善查询性能:对分区对象的查询可以仅搜索自己关心的分区,提高检索速度。
2、增强可用性:如果表的某个分区出现故障,表在其他分区的数据仍然可用;
3、维护方便:如果表的某个分区出现故障,需要修复数据,只修复该分区即可;
4、均衡I/O:可以把不同的分区映射到磁盘以平衡I/O,改善整个系统性能。
 
缺点: 
分区表相关:已经存在的普通表没有方法可以直接转化为分区表。不过 Oracle 提供了在线重定义表的功能【自己编写存储过程也可以实现】。
 
 
(4).表分区的几种类型及操作方法


一.范围分区:
 
范围分区将数据基于范围映射到每一个分区,这个范围是你在创建分区时指定的分区键决定的。
这种分区方式是最为常用的,并且分区键经常采用日期。举个例子:你可能会将销售数据按照月份进行分区。


当使用范围分区时,请考虑以下几个规则:
   1、每一个分区都必须有一个VALUES LESS THEN子句,它指定了一个不包括在该分区中的上限值。
分区键的任何值等于或者大于这个上限值的记录都会被加入到下一个高一些的分区中。
   2、所有分区,除了第一个,都会有一个隐式的下限值,这个值就是此分区的前一个分区的上限值。
   3、在最高的分区中,MAXVALUE被定义。MAXVALUE代表了一个不确定的值。
   这个值高于其它分区中的任何分区键的值,也可以理解为高于任何分区中指定的VALUE LESS THEN的值,同时包括空值。


   【例一:按员工号划分,单列范围分区】

create table test
  (empno number(4),
  ename varchar2(30),
  sal number)
  partition by range(empno)
  (partition e0 values less than (800) tablespace t1,
        partition e1 values less than (1000) tablespace t2,
  partition e2 values less than (2000) tablespace t3,
  partition e3 values less than (3000) tablespace t4,
  partition e4 values less than (maxvalue) tablespace tt);
  

  insert into test values (100,'Tom',1000);
  insert into test values (500,'Peter',2000);
  insert into test values (1000,'Scott',3000);
  insert into test values (1999,'Bill',4000);
  insert into test values (5000,'Gates',6000);
  commit; 


从emp表中选择全部纪录如下:

QL> select * from test;
  
  EMPNO ENAME SAL
  ---------- -----------
  100 Tom 1000
  500 Peter 2000
  1000 Scott 3000
  1999 Bill 4000
  5000 Gates 6000

还可以按照分区进行选择:

SQL> select * from test partition (e1);
  EMPNO ENAME SAL
  ---------- --------------
  100 Tom 1000
  500 Peter 2000

SQL> select * from test partition (e2);
  EMPNO ENAME SAL
  ---------- --------------
  1000 Scott 3000
  1999 Bill 4000

SQL> select * from test partition (e3);


select * from test partition (e4); 

     EMPNO ENAME      SAL
------ ------------------
      5000 Gates      6000

【例二:多列范围分区主要是基于表中多个列值范围对数据进行分区】

drop table test;

  create table test
  (empno number(4),
  ename varchar2(30),
  sal number,
  col1 number not null,
  col2 number not null)
  partition by range(col1,col2)
  (partition e1 values less than (5,1) tablespace emp1,
  partition e2 values less than (10,2) tablespace emp2,
  partition e3 values less than (maxvalue,maxvalue) tablespace emp3);
  
insert into test values (100,'Tom',1000,10,6);


insert into test values (100,'Tom',1000,10,9);
insert into test values (100,'Tom',1000,3,10);


insert into test values (200,'Peter',2000,3,1);
insert into test values (300,'Jane',3000,23,11);
commit;

【例三:按时间划分】
CREATE TABLE ORDER_ACTIVITIES 

    ORDER_ID      NUMBER(7) NOT NULL, 
    ORDER_DATE    DATE, 
    TOTAL_AMOUNT NUMBER, 
    CUSTOTMER_ID NUMBER(7), 
    PAID           CHAR(1) 

PARTITION BY RANGE (ORDER_DATE) 
(
  PARTITION ORD_ACT_PART01 VALUES LESS THAN (TO_DATE('01- MAY -2003','DD-MON-YYYY')) TABLESPACEORD_TS01,
  PARTITION ORD_ACT_PART02 VALUES LESS THAN (TO_DATE('01-JUN-2003','DD-MON-YYYY')) TABLESPACE ORD_TS02,
  PARTITION ORD_ACT_PART03 VALUES LESS THAN (TO_DATE('01-JUL-2003','DD-MON-YYYY')) TABLESPACE ORD_TS03
);


 
 
二.列表分区:
该分区的特点是某列的值只有几个,基于这样的特点我们可以采用列表分区。
这是Oracle 9i新特性,有了这种分区使得我们可以方便按照值来将数据分为更小片断。

【例一】
drop table test;

  create table test (
  empno number(4),
  ename varchar2(30),
  location varchar2(30))
  partition by list (location)
  (partition e1 values ('北京'),
  partition e2 values ('上海','天津','重庆'),
  partition e3 values ('广东','福建'));


insert into test values(123,'123','日本');

insert into test values(123,'123','北京');

这里说明一下,列表分区不能有maxvalue,当你试图insert列表中不存在值时候,Oracle会拒绝这条纪录(ORA-14400)。

 

三.散列分区(hash):
这类分区是在列值上使用散列算法,以确定将行放入哪个分区中。当列的值没有合适的条件时,建议使用散列分区。
散列分区为通过指定分区编号来均匀分布数据的一种分区类型,因为通过在I/O设备上进行散列分区,使得这些分区大小一致。

【例一】------COL类型是字符串  取值: 'a'   1    'asd'   345   678 'you'  '测试'   111    222 

CREATE TABLE HASH_TABLE 

  COL VARCHAR2(8), 
  INF VARCHAR2(100) 

PARTITION BY HASH (COL) 

  PARTITION PART01 TABLESPACE HASH_TS01, 
  PARTITION PART02 TABLESPACE HASH_TS02, 
  PARTITION PART03 TABLESPACE HASH_TS03 
);


简写:
CREATE TABLE emp2
(
    empno NUMBER (4),
    ename VARCHAR2 (30),
    sal   NUMBER 
)
PARTITION BY  HASH (empno) 
PARTITIONS 8 STORE IN (emp1,emp2,emp3,emp4,emp5,emp6,emp7,emp8);
 
hash分区最主要的机制是根据hash算法来计算具体某条纪录应该插入到哪个分区中,hash算法中最重要的是hash函数,
Oracle中如果你要使用hash分区,只需指定分区的数量即可。
建议分区的数量采用2的n次方,这样可以使得各个分区间数据分布更加均匀。
emp1,emp2,emp3,emp4等是表空间名称。

 

四.复合分区


【例一】

create table haha (
empno number(4),
ename varchar2(30),
hiredate date)
partition by range (hiredate)
subpartition by hash (empno)  
(partition e1 values less than (to_date('20020501','YYYYMMDD')),
partition e2 values less than (to_date('20021001','YYYYMMDD')),
partition e3 values less than (maxvalue));

上面例子中将雇员表先按照雇佣时间hiredate进行了范围分区,然后我们假设再把每个分区分为2个子hash分区。
例子中一共将产生2*3=6个分区,分区之中的分区被称为子分区。

    来看看如何维护表空间:

分区表存放在不同表空间,放在不同磁盘中,I/O就分散了,性能提高

公司的主要表一定是分区表


【模拟不同路径】
mkdir -p /oracle/app/oradata/ecom1/   
mkdir -p /oracle/app/oradata/ecom2/
mkdir -p /oracle/app/oradata/ecom3/
mkdir -p /oracle/app/oradata/ecom4/


sqlplus / as sysdba
grant create tablespace to scott;

conn scott/gongao

create tablespace ts01 logging datafile '/oracle/app/oradata/ecom1/ts01.dbf' size 10m;
create tablespace ts02 logging datafile '/oracle/app/oradata/ecom2/ts02.dbf' size 10m;
create tablespace ts03 logging datafile '/oracle/app/oradata/ecom3/ts03.dbf' size 10m;
create tablespace ts04 logging datafile '/oracle/app/oradata/ecom4/ts04.dbf' size 10m;

范围分区
SQL> create table test123(id number,createdate date)
    partition by range(createdate)
    (
    partition p1 values less than (to_date('2001-01-01','yyyy-mm-dd')) tablespace ts01,
    partition p2 values less than (to_date('2002-01-01','yyyy-mm-dd')) tablespace ts02,
    partition p3 values less than (to_date('2003-01-01','yyyy-mm-dd')) tablespace ts03,
    partition pmax values less than (maxvalue) tablespace ts04
   );


创建hash 分区表(按hash算法打散了,再分区,通常应用在不能划分范围的表)

SQL> create table test6 (id number,name varchar2(10))
    partition by hash(name)
    partitions 4
    store in (ts01,ts02,ts03,ts04);



创建列表分区                            
该分区的特点是某列的值只有几个,基于这样的特点我们可以采用列表分区。
比如城市,省份

SQL> create table test122 (id number,name varchar2(10),city varchar2(10))
    partition by list(city)
    (
    partition p1 values('bj','sh') tablespace ts01,
    partition p2 values('gz','sz') tablespace ts02,
    partition p3 values('cc','jl') tablespace ts03,
    partition p4 values(default) tablespace ts04
    );


查看分区表
SQL>  select * from user_tab_partitions order by table_name

——————————————————————————————————————————————————————


分区合并
范围分区合并
SQL> alter table test123 merge partitions p1,p2 into partition p12;

SQL> select * from user_tab_partitions order by table_name

——————————————————————————————————————————————————————


拆分分区

SQL> alter table test123 split partition pmax at(to_date('2004-01-01','yyyy-mm-dd')) into (partition p5,partition pmax);
把原来的pmax分区 拆分成2个分区

——————————————————————————————————————————————————————


创建新的分区
create tablespace ts05 logging datafile '/oracle/app/oradata/ecom/ts05.dbf' size 10m;

SQL> alter table test123 drop partition pmax;

SQL> alter table test123 add partition p15 values less than(to_date('2005-01-01','yyyy-mm-dd'))tablespace ts05;

create tablespace ts06 logging datafile '/oracle/app/oradata/ecom/ts06.dbf' size 10m;

SQL> alter table test123 add partition pnimei values less than(maxvalue)tablespace ts06;

——————————————————————————————————————————————————————

    下一篇将会介绍存储过程有关的知识

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值