關於oracle數據庫總結(三)

-------------------------------------------------------------------------------------增刪改數據程序員


回顧SQL92/99標準的四大類
(1)DML(數據操縱語言):select,insert,update,delete
(2)DDL(數據定義語言):create table,alter table,drop table,truncate table
(3)DCL(數據控制語言):grant select any table to scott/revoke select any table from scott
(4)TCL(事務控制語言):commit,rollback,savepoint to 回滾點spring

向emp表中插入一條記錄(方式一:按表默認結構順序)insert into 表名 values ...語法
insert into emp values(1111,'JACK','IT',7788,sysdate,1000,100,40);sql

向emp表中插入一條記錄(方式二:按自定義順序)insert into 表名(列名) values ...語法
insert into emp(ENAME,EMPNO,JOB,MGR,HIREDATE,SAL,COMM,DEPTNO) 
values('MARRY',2222,'IT',7788,sysdate,1000,100,40);數據庫

向emp表中插入NULL值(方式一:採用顯示插入NULL值)
insert into emp values(3333,'SISI','IT',7788,sysdate,1000,NULL,40);編程

向emp表中插入NULL值 (方式二:採用隱式插入NULL值),前提是所插入的字段容許插入NULL值
insert into emp(ENAME,EMPNO,JOB,MGR,HIREDATE,SAL,DEPTNO) 
values('SOSO',4444,'IT',7788,sysdate,1000,40);服務器

使用&佔位符,動態輸入值,&能夠運用在任何一個DML語句中,在values子句中使用,例如:'&ename'和&sal
insert into emp values(&empno,'&ename','&job',&mgr,&hiredate,&sal,&comm,&xxxxxxxx);
注意:&是sqlplus工具提供的佔位符,若是是字符串或日期型要加''符,數值型無需加''符session

使用&佔位符,動態輸入值,&能夠運用在任何一個DML語句中,在from子句中使用
select * from &table;oracle

使用&佔位符,動態輸入值,&能夠運用在任何一個DML語句中,在select子句中使用
select empno,ename,&colname from emp;ide

使用&佔位符,動態輸入值,&能夠運用在任何一個DML語句中,在where子句中使用
select * from emp where sal > &money;工具

使用&佔位符,動態輸入值,&能夠運用在任何一個DML語句中,在group by 和 having子句中使用
select deptno,avg(sal)
from emp
group by &deptno
having avg(sal) > &money;

刪除emp表中的全部記錄
delete from emp;

將xxx_emp表中全部20號部門的員工,複製到emp表中,批量插入,insert into 表名 select ...語法
insert into emp
select * 
from xxx_emp
where deptno=20;

將'SMITH'的工資增長20%
update emp set sal=sal*1.2 where ename = upper('smith');

將'SMITH'的工資設置爲20號部門的平均工資,這是一個條件未知的事物,優先考慮子查詢
第一:20號部門的平均工資
      select avg(sal) from emp where deptno=20;
第二:將'SMITH'的工資設置爲2207
      update emp set sal=2207 where ename = 'SMITH'; 
子查詢:
     update emp 
     set sal = (
    select avg(sal) 
        from emp 
        where deptno=20    
     ) 
     where ename = 'SMITH';   

刪除工資比全部部門平均工資都低的員工,這是一個條件未知的事物,優先考慮子查詢
第一:查詢全部部門的平均工資
      select avg(sal) from emp group by deptno;
第二:刪除工資比(*,*,*)都低的員工
      delete from emp where sal<all(*,*,*);
子查詢:
      delete 
      from emp 
      where sal < all(
     select avg(sal) 
         from emp 
         group by deptno
      ); 

刪除無佣金的員工
delete from emp where comm is null;

將emp表丟入回收站,drop table 表名
drop table emp;

從回收站將emp表閃回,flashback table 表名 to before drop
flashback table emp to before drop;

查詢回收站,show recyclebin
show recyclebin;

清空回收站,purge recyclebin
purge recyclebin;

使用關鍵字purge,完全刪除emp表,即不會將emp表丟入回收站,永久刪除emp表,drop table 表名 purge
drop table emp purge;

