堆表

数据以堆的形式管理,增加数据时会使用段中找到的第一个能放下数据的自由空间,我们见到的绝大部分的表都是堆表。堆表是数据库的默认表类型。

最简单的情况是

create table test (c1 varchar2(10),c2 varchar2(24),c3 number(9,3)) ;

然后使用tom kyte的方法,尽可能简单的创建表,调用dbms_metadata.get_ddl函数,查看详细定义,然后再根据这个详细版本,定制自己想要的版本。

set long 5000
select dbms_metadata.get_ddl('TABLE','TEST') from dual; CREATE TABLE "SCOTT"."TEST"
( "C1" VARCHAR2(10),
"C2" VARCHAR2(24),
"C3" NUMBER(9,3)
) SEGMENT CREATION DEFERRED
PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255
NOCOMPRESS LOGGING
TABLESPACE "USERS"

延迟段创建特性

11g以后的版本,段会延迟到插入数据才创建,如果想立即创建段使用segment creation immediate,默认为defereed 
可以使用数据字典表dba_segments或者all_segments确认

create table test
(c1 varchar2(10),c2 varchar2(24),c3 number(9,3))
segment creation immediate ;

表空间

如果不指定表空间,则使用表所在用户的默认表空间。 
指定表存储在users表空间里:

create table test (c1 varchar2(10),c2 varchar2(24),c3 number(9,3)) tablespace users;

PCTFREE和PCTUSED

PCTUSED如果使用ASSM(自动段空间管理)的话,会被忽略,绝大部分情况是这样的,oracle也推荐这样。 
PCTFREE用于在数据库块里预留空间用于更新,单到达设置比例后不会有新行插入该块,以免产生行迁移.

create table test (c1 varchar2(10),c2 varchar2(24),c3 number(9,3)) pctfree 20;

INITRANS

initrans控制数据库块头为事务预留的事务插槽个数,如果对该表进行插入和更新的事务非常多,建议将该值设置的稍微大一点。

create table test (c1 varchar2(10),c2 varchar2(24),c3 number(9,3)) initrans 10;

buffer_pool

使用什么缓存池来缓存该表的块 
一般使用默认设置即可, 即default 
对于访问非常频繁的表可以使用 keep池,(一般在其他优化手段测试后才使用这种方法),须首先设置db_keep_cache_size参数。

create table test (c1 varchar2(10),c2 varchar2(24),c3 number(9,3)) storage (buffer_pool keep);

logging和nologging

无论设置成那个在普通DML语句时都要产生日志文件,只有直接路径DML才有区别。绝大部分情况使用logging(默认)。只有在大量加载数据的情况下使用nologging来加快数据的加载

create table test (c1 varchar2(10),c2 varchar2(24),c3 number(9,3)) nologging storage (buffer_pool keep);

compress和nocompress

在直接路径加载或者传统路径加载启用或者禁用压缩。有nocompress(禁用压缩), 
compress对直接路径插入有效 
compress for oltp对直接路径和一般路径插入都有效

压缩的效果一般都比较好,如果cpu资源允许的情况下,可以使用压缩提高对数据库缓冲区缓存的使用效率,可以放更加多的数据了,对于全表扫描较多的应用程序来说是一个很好的优化。但是相应的会增加cpu的使用,使用前应该进行相应的测试。测试会不会对数据插入,修改造成影响。非常适合一次写入多次修改类型数据。

使用 
select blocks,avg_row_length,num_rows,compression,compress_for from user_tables where table_name='xxxxx' 
检查压缩前和压缩后效果差异

约束

可以在表创建时使用约束或者在表创建后增加、修改或者删除约束

约束分为行内约束和行外约束,行内约束指的是在定义列时候一起定义该列相关的约束。行外约束指的是单独一行定义约束。

create table test

c1 varchar2(10) primary key,
c2 varchar2(24) not null,
c3 number(9,3) constraint c3_check check(c3>100),
constarint c2_check check (c2 in ('China',
'Japan','USA'))
)
;

