约束条件用于保证数据的完整性。主要有主键约束(primary key)/非空约束(not null)、惟一约束(unique) 检查约束(check)和外键约束(foreign key).css
主键约束包括了非空和惟一html
create table 表名(字段名 字段类型(长度) 约束条件);java
1.建立本身定义名称约束git
create table 表名(字段名 字段类型(长度),constraint 约束名 约束类型(字段名));github
注:可以经过user_constraints数据字典来查询约束。sql
create table t_test(id number(10);sex char(2); constraint test_sex check (sex in('男'。‘女’)));--可以经过在字段后面加 default 值。来设置默认值;在使用默认值时使用defaultkeyword。数据库
注:元组上的约束的定义oracle
元组级别的限制可以设置不一样属性之间取值的相互约束条件函数
check(ssex='女' or sname NOT like 'MS.%');--当学生性别为男时。其名字不能以MS.开头。post
外键字段可以为空,或者引用自依赖的父项。
1.赋予空值
foreign key(外键字段) references 表名(字段) on delete set null;
2.级联删除
foreign key(外键字段) references 表名(字段) on delete cascade;
constraint pk_t_emp primary key (字段1,字段2);
alter table 表名 drop contraints 约束名称。
alter table 表名 add contraints 约束名称 约束类型(字段);
alter table 表名 modify (字段 字段类型 要加入的约束);
1.create or replace view 视图名 as select * from emp;
2.视图是一种虚拟的表,具备和物理表一样的功能,可以对视图进行增、改和查询。
视图通常是一个表或多个表的行或列的子集。
3.对视图的改动不影响基本表。
4.视图使咱们得到数据更easy。
注:
复杂视图的定义是。视图中的数据不能直接经过表得到,必须经过计算来得到;复杂视图的查询字段必须取别名。
序列是数据库中特有的一组可以实现本身主动增加的数字。
create sequence 序列名 increment by 每次增加的步长 start with 起始值。
1.select 序列名.nextval from dual.--获取序列的下一个值;获取序列的当前值採用currval属性。
oracle特有的默认提供给每一个表的。以便实现某些功能。
表示每条记录的序号(查到结果集后才分配的序号),常常常使用于分页。
表示每条记录的惟一标识(一组32为的字符串),可用来获取记录的物理地址
样例1:删除表中的一样记录
方法一:
delete from t_table t1 where t1.rowid!=(select max(rowid) from t_table t2 where t1.id=t2.id and t.name=t2.name);;--当中 t1.id=t2.id and t.name=t2.name是定义一样记录的条件
方法二:
delete from t_table where roeid not in(select max(rowid) from t_table group by 字段一,字段二);
样例1:删除表中不反复的记录
delete from t_table t1 where t1.rowid=(select max(rowid) from t_table t2 where t1.id=t2.id and t.name=t2.name) and t1.rowid=(select min(rowid) from t_table t2 where t1.id=t2.id and t.name=t2.name) ;
1.三目运算来计算总页数 totalpage=sum/pagesize+sum%pagesize==0?0:1;//计算总页数,sum为总记录数
2.第page页的记录的起始位置和结束位置分别为:
pagesize*(page-1)+1。起始位置
pagesize*page;j、结束位置
注:
1.可以使用差集(minus)在数据库查询中实现分页,但效率低'
2.常用子查询将rownum做为还有一结果集的字段来实现分页。
select ee.* from(select e.* , rownum rr from (select * from emp where sal is not null order by sal ) e )ee where ee.rr berween &start and &end。
3.rownum的分页地java代码演示样例
package com.zhongxin.backstage.biz.impl; import java.util.List; import com.zhongxin.backstage.bean.CardPage; import com.zhongxin.backstage.bean.PlatePage; import com.zhongxin.backstage.biz.CardContextBiz; import com.zhongxin.backstage.dao.CardContextDao; import com.zhongxin.backstage.dao.PlateContextDao; import com.zhongxin.exception.DAOException; import com.zhongxin.entity.MainCard; import com.zhongxin.entity.Plate; import com.zhongxin.factory.Factory; import com.zhongxin.util.DeleteSpaceUtil; public class CardContextBizImpl implements CardContextBiz { private int pageSize=10; private CardContextDao dao=(CardContextDao) Factory.getImpl("CardContextDaoImpl");//定义dao层 public CardPage searchAllCard(int pageNum) throws DAOException { // 获取所有的帖子 //计算分页的页面总数 CardPage cardPage=(CardPage) Factory.getImpl("CardPage"); String sql="select count(*) from tb_mainCard "; int totalCount=dao.getTotalCount(sql); int totalPage=(totalCount/this.getPageSize())+(totalCount%this.getPageSize()==0?0:1); //处理请求页面大于总页面的状况 if(pageNum>totalPage){ pageNum=totalPage; } if(pageNum<=0){ pageNum=1; } cardPage.setTotalPage(totalPage); cardPage.setCurrPage(pageNum); if(totalCount==0){ return cardPage; } //使用基于查询的分页 int start=(pageNum-1)*this.getPageSize()+1; int end=pageNum*this.getPageSize(); //调用dao层的方法获取显示数据 List list=dao.searchCardByPage(start,end); cardPage.setCard(list); return cardPage; } public int getPageSize() { return pageSize; } public void setPageSize(int pageSize) { this.pageSize = pageSize; } public CardContextDao getDao() { return dao; } public void setDao(CardContextDao dao) { this.dao = dao; } public CardPage searchCardById(int pageNum,long id) throws DAOException { //依据id获取主贴信息 //计算分页的页面总数 CardPage cardPage=(CardPage) Factory.getImpl("CardPage"); String sql="select count(*) from tb_mainCard where cardId="+id; int totalCount=dao.getTotalCount(sql); int totalPage=(totalCount/this.getPageSize())+(totalCount%this.getPageSize()==0?0:1); //处理请求页面大于总页面的状况 if(pageNum>totalPage){ pageNum=totalPage; } if(pageNum<=0){ pageNum=1; } cardPage.setTotalPage(totalPage); cardPage.setCurrPage(pageNum); if(totalCount==0){ return cardPage; } //使用基于查询的分页 int start=(pageNum-1)*this.getPageSize()+1; int end=pageNum*this.getPageSize(); //调用dao层的方法获取显示数据 List list=dao.searchCardByPage(start,end,id); cardPage.setCard(list); return cardPage; } public CardPage searchAllCardBySendPeople(int pageNum, String name) throws DAOException { //依据发帖人获取主贴细信息 //计算分页的页面总数 CardPage cardPage=(CardPage) Factory.getImpl("CardPage"); String sql="select count(*) from tb_mainCard where name='"+name+"'"; int totalCount=dao.getTotalCount(sql); int totalPage=(totalCount/this.getPageSize())+(totalCount%this.getPageSize()==0?0:1); //处理请求页面大于总页面的状况 if(pageNum>totalPage){ pageNum=totalPage; } if(pageNum<=0){ pageNum=1; } cardPage.setTotalPage(totalPage); cardPage.setCurrPage(pageNum); if(totalCount==0){ return cardPage; } //使用基于查询的分页 int start=(pageNum-1)*this.getPageSize()+1; int end=pageNum*this.getPageSize(); //调用dao层的方法获取显示数据 List list=dao.getCardByPageAndPeopleName(start,end,name); cardPage.setCard(list); return cardPage; } public CardPage searchAllCardByTime(int pageNum, String time) throws DAOException { // 依据时间获取主贴 //计算分页的页面总数 if(time.contains(".")){ time=time.substring(0,time.lastIndexOf("."));//去掉时间的秒的小数点 } CardPage cardPage=(CardPage) Factory.getImpl("CardPage"); String sql="select count(*) from tb_mainCard where time=to_date('"+time+"','yyyy-mm-dd hh24:mi:ss')"; //System.out.println(sql); int totalCount=dao.getTotalCount(sql); int totalPage=(totalCount/this.getPageSize())+(totalCount%this.getPageSize()==0?0:1); //处理请求页面大于总页面的状况 if(pageNum>totalPage){ pageNum=totalPage; } if(pageNum<=0){ pageNum=1; } cardPage.setTotalPage(totalPage); cardPage.setCurrPage(pageNum); if(totalCount==0){ return cardPage; } //使用基于查询的分页 int start=(pageNum-1)*this.getPageSize()+1; int end=pageNum*this.getPageSize(); //调用dao层的方法获取显示数据 String sql2="select * from (select rownum r,t.* from ("+"select * from tb_mainCard where time=to_date('"+time+"','yyyy-mm-dd hh24:mi:ss')"+") t) t1" + " where t1.r between "+start+" and "+end; List list=dao.getCard(sql2); cardPage.setCard(list); return cardPage; } //SQL> select * from emp where hiredate between (to_date('1981-2-20','yyyy-mm-dd')) and (to_date('1981-2-23','yyyy-mm-dd')); public CardPage searchAllCardByTimeInnerOneDay(int pageNum, String time) throws DAOException { //依据某个时间点的一天内查询的主贴 //计算分页的页面总数 if(time.contains(".")){ time=time.substring(0,time.lastIndexOf("."));//去掉时间的秒的小数点 } CardPage cardPage=(CardPage) Factory.getImpl("CardPage"); String sql="select count(*) from tb_mainCard where time between to_date('"+time+"','yyyy-mm-dd hh24:mi:ss')"+"and to_date('"+time+"','yyyy-mm-dd hh24:mi:ss')+1"; //System.out.println(sql); int totalCount=dao.getTotalCount(sql); int totalPage=(totalCount/this.getPageSize())+(totalCount%this.getPageSize()==0?0:1); //处理请求页面大于总页面的状况 if(pageNum>totalPage){ pageNum=totalPage; } if(pageNum<=0){ pageNum=1; } cardPage.setTotalPage(totalPage); cardPage.setCurrPage(pageNum); if(totalCount==0){ return cardPage; } //使用基于查询的分页 int start=(pageNum-1)*this.getPageSize()+1; int end=pageNum*this.getPageSize(); //调用dao层的方法获取显示数据 String sql2="select * from (select rownum r,t.* from ("+"select * from tb_mainCard where time between to_date('"+time+"','yyyy-mm-dd hh24:mi:ss')"+"and to_date('"+time+"','yyyy-mm-dd hh24:mi:ss')+1"+") t) t1" + " where t1.r between "+start+" and "+end; List list=dao.getCard(sql2); cardPage.setCard(list); return cardPage; } public CardPage searchAllCardByOrderTime(int pageNum, String time) throws DAOException { // 依据查询某个时间点至今的有主贴,并按时间排序 //计算分页的页面总数 if(time.contains(".")){ time=time.substring(0,time.lastIndexOf("."));//去掉时间的秒的小数点 } CardPage cardPage=(CardPage) Factory.getImpl("CardPage"); String sql="select count(*) from tb_mainCard where time between to_date('"+time+"','yyyy-mm-dd hh24:mi:ss')"+"and sysdate"; //System.out.println(sql); int totalCount=dao.getTotalCount(sql); int totalPage=(totalCount/this.getPageSize())+(totalCount%this.getPageSize()==0?0:1); //处理请求页面大于总页面的状况 if(pageNum>totalPage){ pageNum=totalPage; } if(pageNum<=0){ pageNum=1; } cardPage.setTotalPage(totalPage); cardPage.setCurrPage(pageNum); if(totalCount==0){ return cardPage; } //使用基于查询的分页 int start=(pageNum-1)*this.getPageSize()+1; int end=pageNum*this.getPageSize(); //调用dao层的方法获取显示数据 String sql2="select * from (select rownum r,t.* from ("+"select * from tb_mainCard where time between to_date('"+time+"','yyyy-mm-dd hh24:mi:ss')"+"and sysdate"+") t) t1" + " where t1.r between "+start+" and "+end+" order by time "; List list=dao.getCard(sql2); cardPage.setCard(list); return cardPage; } public CardPage searchAllCardBySubject(int pageNum, String subject) throws DAOException { //依据主题获取主贴信息 CardPage cardPage=(CardPage) Factory.getImpl("CardPage"); String sql="select count(*) from tb_mainCard where subject='"+subject+"'"; //System.out.println(sql); int totalCount=dao.getTotalCount(sql); int totalPage=(totalCount/this.getPageSize())+(totalCount%this.getPageSize()==0?0:1); //处理请求页面大于总页面的状况 if(pageNum>totalPage){ pageNum=totalPage; } if(pageNum<=0){ pageNum=1; } cardPage.setTotalPage(totalPage); cardPage.setCurrPage(pageNum); if(totalCount==0){ return cardPage; } //使用基于查询的分页 int start=(pageNum-1)*this.getPageSize()+1; int end=pageNum*this.getPageSize(); //调用dao层的方法获取显示数据 String sql2="select * from (select rownum r,t.* from ("+"select * from tb_mainCard where subject='"+subject+"') t) t1" + " where t1.r between "+start+" and "+end+" order by subject "; List list=dao.getCard(sql2); cardPage.setCard(list); return cardPage; } public CardPage searchAllCardByLikeSubject(int pageNum, String subject) throws DAOException { //依据帖子的主题查询主贴支持模糊查询 subject=DeleteSpaceUtil.deleteSpace(subject);//除掉模糊查询的keyword的中间空白 CardPage cardPage=(CardPage) Factory.getImpl("CardPage"); String sql="select count(*) from tb_mainCard where subject like '%"+subject+"%'"; //System.out.println(sql); int totalCount=dao.getTotalCount(sql); int totalPage=(totalCount/this.getPageSize())+(totalCount%this.getPageSize()==0?0:1); //处理请求页面大于总页面的状况 if(pageNum>totalPage){ pageNum=totalPage; } if(pageNum<=0){ pageNum=1; } cardPage.setTotalPage(totalPage); cardPage.setCurrPage(pageNum); if(totalCount==0){ return cardPage; } //使用基于查询的分页 int start=(pageNum-1)*this.getPageSize()+1; int end=pageNum*this.getPageSize(); //调用dao层的方法获取显示数据 String sql2="select * from (select rownum r,t.* from ("+"select * from tb_mainCard where subject like '%"+subject+"%') t) t1" + " where t1.r between "+start+" and "+end+" order by time "; List list=dao.getCard(sql2); cardPage.setCard(list); return cardPage; } public CardPage searchAllCardByNum(int pageNum, int num) throws DAOException { //依据回帖数查询主贴 CardPage cardPage=(CardPage) Factory.getImpl("CardPage"); String sql="select count(*) from tb_mainCard where replyNum="+num; //System.out.println(sql); int totalCount=dao.getTotalCount(sql); int totalPage=(totalCount/this.getPageSize())+(totalCount%this.getPageSize()==0?0:1); //处理请求页面大于总页面的状况 if(pageNum>totalPage){ pageNum=totalPage; } if(pageNum<=0){ pageNum=1; } cardPage.setTotalPage(totalPage); cardPage.setCurrPage(pageNum); if(totalCount==0){ return cardPage; } //使用基于查询的分页 int start=(pageNum-1)*this.getPageSize()+1; int end=pageNum*this.getPageSize(); //调用dao层的方法获取显示数据 String sql2="select * from (select rownum r,t.* from ("+"select * from tb_mainCard where replyNum="+num+") t) t1" + " where t1.r between "+start+" and "+end+" order by replyNum "; List list=dao.getCard(sql2); cardPage.setCard(list); return cardPage; } public CardPage searchAllCardByGreateNum(int pageNum, int num) throws DAOException { // if(num<0){ num=0; } CardPage cardPage=(CardPage) Factory.getImpl("CardPage"); String sql="select count(*) from tb_mainCard where replyNum>="+num; //System.out.println(sql); int totalCount=dao.getTotalCount(sql); int totalPage=(totalCount/this.getPageSize())+(totalCount%this.getPageSize()==0?0:1); //处理请求页面大于总页面的状况 if(pageNum>totalPage){ pageNum=totalPage; } if(pageNum<=0){ pageNum=1; } cardPage.setTotalPage(totalPage); cardPage.setCurrPage(pageNum); if(totalCount==0){ return cardPage; } //使用基于查询的分页 int start=(pageNum-1)*this.getPageSize()+1; int end=pageNum*this.getPageSize(); //调用dao层的方法获取显示数据 String sql2="select * from (select rownum r,t.* from ("+"select * from tb_mainCard where replyNum>="+num+") t) t1" + " where t1.r between "+start+" and "+end+" order by replyNum "; List list=dao.getCard(sql2); cardPage.setCard(list); return cardPage; } public CardPage searchAllCardByPerfectCard(int pageNum, String perfectCard) throws DAOException { // 查看精品帖 //进行页面显示的内容与数据库的表示转化 int num=0; if("yes".equals(perfectCard)){ String sql="select count(*) from tb_mainCard where perfectCard!="+num; System.out.println(sql); CardPage cardPage=(CardPage) Factory.getImpl("CardPage"); //System.out.println(sql); int totalCount=dao.getTotalCount(sql); int totalPage=(totalCount/this.getPageSize())+(totalCount%this.getPageSize()==0?0:1); //处理请求页面大于总页面的状况 if(pageNum>totalPage){ pageNum=totalPage; } if(pageNum<=0){ pageNum=1; } cardPage.setTotalPage(totalPage); cardPage.setCurrPage(pageNum); if(totalCount==0){ return cardPage; } //使用基于查询的分页 int start=(pageNum-1)*this.getPageSize()+1; int end=pageNum*this.getPageSize(); //调用dao层的方法获取显示数据 String sql2="select * from (select rownum r,t.* from ("+"select * from tb_mainCard where perfectCard!="+num+") t) t1" + " where t1.r between "+start+" and "+end+""; List list=dao.getCard(sql2); cardPage.setCard(list); return cardPage; }else{ String sql="select count(*) from tb_mainCard where perfectCard="+num; CardPage cardPage=(CardPage) Factory.getImpl("CardPage"); //System.out.println(sql); int totalCount=dao.getTotalCount(sql); int totalPage=(totalCount/this.getPageSize())+(totalCount%this.getPageSize()==0?0:1); //处理请求页面大于总页面的状况 if(pageNum>totalPage){ pageNum=totalPage; } if(pageNum<=0){ pageNum=1; } cardPage.setTotalPage(totalPage); cardPage.setCurrPage(pageNum); if(totalCount==0){ return cardPage; } //使用基于查询的分页 int start=(pageNum-1)*this.getPageSize()+1; int end=pageNum*this.getPageSize(); //调用dao层的方法获取显示数据 String sql2="select * from (select rownum r,t.* from ("+"select * from tb_mainCard where perfectCard="+num+") t) t1" + " where t1.r between "+start+" and "+end+""; List list=dao.getCard(sql2); cardPage.setCard(list); return cardPage; } } public CardPage searchAllCardByPlateName(int pageNum, String plateName) throws DAOException { //依据板块获取主贴 CardPage cardPage=(CardPage) Factory.getImpl("CardPage"); String sql="select count(*) from tb_mainCard where plateName='"+plateName+"'"; //System.out.println(sql); int totalCount=dao.getTotalCount(sql); int totalPage=(totalCount/this.getPageSize())+(totalCount%this.getPageSize()==0?0:1); //处理请求页面大于总页面的状况 if(pageNum>totalPage){ pageNum=totalPage; } if(pageNum<=0){ pageNum=1; } cardPage.setTotalPage(totalPage); cardPage.setCurrPage(pageNum); if(totalCount==0){ return cardPage; } //使用基于查询的分页 int start=(pageNum-1)*this.getPageSize()+1; int end=pageNum*this.getPageSize(); //调用dao层的方法获取显示数据 String sql2="select * from (select rownum r,t.* from ("+"select * from tb_mainCard where plateName='"+plateName+"') t) t1" + " where t1.r between "+start+" and "+end+" order by replyNum "; List list=dao.getCard(sql2); cardPage.setCard(list); return cardPage; } public boolean deleteCardById(long id) throws DAOException { //删除主贴 int num =dao.deleteCardById(id); //System.out.println(num); if(num==1){ return true; }else{ return false; } } public boolean deleteCardById(String[] arrId) throws DAOException { //删除选中的主贴 return dao.deleteCardByArrId(arrId); } }
高速的查找定位到某条记录(底层採用rowid来实现);没有索引查找时,将採用全表扫描(full table scan)
注:
1.查找索引可以使用user_indexes数据字典。
2数据库.默以为表中的主键和惟一键创建索引。
create index 索引名 on 表名(字段名)。
1.常常进行更新操做的字段
2.表小,查询结果集大
3.不常用的字段
1.经常用来查询的字段
2.当表的数据量很是大且查询的结果集较小
3.当前字段值很是多为空的字段
4.经常用来做为联合查询的字段
5.外键字段
注:说说你对索引的认识(索引的结构、对dml的影响、对查询的影响和为何提升查询性能)?
1。
索引有b-tree和cluster等类型。oracle使用了一个复杂的自平衡b-tree结构。
2.一般来讲在表上创建适当的索引,在查询时会改进查询性能。
3.但在进行插入、改动和删除是。同一时候会进行索引的改动,在性能上有必定的影响。索引一般可以提升select、update和delete的性能。但会下降insert的速度。
4,。有索引且在查询条件使用索引时,数据库会先读取索引,再依据索引内容和查询条件来查询出rowid,最后依据rowid取出需要的数据。
由于索引内容一般比全表内容要少很是多,所以经过先读索引可以下降I/O,提升查询性能。
1.避免对索引字段进行计算操做
2.避免在索引字段上使用not、<、>、和!=
3.避免在索引列上使用is null 和 is not null。
4.避免在索引列上出现数据类型转换
5.避免在索引字段上使用函数
6.避免在创建索引的列中使用空值.
存储描写叙述对象(表。序列、视图、触发器、过程、函数等)信息的表或视图称为数据字典。
user_tables/user_constraints/user_indexes/user_sequences/user_views/user_objects
好比:select distinct object——type from user_objects;--查看所有的对象
user_all_XXX 当前用户所能訪问的对象的数据字典
dba_xxx 当前数据库下得所有对象的数据字典
一个数据库划分为一个或多个逻辑单元,该逻辑单元称为表空间。block(块)组成extent(长度),extent组成segment(段)。segment组成tablespace。
1.block是Oracle中存储数据块的最小单位,因此数据终于都是存储在block中。它也被称为逻辑blocks或是页(pages)。
2.每一个操做系统都有本身的block size。
而这里的block是Oracle本身的,不一样于OS的blocks。可以经过设置DB_BLOCK_SIZE设置Oracle的block为OS的block的几倍。从而下降没必要要的I/O。不管block中存放的数据是表、索引仍是cluster data,block的结构都是一致:
3. @ block header: 这里主要存储一些数据块的基本信息,如数据块地址,块类型(table data, index等),以及一些事务信息。
为了增强理解,咱们dump一下block看看:
SQL> select dbms_rowid.rowid_relative_fno(rowid) as fno, dbms_rowid.rowid_block_number(rowid) from t1 where b=1;
FNO DBMS_ROWID.ROWID_BLOCK_NUMBER(ROWID)
———- ————————————
4 388
SQL> alter system dump datafile 4 block 388;
在dump file中,咱们看到
Block header dump: 0×01000184
Object id on Block? Y
seg/obj: 0xcd17 csc: 0×00.8d80b itc: 2 flg: E typ: 1 – DATA
brn: 0 bdba: 0×1000181 ver: 0×01 opc: 0
inc: 0 exflg: 0
# 下面是一些比較重要的事务信息。每当一个事务開始时,都要得到一个ITL entry, 不然将会出现ITL 等待。
Itl Xid Uba Flag Lck Scn/Fsc
0×01 0×0002.005.0000010b 0×00800024.0128.32 –U- 66 fsc 0×0000.0008d8f3
0×02 0×0000.000.00000000 0×00000000.0000.00 —- 0 fsc 0×0000.00000000
data_block_dump,data header at 0xceb6864
4. @ table directory 记录该块中 table rows 的信息,例如如下所看到的:
===============
tsiz: 0×1f98
hsiz: 0×96
pbl: 0×0ceb6864
bdba: 0×01000184
76543210
flag=——–
ntab=1 // no. of tables, 除了cluster 之外。普通状况都为一
nrow=66 // 该block 上 rows 的数目
frre=-1
fsbo=0×96
fseo=0×402
avsp=0×36c
tosp=0×36c
5.@ row directroy 记录该块中记录的每一条记录的地址信息。例如如下所看到的:
0×12:pri[0] offs=0×402
0×14:pri[1] offs=0×46d
0×16:pri[2] offs=0×4d8
…
…
0×92:pri[64] offs=0×1ec2
0×94:pri[65] offs=0×1f2d
终于的记录条数应该和table directory 中的nrows相等。
这部分空间一旦被分配,将不可能收回,仅仅能在有新行insert时被重用。
** overhead:在block中,上述的header、table directory和row directory被合称为overhead。
6. @ row data 记录表中的实际数据。
7. @ free space 该部分主要用于update,insert等操做。 同一时候ITL entry 也可以在该部分得到。
附注: 在data block中的free space的使用与优化
1.当数据被delete或update时,可能引发block产生free space对此:
①假设有insert语句与对应释放block space的语句在同一个transaction中,则insert可以使用刚刚释放的block space。
②假设insert语句与对应的释放block space的语句不在同一个transaction中。则释放的block space仅仅有在事务被commit以后才干被使用。
Oracle当发生下面两种状况会进行free space的合并:insert或update操做视图使用一个有足够free space的block;free space存在大量碎片,没法进行数据的insert等。
2. row的连接与迁移:
当一条记录row的数据太大时。可能没法放在一个block中,这样的状况下Oracle每每会使用chain(连接)的方法;此外。当one row被update后,数据量增大。当前的block已经不能全然容纳时,Oracle会把该row数据整个迁移(migrates)到其它的数据块中。但在原来row的位置上保存一个指针。连接到新的地址上,大量的迁移、连接将会下降DB的I/O性能。
extent 是每次分配给一个对象的逻辑最小单位,是由必定数量连续的block组成。一个或多个extent又组成了一个segment。
1. @ Extent的分配:
对于本地管理表空间。DB会先肯定可以分配extent的候选datafile,随后查询该datafile的bitmap,肯定是否有所需大小的连续空暇blocks。直到找到知足的datafile。假设使用dictionary managed tablespace,则是去查询数据字典。而不是datafile头部的bitmap信息。
另外,由于某些缘由,假设想手工非配extent时。可以使用alter table table_name allocate extent。
2. @ Extent的收回:
1)当一个extent被分配给了某个object。除非这个obj被drop,不然extent将不会被其它obj所使用。除非 trauncate … drop storage.或者alter table … dealocate unused.(以上两种方法都不适用于index)。
另外。对于rollback segments。假设指定了optimal參数。oracle会本身dealocate一些extent。
2) 在dictionary managed tablespace中,假设所请求的ext 大于各个free extents 大小,这是oracle将聚合临近的extent。造成一个更大的extent。
在local managed tablespace中。则无此限制。 一旦extent 被分配和回收,对应的文件头bitmap或者数据字典都会被更新。
它是extents的集合,它包括了在表空间中所包括的详细逻辑存储机构的所有extents。
好比一个未分区的table,index, cluster被成为一个段,一个被分区的index,table的一个partition 被成为一个段。对于temporary segment。主要用于排序等操做。仅仅有当DB的内存没法存放对应的排序操做并没有法找到其它更好的解决的方法时。才会在暂时表空间中建立temporary segment。
1.下面语句均可能要建立temporary segment。 CREATE INDEX SELECT ... ORDER BY SELECT DISTINCT ... SELECT ... GROUP BY SELECT . . . UNION SELECT ... INTERSECT SELECT ... MINUS