依據xxx_emp表結構,建立emp表的結構,但不會插入數據
create table emp
as
select * from xxx_emp where 1<>1;

建立emp表,複製xxx_emp表中的結構,同時複製xxx_emp表的全部數據
create table emp
as
select * from xxx_emp where 1=1;
注意:where不寫的話,默認爲true

將emp截斷,再自動建立emp表,truncate table 表名
truncate table emp;

向emp表,批量插入來自xxx_emp表中部門號爲20的員工信息,只包括empno,ename,job,sal字段
insert into emp(empno,ename,job,sal)
select empno,ename,job,sal 
from xxx_emp 
where deptno=20;

使用關鍵字purge,完全刪除emp表,即不會將emp表丟入回收站
drop table emp purge;

依據xxx_emp表,只建立emp表,但不復制數據,且emp表只包括empno,ename字段
create table emp(empno,ename)
as
select empno,ename from xxx_emp where 1=2;

向emp表(只含有empno和ename字段),批量插入xxx_emp表中部門號爲20的員工信息
insert into emp(empno,ename)
select empno,ename from xxx_emp where deptno=20;

drop table 和 truncate table 和 delete from 區別:
drop table
1)屬於DDL
2)不可回滾
3)不可帶where
4)表內容和結構刪除
5)刪除速度快

truncate table
1)屬於DDL
2)不可回滾
3)不可帶where
4)表內容刪除
5)刪除速度快

delete from
1)屬於DML
2)可回滾
3)可帶where
4)表結構在,表內容要看where執行的狀況
5)刪除速度慢,須要逐行刪除
軟件工程師


-------------------------------------------------------------------------------------事務

回顧什麼是事務?
一個不可分割的子操做造成一個總體,該總體要麼所有執行成功,要麼所有執行失敗。例如:轉賬

回顧爲何要用事務?
若是不用事務的話,爲轉賬爲例,可能出現一個用戶錢增長了,另外一個用戶錢不變

回顧編程中,事務可用於哪一層?
事務放在業務層

回顧jdbc編程中,如何使用事務?
connection.setAutoCommit(false);
pstmt.executeUpdate();
connection.commit();
connection.rollback();

回顧hibernate編程中,如何使用事務?
transaction.begin();
session.save(new User());
transaction.commit();
transaction.rollback();

回顧spring編程中,如何使用事務?
spring能夠分爲二種
>編程式事務,藕合
>聲明式事務,解藕,提倡

Oracle的事務只針對DML操做,即select/insert/update/delete

回顧MySQL的事務開始:start transaction
Oracle的事務開始:第一條DML操做作爲事務開始

Oracle的提交事務
(1)顯示提交:commit    
(2)隱藏提交:DDL/DCL/exit(sqlplus工具)
注意:提交是的從事務開始到事務提交中間的內容,提交到ORCL數據庫中的DBF二進制文件

Oracle的回滾事務
(1)顯示回滾:rollback
(2)隱藏回滾:關閉窗口(sqlplus工具),死機,掉電
注意:回滾到事務開始的地方

回顧什麼是回滾點?
在操做之間設置的一個標誌位,用於未來回滾之用

回顧爲何要設置回滾點?savepoint a;rollback to savepoint a;
若是沒有設置回滾點的話,Oracle必須回滾到事務開始的地方,其間作的一個正確的操做也將撤銷

使用savepoint 回滾點,設置回滾點a    
savepoint a;

使用rollback to savepoint,回滾到回滾點a處
rollback to savepoint a;

Oracle提交或回滾後,原來設置的回滾點還有效嗎?
原回滾點無效了

Oracle之因此能回滾的緣由是?
主要機制是實例池 

回顧MySQL支持的四種事務隔離級別及可以解決的問題
(1)read uncommitted -- 不能解決任何缺點
(2)read committed   -- 髒讀,Oracle默認
(3)reapatable read  -- 不可重複讀,髒讀,MySQL默認
(4)serializable     -- 幻讀,不可重複讀,髒讀,效率低