其中primary key 、not null、 c3_check为行内约束,c2_check为行外约束

约束的状态

enable 表示启用 
disable 表示不启用 
validate 表示当前表中所有数据都被验证了 
novalidate 表示当前表中的数据没有被验证。 
一般情况只需设置enable validate(默认) 
其它组合用于对大数据进行ETL时使用节省时间

还有一个表示约束是延迟起效还是立即起效。延迟起效表示在commit完成时进行检查约束是否正确,立即起效表示对该语句处理时进行判断是否满足约束 
默认情况是立即起效 
延迟起效的语法为 
deferred initially immediate|deferred 只有这样设置了的约束才能在事务控制时使用约束控制延迟。

null和not null约束

表示该列可不可以为空

unique约束

表示该列的值在表内必须唯一,但是可以为null

create table test

c1 varchar2(10),
c2 varchar2(24),
c3 number(9,3),
constraint pk_test primary key (c1,c2),
constraint uk_test unique (c3)
)
;

primary key约束

这些键表示的值在全表唯一且不为空(主键的所有列都不能为null),可以由单列作为主键或者多列组合作为主键

create table test

c1 varchar2(10),
c2 varchar2(24),
c3 number(9,3),
constraint pk_test primary key (c1,c2)
)
;

引用约束

用于表示父子表,使用引用约束的表为子表,被引用约束的表为父表

create table parent

c1 varchar2(10),
c2 varchar2(24),
c3 number(9,3),
constraint pk_test primary key (c1,c2)
)
; create table child

c1 varchar2(10),
c2 varchar2(24),
c3 number(9,3),
c4 number(9,3),
constraint fk_child foreign key (c1,c2) references parent(c1,c2)
)
;
//父表删除一行,子表和其关联的行被删除
create table child1

c1 varchar2(10),
c2 varchar2(24),
c3 number(9,3),
c4 number(9,3),
constraint fk_child foreign key (c1,c2) references parent(c1,c2) on delete cascade
)
; //父表删除一行,子表和其关联的行被删除
create table child2

c1 varchar2(10),
c2 varchar2(24),
c3 number(9,3),
c4 number(9,3),
constraint fk_child foreign key (c1,c2) references parent(c1,c2) on delete set null
)
;

引用约束还有一个和性能关系很大的条件,如果不对子表的引用列加上索引,当父表更新或者删除时会锁定整个子表。

check约束

用于检查某些条件,大于,小于,在一个集合里面等等

组合上述条件的例子

create table test
(c1 varchar2(10) primary key,
c2 varchar2(24),
c3 number(9,3),
constraint c2_c3_check check(c2 in ('China','USA') and c3>5.0)
enable validate) tablespace users pctfree 20 storage (buffer_pool keep);

索引组织表(IOT)

索引组织表是将数据存储在索引结构里。索引组织表中的数据按照主键存储和排序。索引组织表首先是对于信息的获取非常有利。其次由于是按索引进行存储的,索引的前缀部分相同的键会存储在一起。IOT表对于信息获取,空间应用和OLAP相当有用。

IOT表有三个属性很重要

compress N和nocompress

compress N表示对索引的前N项提取公因子。在重复度很高的情况下压缩性非常好。

可以对IOT表的主键使用 
analyze index iot_pk validate structure; 
然后查看index_stats表的opt_cmpr_count获取最优N值。

pctthreshold

表示行数据量超过块大小的这个百分比时,剩余的列放到overflow里去。

including

行中从第一列到该列为止都存储在叶子块里,剩余的列放到overflow里。

overflow

允许你创建另一个段,当数据行太长时溢出到这个段上来,以使IOT的叶子块尽量容纳更多的行。

IOT表的分区

分区键必须是主键的子集

create table line
(point_id varchar2(20),
line_id varchar2(20),
x number(10,3),
y number(10,3),
loc varchar2(20),
time date,
constraint pk_line primary key(line_id,point_id,time)
)
organization index
partition by range(time)
(partition p0 values less than (to_date('2016-1-1','yyyy-mm-dd'))
);

例子