注意:jdbc/dbutils速度快,但書寫煩
      mybaits速度中等,但書寫"中等"
      hibernate速度慢,但書寫"爽"
      
Oracle支持的二種事務隔離級別及可以解決的問題
Oracle支持:read committed 和 serializable

Oracle中設置事務隔離級別爲serializable
set transaction isolation level serializable;

演示二個用戶同時操做emp表,刪除KING這條記錄,會有什麼後果?
由於有隔離級別的存在,因此不會出現二個用戶都刪除了KING這條記錄,
必定是一個用戶刪除KING成功,在該用戶沒有提交的狀況下,另外一個用戶等待


-------------------------------------------------------------------------------------訪問其它用戶下的對象


聲明:scott或hr叫用戶名/方案名/空間名
      scott--tiger
      hr-----lion
      
查詢當前用戶是誰
show user;

查詢scott本身表空間下的全部對象時,可加,或不加用戶名select * from emp;
select * from emp;

select * from scott.emp;

以sysdba身份解鎖hr普通賬戶
alter user hr account unlock;

以sysdba身份設置hr普通賬戶的密碼
alter user hr identified by lion;

當scott查詢hr表空間下的全部表時,必須得加用戶名
select * from hr.jobs;

在默認狀況下,每一個用戶只能查詢自已空間下的對象的權限,不能查詢其它用戶空間下的對象

以sysdba身份角色,授予scott用戶查詢全部用戶空間下的對象權限
grant select any table to scott;

以sysdba身份,撤銷scott用戶查詢全部用戶空間下的對象權限
revoke select any table from scott;

scott自已查看本身所擁有的權限
select * from user_sys_privs;

從scott用戶空間導航到sysdba用戶空間
conn / as sysdba;

從sysdba用戶空間導航到scott用戶空間
conn scott/tiger;

從scott用戶空間導航到hr用戶空間
conn hr/lion;

查詢hr用戶空間中的全部對象
select * from tab;

從hr用戶空間導航到scott用戶空間
conn scott/tiger;

在scott用戶空間下,查詢hr用戶空間下的jobs表,必須加上hr用戶空間名
select * from hr.jobs;


-------------------------------------------------------------------------------------視圖


什麼是視圖【View】 
(1)視圖是一種虛表 
(2)視圖創建在已有表的基礎上, 視圖賴以創建的這些表稱爲基表
(3)向視圖提供數據內容的語句爲 SELECT 語句,能夠將視圖理解爲存儲起來的 SELECT 語句
(4)視圖向用戶提供基表數據的另外一種表現形式
(5)視圖沒有存儲真正的數據,真正的數據仍是存儲在基表中
(6)程序員雖然操做的是視圖,但最終視圖還會轉成操做基表
(7)一個基表能夠有0個或多個視圖 

什麼狀況下會用到視圖
(1)若是你不想讓用戶看到全部數據(字段,記錄),只想讓用戶看到某些的數據時,此時可使用視圖
(2)當你須要減化SQL查詢語句的編寫時,可使用視圖,但不提升查詢效率

視圖應用領域
(1)銀行,電信,金屬,證券軍事等不便讓用戶知道全部數據的項目中

視圖的做用
(1)限制數據訪問
(2)簡化複雜查詢
(3)提供數據的相互獨立
(4)一樣的數據,能夠有不一樣的顯示方式

基於emp表全部列,建立視圖emp_view_1,create view 視圖名 as select對一張或多張基表的查詢
create view emp_view_1
as
select * from emp;

默認狀況下,普通用戶無權建立視圖,得讓sysdba爲你分配creare view的權限 

以sysdba身份,受權scott用戶create view權限
grant create view to scott;

以sysdba身份,撤銷scott用戶create view權限
revoke create view from scott;

基於emp表指定列,建立視圖emp_view_2,該視圖包含編號/姓名/工資/年薪/年收入(查詢中使用列別名)
create view emp_view_2
as
select empno "編號",ename "姓名",sal "工資",sal*12 "年薪",sal*12+NVL(comm,0) "年收入"
from emp;

基於emp表指定列,建立視圖emp_view_3(a,b,c,d,e),包含編號/姓名/工資/年薪/年收入(視圖中使用列名)
create view emp_view_3(a,b,c,d,e)
as
select empno "編號",ename "姓名",sal "工資",sal*12 "年薪",sal*12+NVL(comm,0) "年收入"
from emp;

查詢emp_view_3建立視圖的結構
desc emp_view_3;

修改emp_view_3(id,name,salary,annual,income)視圖,create or replace view 視圖名 as 子查詢
create or replace view emp_view_3(id,name,salary,annual,income)
as
select empno "編號",ename "姓名",sal "工資",sal*12 "年薪",sal*12+NVL(comm,0) "年收入"
from emp;

查詢emp表,求出各部門的最低工資,最高工資,平均工資
select min(sal),max(sal),round(avg(sal),0),deptno
from emp
group by deptno;

建立視圖emp_view_4,視圖中包含各部門的最低工資,最高工資,平均工資
create or replace view emp_view_4
as
select deptno "部門號",min(sal) "最低工資",max(sal) "最高工資",round(avg(sal),0) "平均工資"
from emp
group by deptno;

建立視圖emp_view_5,視圖中包含員工編號,姓名,工資,部門名,工資等級
create or replace view emp_view_5
as
select e.empno "編號",e.ename "姓名",e.sal "工資",d.dname "部門名",s.grade "工資等級"
from emp e,dept d,salgrade s
where (e.deptno=d.deptno) and (e.sal between s.losal and s.hisal);

刪除視圖emp_view_1中的7788號員工的記錄,使用delete操做,會影響基表嗎
delete from emp_view_1 where empno=7788;寫法正確,會影響基表

修改emp_view_1爲只讀視圖【with read only】,再執行上述delete操做,還行嗎?
create or replace view emp_view_1
as
select * from emp
with read only;
不能進行delete操做了

刪除視圖中的【某條】記錄會影響基表嗎?
會影響基表

將【整個】視圖刪除,會影響表嗎?
不會影響基表

刪除視圖,會進入回收站嗎?
不會進入回收站

刪除基表會影響視圖嗎?
會影響視圖

閃回基表後,視圖有影響嗎?
視圖又能夠正常工做了


-------------------------------------------------------------------------------------同義詞


什麼是同義詞【Synonym】
(1)對一些比較長名字的對象(表,視圖,索引,序列,。。。)作減化,用別名替代

同義詞的做用
(1)縮短對象名字的長度
(2)方便訪問其它用戶的對象

建立與salgrade表對應的同義詞,create synonym 同義詞 for 表名/視圖/其它對象
create synonym e for salgrade;
create synonym ev5 for emp_view_5;

以sys身份授予scott普通用戶create synonym權限
grant create synonym to scott;

以sys身份從scott普通用戶撤銷create synonym權限
revoke create synonym from scott;

使用同義詞操做salgrade表
select * from s;

刪除同義詞
drop synonym ev5;

刪除同義詞,會影響基表嗎?
不會影響基表

刪除基表,會影響同義詞嗎?
會影響同義詞


-------------------------------------------------------------------------------------序列


什麼是序列【Sequence】
(1)相似於MySQL中的auto_increment自動增加機制,但Oracle中無auto_increment機制
(2)是oracle提供的一個產生惟一數值型值的機制
(3)一般用於表的主健值
(4)序列只能保證惟一,不能保證連續
     聲明:oracle中,只有rownum永遠保持從1開始,且繼續
(5)序列值,可放於內存,取之較快
 
題問:爲何oracle不直接用rownum作主健呢?
rownum=1這條記錄不能永遠惟一表示SMITH這個用戶
但主鍵=1確能夠永遠惟一表示SMITH這個用戶

爲何要用序列
(1)之前咱們爲主健設置值,須要人工設置值,容易出錯
(2)之前每張表的主健值,是獨立的,不能共享

爲emp表的empno字段,建立序列emp_empno_seq,create sequence 序列名
create sequence emp_empno_seq;