使用including控制overflow
create table address
(
type varchar2(10),
location varchar2(200),
phone varchar2(20),
detail varchar2(800),
constraint pk_address primary key (type,location)
) organization index
including location overflow;
使用pctthreshold控制overflow
create table address
(
type varchar2(10),
location varchar2(200),
phone varchar2(20),
detail varchar2(800),
constraint pk_address primary key (type,location)
) organization index
pctthreshold 5 overflow; 使用including和pctthreshold的组合也是可以的,但是一般不是特别有用

外部表

分区表

分区是将一个表或者索引分成多个更小,更可管理的部分。逻辑上将只有一个表或索引,对外部使用该表的人而言,就是一个表和普通表没有任何分别,但是在物理上这一个表可以由多个分区组成,每个分区都是一个独立的对象,可以单独处理,或是作为一个更大的部分被处理。

分区表

区间分区

指定存储在一起的数据的区间,比如2016-3-1到2016-4-1的放在分区1,2016-4-1到2016-5-1的放在分区2,等等

常见使用方法有两种,常规区间分区和间隔分区 
但是不管是哪种分区方式,和普通表一样,可以在表后面指定PCTFREE、INITRANS、存储性质(基本上就是buffer_pool)、表空间等物理属性。如果分区没有覆写这些属性,则分区和表的这些性质保持一致 
当然,每个分区后都可以指定PCTFREE、INITRANS、存储性质(基本上就是buffer_pool)、表空间等物理属性

常规区间分区

语法结构为

partition by range (column_name)
(partition name1 values less than (value1),
partition name2 values less than (valuee2),
....
partition last_part values less than (maxvalue));

最后一个小于maxvalue是为了让所有情况都可以被表所包含。这里的小于,指的是严格小于,等于不包含在内。

举个例子

create table log
(
text varchar2(255),
rksj date
)
pctfree 20 storage(buffer_pool default)
partition by range(rksj)
(
partition part_2016_3 values less than (to_date('2016-3-1','yyyy-mm-dd')),
partition part_2016_4 values less than (to_date('2016-4-1','yyyy-mm-dd')) pctfree 10 storage(buffer_pool keep),
partition part_other values less than (maxvalue)
)

可以使用alter table修改分区的物理属性

alter table log modify partition part_2016_3 storage(buffer_pool keep);

间隔区间分区

间隔分区是从oracle 11gr1开始新增加的一个特性,以一个分区为起点,设置一个规则(间隔),让oracle根据该规则知道以后该怎么增加分区。这样就不需要预先设置好所有的分区了,oracle在插入数据时知道自己去创建分区。间隔分区的键值应该是可以和number、interval进行相加的列。

对于任何合适的现有区间分区表,都可以使用alter table修改为间隔区间分区表。

语法

partition by range (column_name) interval  (expr) store in (tablespace1,tablespace2,....)
(partition name1 values less than (value1),
partition name2 values less than (valuee2),
....);

一般间隔分区只需创建一个起始分区即可.

create table log
(
text varchar2(255),
rksj date
)
pctfree 20 storage(buffer_pool default)
partition by range(rksj) interval (numtoyminterval(1,'month'))
(
partition part_2016_3 values less than (to_date('2016-3-1','yyyy-mm-dd'))
)

间隔分区的缺点

11g开始oracle增加了interval分区,和range分区最大的区别就是它会根据数据自动去创建分区。 
但是它有以下缺点 
1. 第一个分区不能删除,因为它是参考,删除会报ora-14758错误。 
2. 分区没有便于管理的名称 
3. 如果创建索引时指定了多个分区,则这些分区之间是不会应用interval继续分区了。只有大于这其中的值才会开始分区 
4. 不能执行分区的循环使用??

ora-14758错误解决方法 
先将间隔分区表转化为普通range分区表 
alter table table_name set interval (); 
删除指定分区后再将间隔设置回来 
alter table table_name set interval (numtodsinterval(1,’DAY’));

散列分区

散列分区是在一个列或者多个列上引用散列函数,行会按散列值放到不同的分区上去。oracle建议分区数应该是2的一个幂次方(2,4,8,16,。。。)。

散列分区的目的是让数据很好的分布在多个不同的设备上,或者将数据聚集到更可管理的块上,所以散列键应该是唯一的列或者至少有足够的相异值。以便数据能在多个分区上均匀的分布。

partition  by hash (column1,column2,...)
(
partition part1 tablespace ts_name1,
partition part2,
..... )

其它物理属性不能在这里设置。

或者

partition by hash (column1,column2,...) partitions n store in (ts_name1,ts_name2,...);
create table log
(
id number(10),
text varchar2(255),
rksj date
)
partition by hash(id)
(
partition part1 tablespace users ,
partition part2,
partition part3 tablespace ts_test,
partition part4
); create table log
(
id number(10),
text varchar2(255),
rksj date
)
partition by hash(id) partitions 4
store in (users,ts_test);

列表分区

根据离散的值决定数据该放在哪个分区里。

partition by list(column1,...)
(
partition part1 values (value1,value2),
partition part2 values (value3,value4),
.....
partition part_default (default)
)

如果设置了default分区,则不能再增加分区了,只能删除default分区才能增加分区

create table data
(
rawdata raw(200),
status varchar2(1)
)
partition by list(status)
(
partition part_u values ('u') tablespace users storage(buffer_pool keep),
partition part_p values ('p')tablespace ts_test,
partition part_def values (default)
);

引用分区

引用分区是oracle 11gr1引入的新特性,要以某种方式 
对子表进行分区,使得子表的分区和父表的保持一对一的关系。