刪除序列emp_empno_seq,drop sequence 序列名
drop sequence emp_empno_seq;

查詢emp_empno_seq序列的當前值currval和下一個值nextval,第一次使用序列時,必須選用:序列名.nextval
select emp_empno_seq.nextval from dual;
select emp_empno_seq.currval from dual;

使用序列,向emp表插入記錄,empno字段使用序列值
insert into emp(empno) values(emp_empno_seq.nextval);
insert into emp(empno) values(emp_empno_seq.nextval);
insert into emp(empno) values(emp_empno_seq.nextval);

修改emp_empno_seq序列的increment by屬性爲20,默認start with是1,alter sequence 序列名
alter sequence emp_empno_seq
increment by 20;

修改修改emp_empno_seq序列的的increment by屬性爲5
alter sequence emp_empno_seq
increment by 5;

修改emp_empno_seq序列的start with屬性,行嗎
alter sequence emp_empno_seq
start with 100;

有了序列後,還能爲主健手工設置值嗎?
insert into emp(empno) values(9999);
insert into emp(empno) values(7900);

刪除表,會影響序列嗎?
你沒法作insert操做

刪除序列,會影響表嗎?
表真正亡,序列亡

在hibernate中,若是是訪問oracle數據庫服務器,那麼User.hbm.xml映射文件中關於<id>標籤如何配置呢?
<id name="id" column="id">
   <generator class="increment/identity/uuid/【sequence】/【native】"/>
</id>


-------------------------------------------------------------------------------------索引


什麼是索引【Index】
(1)是一種快速查詢表中內容的機制,相似於新華字典的目錄
(2)運用在表中某個/些字段上,但存儲時,獨立於表以外

爲何要用索引
(1)經過指針加速Oracle服務器的查詢速度
(2)經過rowid快速定位數據的方法,減小磁盤I/O
     rowid是oracle中惟一肯定每張表不一樣記錄的惟一身份證

rowid的特色
(1)位於每一個表中,但表面上看不見,例如:desc emp是看不見的
(2)只有在select中,顯示寫出rowid,方可看見
(3)它與每一個表綁定在一塊兒,表亡,該表的rowid亡,二張表rownum能夠相同,但rowid必須是惟一的
(4)rowid是18位大小寫加數字混雜體,惟一表代該條記錄在DBF文件中的位置
(5)rowid能夠參與=/like比較時,用''單引號將rowid的值包起來,且區分大小寫
(6)rowid是聯繫表與DBF文件的橋樑

索引的特色
(1)索引一旦創建, Oracle管理系統會對其進行自動維護, 並且由Oracle管理系統決定什麼時候使用索引
(2)用戶不用在查詢語句中指定使用哪一個索引
(3)在定義primary key或unique約束後系統自動在相應的列上建立索引
(4)用戶也能按本身的需求,對指定單個字段或多個字段,添加索引

何時【要】建立索引
(1)表常常進行 SELECT 操做
(2)表很大(記錄超多),記錄內容分佈範圍很廣
(3)列名常常在 WHERE 子句或鏈接條件中出現
 注意:符合上述某一條要求,均可建立索引,建立索引是一個優化問題,一樣也是一個策略問題
       
何時【不要】建立索引
(1)表常常進行 INSERT/UPDATE/DELETE 操做
(2)表很小(記錄超少)
(3)列名不常常做爲鏈接條件或出如今 WHERE 子句中
同上注意

爲emp表的empno單個字段,建立索引emp_empno_idx,叫單列索引,create index 索引名 on 表名(字段,...)
create index emp_empno_idx
on emp(empno);

爲emp表的ename,job多個字段,建立索引emp_ename_job_idx,多列索引/聯合索引
create index emp_ename_job 
on emp(ename,job);
若是在where中只出現job不使用索引
若是在where中只出現ename使用索引
咱們提倡同時出現ename和job

注意:索引建立後,只有查詢表有關,和其它(insert/update/delete)無關,解決速度問題

刪除emp_empno_idx和emp_ename_job_idx索引,drop index 索引名 drop index emp_empno_idx; drop index emp_ename_job_idx;