create table orders
(
order# number(10) primary key,
order_date date,
data varchar2(100)
)
partition by range(order_date)
(
partition part_2015 values less than (to_date('2016-1-1','yyyy-mm-dd')),
partition part_2016 values less than (to_date('2017-1-1','yyyy-mm-dd'))
); create table order_items
(
order# number(10),
item# number(10),
price number(5,2),
description varchar2(200),
constraint pk_order_items primary key(order#,item#),
constraint fk_order_items foreign key(order#) references orders(order#)
)
partition by reference (fk_order_items);

组合分区表

的range,list和hash分区,在这些分区的基础上再进行分区。 
每种分区都可以进行range,list和hash子分区。

例子

在区间分区的基础上散列分区
create table log
(
id number(10),
text varchar2(200),
logtime date,
type varchar2(1)
)
partition by range(logtime)
subpartition by hash(id) subpartitions 10 store in (users,ts_test)
(partition part_2015 values less than (to_date('2016-1-1','yyyy-mm-dd')),
partition part_2016 values less than (to_date('2017-1-1','yyyy-mm-dd'))
); 区间分区上列表分区
create table log
(
id number(10),
text varchar2(200),
logtime date,
type varchar2(1)
)
partition by range(logtime)
subpartition by list(type)
subpartition template
(
subpartition part_a values ('A') tablespace users,
subpartition part_b values ('B') tablespace ts_test,
subpartition part_cd values ('C','D') tablespace users
)
(partition part_2015 values less than (to_date('2016-1-1','yyyy-mm-dd')),
partition part_2016 values less than (to_date('2017-1-1','yyyy-mm-dd'))
); create table log
(
id number(10),
text varchar2(200),
logtime date,
type varchar2(1)
)
partition by hash(id)
subpartition by list(type)
subpartition template
(
subpartition part_a values ('A') tablespace users,
subpartition part_b values ('B') tablespace ts_test,
subpartition part_cd values ('C','D') tablespace users
)
partitions 8 store in (users,ts_test)
;

聚簇表

索引聚簇表

聚簇表的理念是将数据按照我们想要的方式(聚簇)将多个表预联结在一起,即放在同一个块上。聚簇也可用于单个表,按某个列 
将数据分组存储。

create cluster emp_dept_cluster
(deptno number(2))
size 1024; select dbms_metadata.get_ddl('CLUSTER','EMP_DEPT_CLUSTER') from dual; DBMS_METADATA.GET_DDL('CLUSTER','EMP_DEPT_CLUSTER')
-------------------------------------------------------------------------------- CREATE CLUSTER "SCOTT"."EMP_DEPT_CLUSTER" (
"DEPTNO" NUMBER(2,0) )
SIZE 1024
PCTFREE 10 PCTUSED 40 INITRANS 2 MAXTRANS 255
STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1
BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT)
TABLESPACE "USERS"
PARALLEL (DEGREE 1 INSTANCES 1)

其中size是聚簇最重要的一个参数,意思是每个键值大概关联多大的空间,这里是1024B,对于大小为8KB的块可以放下7个键。如果设置的太大会浪费空间,如果设置太小又会过度串链,违背了聚簇就是为了将相关数据放在一起的本意。

向聚簇中放数据之前,首先要为聚簇创建索引,然后就可以创建聚簇表了。聚簇索引的任务就是拿到一个键值,然后返回包含这个键值的块地址。

create index idx_emp_dept_cluster on cluster emp_dept_cluster;

create table dept
(deptno number(2),
dname varchar2(20),
loc varchar2(20))
cluster emp_dept_cluster(deptno); create table emp
(
empno number(10) primary key,
name varchar2(20),
mgr number(10),
sal number(8,2),
deptno number(2)
)
cluster emp_dept_cluster(deptno);

聚簇表没有tablespace这些段属性,因为这些属性都在聚簇上定义。

不适合索引聚簇表的情况

  1. 有大量修改的情况
  2. 经常需要全表扫描的情况
  3. 需要进行分区,聚簇和聚簇表都是不能分区的。
  4. 需频繁的truncate和加载,聚簇中的表不能truncate,这是因为聚簇中有多个表放在一起,显然就不能truncate。

适合情况

主要用于读,且通过索引来读,另外会频繁的把信息联结起来使用。

散列聚簇表

基本和索引聚簇表一样,就是将索引换成了散列函数。oracle获取一列的值,通过散列函数得到一个值,然后通过这个值获得数据所在的块。使用散列的缺点是无法进行 扫描,只要是范围扫描则必须执行全表扫描。

块的计算

散列聚簇表的块数是预先分配好的。由散列聚簇表的hashkeys和size加上块的大小得到,即trunc(hashkeys*size/blocksize)

例子

create cluster hash_cluster
(hash_key number(10)
)
hashkeys 10000
size 8192
tablespace users; create table hash_table1
(
x number(10),name varchar2(10)
) cluster hash_cluster(x); create table hash_table2
(
x number(10),loc varchar2(10)
) cluster hash_cluster(x);

散列聚簇表还可以使用单表散列聚簇表

create cluster hash_cluster 
(hash_key number(10) 

hashkeys 10000 
size 8192 
single table 
tablespace users;

临时表

用于保存事务或者会话期间的中间结果。临时表中保存的数据只对当前会话可见,分为两种情况,一种是事务一结束数据就被清空。一种是事务结束后依然存在。使用临时表生成的redo数据要少。

create global temporary med 
(name varchar2(10), 
phone varchar2(20) 

on commit delete rows;

create global temporary med 
(name varchar2(10), 
phone varchar2(20) 

on commit preserve rows;

oracle表相关的更多相关文章

  1. oracle表分区以及普表转分区表(转)

    概述 Oracle的表分区功能通过改善可管理性.性能和可用性,从而为各式应用程序带来了极大的好处.通常,分区可以使某些查询以及维护操作的性能大大提高.此外,分区还可以极大简化常见的管理任务,分区是构建 ...

  2. oracle表分区详解

    原文来自:http://www.cnblogs.com/leiOOlei/archive/2012/06/08/2541306.html oracle表分区详解 从以下几个方面来整理关于分区表的概念及 ...

  3. Oracle表空间管理

    oracle表空间相关常用命令小结: 1.ALTER DATABASE SET DEFAULT BIGFILE TABLESPACE;              //修改表空间数据文件类型 2.ALT ...

  4. 【转】Oracle 表空间与数据文件

    --============================== --Oracle 表空间与数据文件 --============================== /* 一.概念 表空间:是一个或 ...

  5. 【应用】:shell crontab定时生成oracle表的数据到txt文件,并上传到ftp

    一.本人环境描述      1.oracle服务端装在win7 32位上,oracle版本为10.2.0.1.0      2.Linux为centos6.5 32位,安装在Oracle VM Vir ...

  6. Oracle表空间详解

    Oracle表空间详解 1.表空间的分类 Oracle数据库把表空间分为两类:系统表空间和非系统表空间. 1.1系统表空间指的是数据库系统创建时需要的表空间,这些表空间在数据库创建时自动创建,是每个数 ...

  7. nagios监控oracle 表空间

    oracle表空间满的危害以及处理方式见我的博客链接https://www.cnblogs.com/-abm/p/9764803.html 除此之外我们还需要对表空间实时监控,这样就可以及时了解表空间 ...

  8. ORACLE表空间操作实例

    本文主要介绍oracle表空间常见的操作实例,包括创建.查询.增加.删除.修改.表空间和数据文件常用的数据字典和动态性能视图包括v$dbfile.v$datafile.v$tempfile.dba_s ...

  9. Oracle 表空间与数据文件

    -============================== --Oracle 表空间与数据文件 --============================== /* 一.概念 表空间:是一个或多 ...

随机推荐

  1. mysql模拟rownum的一个方法

    mysql> select * from t2; +----+---------------------+ | id | d | +----+---------------------+ :: ...

  2. ThroughRain第二次冲刺总结

    团队名:ThroughRain 项目确定:<餐厅到店点餐系统> 项目背景:本次项目是专门为餐厅开发的一套订餐系统.大家有没有发现在节假日去餐厅吃饭会超级麻烦,人很多, 热门的餐厅基本没有座 ...

  3. RCU-数据库初始化参数

    C:\Windows\System32>sqlplus sys/As123456 as sysdba SQL> show parameter processes; SQL> shut ...

  4. 重新想象 Windows 8.1 Store Apps (91) - 后台任务的新特性: 下载和上传的新特性, 程序启动前预下载网络资源, 后台任务的其它新特性

    [源码下载] 重新想象 Windows 8.1 Store Apps (91) - 后台任务的新特性: 下载和上传的新特性, 程序启动前预下载网络资源, 后台任务的其它新特性 作者:webabcd 介 ...

  5. Linux守护进程实现程序只运行一次

    1.守护进程 守护进程(Daemon)是一种运行在后台的特殊进程,它独立于控制终端并且周期性的执行某种任务或等待处理某些发生的事件. 2.让程序只运行一次 如果让程序只运行一次,有很多方法,此处的一种 ...

  6. 泛函编程(8)-数据结构-Tree

    上节介绍了泛函数据结构List及相关的泛函编程函数设计使用,还附带了少许多态类型(Polymorphic Type)及变形(Type Variance)的介绍.有关Polymorphism的详细介绍会 ...

  7. 面向企业客户的制造业CRM系统的不成熟思考

    CRM就是客户关系管理(Customer Relationship Management),一直一知半解,最近有涉及这方面的需求,所以稍作研究,并思考一些相关问题. CRM是什么? CRM具体如何定义 ...

  8. ABAP->内表数据下载到CSV格式(原创转载请注明)

    需求:将alv上面的数据计算到内表中区,然后通过自定义按钮进行下载到csv格式中 附加:现在基本不用csv导出了,但是有些变态需求强行要求,也只好研究出来了,excel与txt导出很简单,那就不多说了 ...

  9. mongodb 基本指令学习 (2)

    db.collectionname.find(<criteria>, <projection>) <criteria>   可选   类型 文档    文档的过滤条 ...

  10. c#多线程生产者消费者(手稿)

    屋舍简陋,隔壁的娃娃哭了一晚,心中无恶意纯中性的想,有病就赶紧带孩子去看医生吧,能哭这么久估计孩子真的不舒服.