日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Oracle第二天

發布時間:2023/12/10 编程问答 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Oracle第二天 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

Oracle第二天

?

整體安排(3天)

第一天:Oracle的安裝配置(服務端和客戶端),SQL增強(單表查詢)。

第二天:SQL增強(多表查詢、子查詢、偽列-分頁),數據庫對象(表、約束、序列),Oracle基本體系結構、表空間、用戶和權限 ,視圖、同義詞

第三天:數據庫對象(索引、數據字典),PLSQL編程、存儲過程,數據庫備份和還原。

?

?

今天的安排:

  • 多表關聯查詢(內連接(等值和不等值)、外連接(左外、右外、全外)、自連接,Oracle的寫法)
  • SQL增強-子查詢(分為單行子查詢和多行子查詢。)
  • 偽列(rowid和rownum-Oracle分頁)--查詢結束
  • 數據處理(包括插入數據(批量插入語法等)、更新數據、刪除數據(高水位,truncate和delete區別)。
  • 數據庫事務,包括事務的開啟和結束、事務保留點等。
  • 數據庫對象--表,包括創建表(復制表語法)、修改表、刪除表
  • 了解一下表的約束(新增check約束)
  • 序列,包括語法、應用、注意事項。
  • Oracle的體系結構-幾個概念
  • 表空間的管理,包括概念、創建表空間等。
  • 用戶和權限相關(普通用戶只需要兩個角色)
  • 視圖:概念、語法、作用
  • 同義詞:概念、語法、作用
  • ?

    ?

    ?

  • 多表(關聯)查詢

  • 多表查詢也稱之為關聯查詢、多表關聯查詢等,主要是指通過多個表的關聯來獲取數據的一種方式。

  • 多表映射關系

  • 一對多:A表的一行數據,對應B表中的多條。如:一個部門可以對應多個員工.

    多對一:B表中的多條對應A表的一行數據.如:多個員工對應一個部門.

    多對多:學生和選修課表----學生和課程對應表。

    一對一:人員基本信息和人員信息擴展表。

  • 笛卡爾集

  • ?

    笛卡爾集對于我們數據庫的數據查詢結果的影響:

  • 數據冗余。---笛卡爾集并不是我們所需要的數據.
  • 效率問題:導致數量級的增長。100w *100w====1w億。如果你在查詢大量數據的時候,不注意這個笛卡爾集的話,會導致你的查詢結果時間非常非常非常長,還會導致數據庫故障。
  • 因此,在實際運行環境下,應避免使用全笛卡爾集。

    ?

    笛卡爾集產生的條件:

    • 省略連接條件
    • 連接條件無效

    如下示例:

    如何避免笛卡爾集:

    在 WHERE 加入有效的連接條件。

    這時候就需要學習表關聯的幾種方式了。

  • 多表連接的類型

  • 根據連接方式的不同,Oracle的多表關聯的類型分為:

    內連接、外連接、自連接。

    內連接分為:等值內連接、不等值內連接

    外連接分為:左外連接、右外連接、全外連接

    自連接是一種特殊的關聯,可以包含內連接和外連接的連接方式。

  • 關于sql99-了解

  • Oracle是關系型數據庫,它遵的規范(sql規范)。

    但是,mysql和Oracle有些地方不一樣,原因:各個廠商的實現可能會有差別。

    ?

    Sql99 是為了 統一規范多個關系型數據庫的通用語法的

    ?

  • 多表連接的基本語法

  • Sql99的語法:

    Oracle的語法:

    ?

    sql語句 優化:

    加上前綴:效率高!

    ?

  • 內連接

  • 等值內連接

  • 等值內連接也稱之為等值連接。

    【示例】

    -需求:查詢一下員工信息,并且顯示其部門名稱

    --需求:查詢一下員工信息,并且顯示其部門名稱

    SELECT * FROM emp t1,dept t2 WHERE t1.deptno=t2.deptno;--等值內連接,數據庫的私有擴展語法:隱式內連接(mysqloracle都支持)

    SELECT * FROM emp t1 INNER JOIN dept t2 ON t1.deptno=t2.deptno;--sql99語法,顯示內連接(所有符合sql99規范的都支持)

  • 不等值內連接

  • 不等值內連接也稱之為不等值連接。

    【示例】需求:查詢員工信息,要求顯示員工的編號、姓名、月薪、工資級別。

    --分析:要完成這個需求,需要使用到下面兩張表:

    --需求:查詢員工信息,要求顯示員工的編號、姓名、月薪、工資級別。

    SELECT * FROM emp t1,salgrade t2 WHERE t1.sal >=t2.losal AND t1.sal<=t2.hisal;--隱式語法

    SELECT * FROM emp INNER JOIN salgrade ON emp.sal >=salgrade.losal AND emp.sal <=salgrade.hisal --sql99

    ?

  • 表的別名

  • 為什么要使用表的別名?

    • 使用別名可以簡化查詢。
    • 使用表名前綴可以提高執行效率。--SQL性能優化方案
    • 在不同表中具有相同列名的列,可以用表的別名作為前綴來加以區分。

    ?

    需要注意的是,如果一旦使用了表的別名,則不能再使用表的真名。

  • 更多表的連接

  • 注意:這個理論。

    ?

  • 外連接

  • 分為左外連接,右外連接,全外連接(oracle特有 mysql

    沒有)。

    ?

  • 左外連接

  • --查詢"所有"員工信息,要求顯示員工號,姓名 ,和部門名稱--要求使用左外連接

    ?

    --查詢"所有"員工信息,要求顯示員工號,姓名 ,和部門名稱--要求使用左外連接

    SELECT * FROM emp t1 LEFT OUTER JOIN dept t2 ON t1.deptno=t2.deptno;--sql99標準語法

    SELECT * FROM emp t1,dept t2 WHERE t1.deptno=t2.deptno(+);--oracle私有語法(mysql不支持),+放到右邊是左外,你可以認為(+)是附加補充的意思。--要求查詢所有的信息的表,我們可以稱之為主表,而補充信息的表,稱之為從表

    ?

  • 右外連接

  • ----查詢所有部門及其下屬的員工的信息。--右外連接

    ?

    SELECT * FROM emp t1 RIGHT OUTER JOIN dept t2 ON t1.deptno=t2.deptno;--sql99--右外連接--右邊表(dept)數據全部顯示。

    SELECT * FROM emp t1,dept t2 WHEREt1.deptno(+)=t2.deptno;--oracle語法,右外連接

    ?

  • 如何選擇左外和右外

  • SELECT t1.*,t2.* FROM dept t1 ,emp t2 WHERE t1.deptno=t2.deptno(+);

    --1.到底是使用左外還是右外,主要是看兩張表的在語句中的位置,

    --兩張表是有主從關系,一般把主表放在左邊,----一般兩張表的情況下,我們都使用左連接.

    --2.+到底是放在條件哪邊?左外連接的+放在右邊,右外連接的+放在左邊.----記憶的方法:(+)放在從表的一方,起到數據附加的作用.

    簡單的說:左外連接就是左邊的表的數據全部顯示,右外就是右邊的表的數據全部顯示。

    ?

    這種(+)的寫法,只能用在Oracle。不能用于mysql!

    ?

    一定要有主表和從表這個概念,分清那張是主表,哪張是從表。

    把你想查詢基礎表當成左表。想把誰全部都查詢出來就當成主表。

    到底哪張是主表哪張是從表?最終還看你的需求。

    一般我們把主表放在左邊,使用左外連接。

    一般情況下,我們就用左連接就行了。

    ?

  • 全外連接

  • 左表和右表的數據全部都顯示,而且不是笛卡爾集。

    相當于左外+右外的數據。

    【示例】

    需求:要求將所有員工和所有部門都顯示出來

    --全外連接

    SELECT * FROM emp t1 LEFT OUTER JOIN dept t2 on t1.deptno=t2.deptno

    UNION

    SELECT * FROM emp t1 RIGHT JOIN dept t2 ON t1.deptno=t2.deptno;

    SELECT * FROM emp t1 FULL OUTER JOIN dept t2 ON t1.deptno=t2.deptno;--sql99語法,Oracle沒有私有擴展的語法。而且,mysql沒有全外

    ?

    ?

  • 自連接

  • 自連接,就是將一張表當成兩張表來查詢。

  • 示例

  • 自連接的查詢的原理:就是將一張表當成兩張表來使用.

    【示例】

    1.查詢員工信息,要求同時顯示員工和員工的領導的姓名

    2.查詢"所有"員工信息,要求同時顯示員工和員工的領導的姓名

    --查詢員工信息,要求同時顯示員工和員工的領導的姓名

    SELECT * FROM emp t1,emp t2 WHERE t1.mgr=t2.empno;

    --查詢"所有"員工信息,要求同時顯示員工和員工的領導的姓名

    SELECT * FROM emp t1,emp t2 WHERE t1.mgr=t2.empno(+);

    自連接是一種特殊的多表連接方式,其實含有內連接和外連接的操作.

    注意問題:你也要注意笛卡爾集的產生.

    ?

  • 子查詢

  • 子查詢也稱之為嵌套子句查詢。

  • 語法

  • 語法上的運行使用規則:

    • 子查詢 (內查詢、嵌套子句) 在主查詢之前一次執行完成。(子查詢先執行)
    • 子查詢的結果被主查詢使用 (外查詢)。
    • 子查詢要包含在括號內。
    • 子查詢放在比較條件的右側
  • 為什么要使用子查詢?

  • 【需求】誰的工資比scott高?

    采用連接的方式寫(這里是自連接,見下圖):

    ?

    --【需求】誰的工資比scott高?

    --多表關聯查詢:自連接的不等值連接

    SELECT * FROM emp t1,emp t2 WHERE t2.ename='SCOTT' AND t1.sal>t2.sal

    --不等值連接

    ?

    采用子查詢的方式寫:

    --子查詢

    --分析一下:誰的工資比scott高?--->1,scott工資是多少2,誰的工資比3000

    SELECT sal FROM emp WHERE ename='SCOTT';

    SELECT * FROM emp WHERE sal >3000;

    SELECT * FROM emp WHERE sal >(SELECT sal FROM emp WHERE ename='SCOTT');

    ?

    對比可以發現:在某些業務上,子查詢比連接查詢更容易理解。

    ?

  • 子查詢的分類

  • 單行操作符(> = <)對應單行子查詢多行操作符(in,not in)對應多行子查詢

  • 單行子查詢

  • 語法要求:

    • 只返回一行。
    • 使用單行比較操作符。

    ?

    其中<>也可以可以用!=代替,意思一樣。

    【示例】--查詢部門名稱是SALES的員工信息

    ?

    --查詢部門名稱是SALES的員工信息

    SELECT * FROM emp WHERE deptno=(SELECT deptno FROM DEPT WHERE dname ='SALES')

    了解:子查詢可以是一張表的數據,也可以是不同表的數據。

  • 空值問題

  • 【代碼】

    需求:查找工作和'Rose' 這個人的工作一樣的員工信息

    需求:查找工作和'Rose' 這個人的工作不一樣的員工信息

    --需求:查找工作和'Rose' 這個人的工作一樣的員工信息

    SELECT job FROM emp WHERE ename = 'Rose';

    ?

    SELECT * FROM emp WHERE job =(SELECT job FROM emp WHERE ename = 'Rose');

    ?

    SELECT * FROM emp;

    ?

    --需求:查找工作和'Rose' 這個人的工作不一樣的員工信息

    SELECT * FROM emp WHERE job !=(SELECT job FROM emp WHERE ename = 'Rose');

    ?

    --結論: 只要子查詢返回的結果是null的話, 那么主查詢的結果就一定是null

    注意:使用子查詢的時候,一定要保證子查詢不能為空,否則數據就會出現異常。

  • 非法使用單行子查詢

  • 【示例】需求:查找工作和'SMITH' 'ALLEN'這兩個人的工作一樣的員工信息

  • 多行子查詢

  • 語法要求:

    • 返回多行。
    • 使用多行比較操作符。

  • In操作符

  • 【示例】

    需求:查找工作和'SMITH' 'ALLEN'這兩個人的工作一樣的員工信息

    --需求:查找工作和'SMITH' 'ALLEN' 這兩個人的工作不一樣的員工信息

    --需求:查找工作和'SMITH' 'ALLEN' 這兩個人的工作一樣的員工信息

    ?

    SELECT JOB FROM emp WHERE ename IN('SMITH','ALLEN');

    SELECT * FROM emp WHERE job IN(SELECT JOB FROM emp WHERE ename IN('SMITH','ALLEN'));

    ?

    --需求:查找工作和'SMITH' 'ALLEN' 這兩個人的工作不一樣的員工信息

    SELECT * FROM emp WHERE job NOT IN(SELECT JOB FROM emp WHERE ename IN('SMITH','ALLEN'));

    ?

  • Any和all操作符

  • 【示例】需求:查詢工資比30號部門任意一個員工的工資高的員工信息。--面試題

    【示例】需求:查詢工資比30號部門所有員工的工資高的員工信息。

    --需求:查詢工資比30號部門任意一個員工的工資高的員工信息。--面試題

    SELECT * FROM emp WHERE deptno =30;

    --任意一個:比最低的那個高就ok。

    SELECT * FROM emp WHERE sal >(SELECT MIN(sal) FROM emp WHERE deptno=30);

    --any(多行函數)

    SELECT * FROM emp WHERE sal >ANY(SELECT sal FROM emp WHERE deptno=30);

    --【示例】需求:查詢工資比30號部門所有員工的工資高的員工信息。

    SELECT * FROM emp WHERE sal>(SELECT MAX (sal) FROM emp WHERE deptno=30);

    --all(多個返回記錄)--max(sal)

    SELECT * FROM emp WHERE sal>ALL(SELECT sal FROM emp WHERE deptno=30);

    ?

    分析結果:

    ?

  • 子查詢注意事項

    • 關于格式:子查詢要包含在括號內,最好有合理的書寫風格。

    • 子查詢的位置可以放在主查詢的where、select、having、from的后面。不可以放在主查詢的group by后面。
    • 子查詢和主查詢可以是同一張表,也可以不是是不同一張表,只要子查詢返回的結果在主查詢中能使用即可。
    • 關于使用操作符:單行操作符對應單行子查詢,多行操作符對應多行子查詢。
    • 執行順序:一般子查詢先執行,再執行主查詢;
    • 關于排序:一般不在子查詢中使用order by;但在top-N分析問題中,必須在子查詢中使用order by。
    • 多行子查詢一般用于from后面,作為一張新的虛擬臨時表來使用。

    ?

    虛擬臨時表是臨時表的一種,是運行過程中,內存中虛擬出來的一張臨時表,用于sql的操作。

    【示例】

    --虛擬表

    SELECT * FROM

    (

    SELECT * FROM emp WHERE deptno=30 --虛表:將查詢結果再作為一張表來使用。

    ) t

    WHERE sal>2000

    ?

  • 子查詢和多表關聯查詢的選擇

  • 理論上,在都可以實現需求的情況下盡量選擇多表查詢。

    原因:子查詢會操作兩次,多表查詢只操作一次。多表的效率高。

    但要注意的是,多表查詢如果產生了笛卡爾集(語句上要注意條件的使用),則會出現嚴重的效率問題。

    一般不在子查詢中使用排序(order by),但在top-N分析問題中必須在子查詢中使用排序。

    ?

  • 偽列

  • 什么是偽列

    • 偽列是在ORACLE中的一個虛擬的列。
    • 列的數據是由ORACLE進行維護和管理的,用戶不能對這個列修改,只能查看。
    • 所有的偽列要得到值必須要顯式的指定。

    ?

    最常用的兩個偽列:rownum和rowid。

    ?

  • ROWNUM

  • ROWNUM(行號):是在查詢操作時由ORACLE為每一行記錄自動生成的一個編號。

    每一次查詢ROWNUM都會重新生成。(查詢的結果中Oracle給你增加的一個編號,根據結果來重新生成)

    rownum永遠按照默認的順序生成。(不受orderby的影響)

    rownum只能使用< <=,不能使用> >=符號,原因是:Oracle是基于行的數據庫,行號永遠是從1開始,即必須有第一行,才有第二行。

  • 行號的產生

  • 【示例】需求:查詢出所有員工信息,并且顯示默認的行號列信息。

    --需求:查詢出所有員工信息,并且顯示默認的行號列信息。

    SELECT ROWNUM,t.* FROM emp t;--* 和指定的列一起顯示的時候,必須加別名

    提示兩點:

    • ROWNUM是由數據庫自己產生的。
    • ROWNUM查詢的時候自動產生的。

    ?

  • 行號的排序

  • 【示例】????

    --需求:查詢出所有員工信息,按部門號正序排列,并且顯示默認的行號列信息。

    SELECT ROWNUM,t.* FROM emp t ORDER BY deptno;--order by 的原理:將查詢結果(此時行號已經有了,已經和每一行數據綁定了)進行排序。

    - --order by是查詢語句出來的結果之后再排序的,,rownu是在查詢出來結果的時候產生。order by不會影響到行號

    --先排序,再查詢

    SELECT ROWNUM,t.* FROM

    (

    SELECT * FROM emp ORDER BY deptno

    ) t

    結論:

    order by排序,不會影響到rownum的順序。rownum永遠按照默認的順序生成。

    所謂的"默認的順序",是指系統按照記錄插入時的順序(其實是rowid)。

  • 利用行號進行數據分頁-重點

  • 回顧mysql如何排序?

    select * from table limit m,n

    其中m是指記錄開始的index,從0開始,表示第一條記錄

    n是指從第m+1條開始,取n條。

    select * from tablename limit 3,3

    即取出第4條至第6條,3條記錄

    Oracle如何分頁呢?

    結論:Mysql使用limit的關鍵字可以實現分頁,但Oracle沒有該關鍵字,無法使用該方法進行分頁。

    【示例】需求:根據行號查詢出第四條到第六條的員工信息。

    --需求:根據行號查詢出第四條到第六條的員工信息。

    SELECT ROWNUM,t.* FROM emp t;

    SELECT ROWNUM,t.* FROM emp t WHERE ROWNUM >=4 AND ROWNUM<=6;

    --rownum只能使用< <=,不能使用> >=符號,原因是:Oracle是基于行的數據庫,行號永遠是從1開始,即必須有第一行,才有第二行。

    SELECT ROWNUM,t.* FROM emp t WHERE ROWNUM<=6;

    --方案:可以使用子查詢

    SELECT rownum,t2.* FROM

    (

    SELECT ROWNUM r,t.* FROM emp t WHERE ROWNUM<=6--此時子查詢的rownum已經變成了虛表的一個列

    ) t2--盡量讓虛表盡量小

    WHERE t2.r >=4

    ?

    --需求:要分頁查詢,每頁3條記錄,查詢第二頁

    /*

    pageNum=2

    pageSize=3

    ?

    計算:

    firstIndex=pageSize*(pageNum-1);

    maxCount=pageSize

    ?

    mysql:

    limit 起始索引firstIndex,最大記錄數maxCount

    ?

    Oracle

    //起始行號

    firstRownum=pageSize*(pageNum-1)+1

    //結束行號

    endRownum=firstRownum+pageSize-1

    ?

    具體計算:

    firstRownum=3*(2-1)+1=4;

    endRownum=4+3-1=6;

    */

    --Oracle的分頁,從子查詢寫起,也就是說從小于等于寫起,或者說從endRownum寫起

    SELECT ROWNUM ,t2.* FROM

    (

    SELECT ROWNUM r,t.* FROM emp t WHERE ROWNUM <=6

    ) t2 WHERE t2.r >=4;

    --優化

    SELECT * FROM

    (

    SELECT ROWNUM r,t.* FROM emp t WHERE ROWNUM <=6

    ) WHERE r >=4;

    SELECT empno,ename,job FROM--結果指定字段

    (

    SELECT ROWNUM r,t.* FROM emp t WHERE ROWNUM <=6

    ) WHERE r >=4;

    ?

    --按照薪資的高低排序再分頁

    SELECT * FROM

    (

    SELECT ROWNUM r,t.* FROM emp t WHERE ROWNUM <=6 ORDER BY sal DESC

    ) WHERE r >=4 ;

    ?

    SELECT * FROM emp ORDER BY sal DESC;

    --先排序薪資,再分頁

    SELECT * FROM

    (

    SELECT ROWNUM r,t.* FROM

    (SELECT * FROM emp ORDER BY sal DESC) t

    WHERE ROWNUM <=6 ORDER BY sal DESC

    )

    WHERE r >=4 ;--Hibernate會自動將所有數據封裝到實體對象(多余出來的行號那一列不會封裝)

    --如果不需要額外的字段,則只需要指定特定的列名就可以了。

    --優化:子查詢字段盡量少一些。數據量少。比如,表中有100個字段,但你就想顯示5個,那么,你就子查詢中直接指定5個就ok了。但,使用orm框架的建議都查出來。

    SELECT * FROM

    (

    SELECT ROWNUM r,t.* FROM

    (SELECT ename,job,sal FROM emp ORDER BY sal DESC) t

    WHERE ROWNUM <=6 ORDER BY sal DESC

    )

    WHERE r >=4 ;

    --通用

    SELECT * FROM

    (

    SELECT ROWNUM r,t.* FROM

    (SELECT ename,job,sal FROM emp ORDER BY sal DESC) t

    WHERE ROWNUM <=endRownum ORDER BY sal DESC

    )

    WHERE r >=firstRownum ;

    ?

    /*

    另外一種計算方法(索引算法)

    firstIndex=pageSize*(pageNum-1);

    endRownum=firstIndex+pageSize

    */

    SELECT * FROM

    (

    SELECT ROWNUM r,t.* FROM

    (SELECT ename,job,sal FROM emp ORDER BY sal DESC) t

    WHERE ROWNUM <=endRownum ORDER BY sal DESC

    )

    WHERE r > firstIndex;--Hibernate的內置算法

    ?

    ?

    2016-10-22

    ?

    ?

    ----需求:要分頁查詢,每頁3條記錄,查詢第二頁

    /*

    ?

    mysql: select * from emp limit 3,3;

    ?

    ?

    page = 2;

    pageSize = 3;

    ?

    ?

    firstIndex = (page-1)*pageSize;

    ?

    maxCount = pageSize;

    ?

    select * from emp limit firstIndex,maxCount;

    ?

    ?

    oracle:

    ?

    ?

    page = 2;

    pageSize = 3;

    ?

    startRowNum = (page-1)*pageSize+1;

    ?

    endRowNum = pageSize*page

    ?

    ?

    ?

    select * from (select rownum r,t.* from emp t where rownum<=endRowNum) where r>=startRowNum;

    ?

    ?

    ?

    ----按照薪資的高低排序再分頁

    ?

    ?

    */

    ?

    ?

    SELECT *FROM emp ORDER BY sal DESC;

    ?

    SELECT ROWNUM,t.* FROM(SELECT *FROM emp ORDER BY sal DESC) t WHERE ROWNUM<=6;

    ?

    SELECT * FROM (SELECT ROWNUM r,t.* FROM(SELECT *FROM emp ORDER BY sal DESC) t WHERE ROWNUM<=6) t2 WHERE t2.r>=4;

    分析原因:

    rownum只能使用< <=,不能使用> >=符號,原因是:Oracle是基于行的數據庫,行號永遠是從1開始,即必須有第一行,才有第二行。

    ?

    【提示】:

    • 如何記憶編寫Oracle的分頁?建議寫的時候從里到外來寫,即先寫小于的條件的子查詢(過濾掉rownum大于指定值的數據),再寫大于的條件的查詢(過濾掉rownum小于的值)。
    • Oracle的分頁中如果需要排序顯示,要先排序操作,再分頁操作。(再嵌套一個子查詢)
    • 性能優化方面:建議在最里層的子查詢中就直接指定字段或者其他的條件,減少數據的處理量。

    ?

  • ROWID

  • ROWID(記錄編號):是表的偽列,是用來唯一標識表中的一條記錄,并且間接給出了表行的物理位置,定位表行最快的方式。

    ?

    • 主鍵:標識唯一的一條業務數據的標識。主鍵是給業務給用戶用的。不是給數據庫用的。
    • 記錄編號rowid:標識唯一的一條數據的。主要是給數據庫用的。類似UUID。

  • ROWID的查看

  • 【示例】

    SELECT t.*,ROWID FROM emp t;

    ?

  • ROWID的產生

  • 使用insert語句插入數據時,oracle會自動生成rowid并將其值與表數據一起存放到表行中。

    這與rownum有很大不同,rownum不是表中原本的數據,只是在查詢的時候才生成的

    提示:rownum默認的排序就是根據rowid

  • ROWID的作用

  • 這里列舉兩個常見的應用:

    • 去除重復數據。--面試題—了解
    • 在plsql Developer中,加上rowid可以更改數據。

    ?

    關于主鍵和rowid的區別:

    相同點:為了標識唯一一條記錄的。

    不同點:

    主鍵:針對業務數據,用來標識不同的一條業務數據。

    rowid:針對具體數據的,用來標識不同的唯一的一條數據,跟業務無關。

    ?

    ?

    【示例】需求:刪除表中的重復數據,要求保留重復記錄中最早插入的那條。(DBA面試題)

    --查看rowid

    SELECT t.*,ROWID FROM emp t;

    --需求:刪除表中的重復數據,要求保留重復記錄中最早插入的那條。(DBA面試題)

    --準備測試表和測試數據:

    --參考建表語句如下:

    -- Create table

    create table test

    (

    id number,

    name varchar2(50)

    )

    ;

    --插入測試數據

    INSERT INTO TEST VALUES(1,'xiaoming');

    INSERT INTO TEST VALUES(2,'xiaoming');

    INSERT INTO TEST VALUES(3,'xiaoming');

    COMMIT;

    SELECT * FROM TEST ;

    --通過rowid,剔除重復xiaoming,保留最早插入的xiaoming

    SELECT t.*,ROWID FROM TEST t;

    --刪除的的時候,可以先查詢你要刪除的東東

    SELECT t.*,ROWID FROM TEST t WHERE ROWID > (SELECT MIN(ROWID) FROM TEST);

    DELETE FROM TEST t WHERE ROWID > (SELECT MIN(ROWID) FROM TEST);

    ?

    --語句有缺點:條件不足,會只保留一條數據,誤刪其他數據

    --重新插入測試數據

    INSERT INTO TEST VALUES(1,'xiaoming');

    INSERT INTO TEST VALUES(2,'xiaoming');

    INSERT INTO TEST VALUES(3,'xiaoming');

    INSERT INTO TEST VALUES(4,'Rose');

    INSERT INTO TEST VALUES(5,'Rose');

    COMMIT;

    --剔除重復數據

    SELECT * FROM TEST WHERE ROWID NOT in(SELECT MIN(ROWID) FROM TEST GROUP BY NAME);

    DELETE TEST WHERE ROWID NOT in(SELECT MIN(ROWID) FROM TEST GROUP BY NAME);

    ?

    注意:刪除重復記錄一定要小心,萬一你的條件有問題,就會刪錯數據.建議刪除之前,可以先用查詢查一下,看是否是目標數據。

    數據一旦刪除恢復比較麻煩,但可以恢復,采用日志回滾。一般不要輕易用。

    ?

  • 數據處理

  • 說完了所有的查詢,下面說說增、刪、改。

  • Update

    • 使用工具進行更新數據的操作。(通過rowid偽列)

    通過工具修改數據

    提示:是否能使用工具修改,主要看語句有沒有rowid。

    ?

  • Insert

  • 批量插入

  • 語法:

    INSERT INTO table VALUES--單條插入語法

    INSERT INTO table SELECT查詢語句--批量插入語法(主要用于將一張表中的數據批量插入到另外一張表中)

    ?

    【示例】需求:將dept表中部門名稱不為空的數據都插入到test表中

    --需求:將dept表中部門"名稱"不為空的數據都插入到test表中

    INSERT INTO TEST(ID,NAME) SELECT deptno,dname FROM dept;--select的結果必須能插入到目標表中。(字段個數要對應、字段類型要對應)

    INSERT INTO TEST SELECT deptno,dname FROM dept ;--必須前后字段對應

    --非法使用批量插入

    INSERT INTO TEST SELECT deptno,dname,loc FROM dept ;

    ?

  • Delete

  • Delete和truncate區別-面試題

    • delete逐條刪除,truncate先摧毀表,再重建
    • 最根本的區別是:delete是DML(可以回滾,還能閃回),truncate是DDL(不可以回滾 ,后面的所事務會講回滾)
    • Delete不會釋放空間,truncate會(當確定一張表的數據不再使用,應該使用truncate)
    • delete會產生碎片,truncate不會。

    友情提示:面試經常會被問道。

    ?

  • Hwm-高水位

  • 高水位線英文全稱為high water mark,簡稱HWM,那什么是高水位呢?

    在Oracle數據的存儲中,可以把存儲空間想象為一個水庫,數據想象為水庫中的水。水庫中的水的位置有一條線叫做水位線,在Oracle中,這條線被稱為高水位線(High-warter mark, HWM)。在數據庫表剛建立的時候,由于沒有任何數據,所以這個時候水位線是空的,也就是說HWM為最低值。當插入了數據以后,高水位線就會上漲,但是這里也有一個特性,就是如果你采用delete語句刪除數據的話,數據雖然被刪除了,但是高水位線卻沒有降低,還是你剛才刪除數據以前那么高的水位。也就是說,這條高水位線在日常的增刪操作中只會上漲,不會下跌。

    ?

    【高水位對Oracle的應用有什么影響呢?】

    高水位對查詢有巨大的影響。而且還浪費空間。

    ?

    【解讀Oracle中Select語句的特性】

    極端例子:數據庫有10w條數據,刪掉了前面的99999個,我select查詢的時候,還是需要掃描10w次,雖然表中只有一條數據。效率還是非常的低!!!!!

    ?

    如何解決高水位帶來的查詢效率問題呢?

  • 將表數據備份出來,摧毀表再重建(truncate table),然后再將數據導回來。
  • 收縮表,整理碎片,可使用變更表的語句:alter table 表名 move
  • ?

    ?

    【示例】查看、測試、消除高水位—了解

    --之前查看rowid

    SELECT t.*,ROWID FROM TEST t;

    ?

    --對表進行分析,收集統計信息(執行了收集信息的動作,user_tables表的塊字段才有數據)

    analyze table TEST compute statistics;

    --查詢表數據的塊信息,其中blocks是高水位,empty_blocks是預申請的塊空間。

    select table_name,blocks,empty_blocks from user_tables where table_name='TEST';

    --收縮表(整理碎片),降低高水位,消除行移植和行鏈接,不釋放申請的空間

    ALTER TABLE TEST MOVE;

    ?

    --對表進行分析,收集統計信息(執行了收集信息的動作,user_tables表的塊字段才有數據)

    analyze table TEST compute statistics;

    --查詢表數據的塊信息,其中blocks是高水位,empty_blocks是預申請的塊空間。

    select table_name,blocks,empty_blocks from user_tables where table_name='TEST';

    ?

    --之后查看rowid

    SELECT t.*,ROWID FROM TEST t;

    結論:

    • 收縮表之后,高水位線下降了。
    • 收縮表之后,rowid發生了變化。

    ?

    注意:

    • move最好是在空閑時做,記得move的是會產生鎖的(如果你move的時候需要很長事件,那么別人是不能操作這張表的。排他鎖)
    • move以后記得重建index(后續講到索引,你會知道索引存放的其實就是數據的地址信息。當數據的地址變動了,索引也會失效。)語法:ALTER INDEX 索引名字 REBUILD;

    ?

  • 數據庫事務

  • 什么是數據庫事務?

  • 事務是保持數據的一致性,它由相關的DDL或者DML語句做為載體,這組語句執行的結果要么一起成功,要么一起失敗。

    ?

  • 事務的特性

  • SQL92標準定義了數據庫事務的四個特點(ACID):

    原子性 (Atomicity) :一個事務里面所有包含的SQL語句是一個執行整體,不可分割,要么都做,要么都不做

    一致性 (Consistency) :事務開始時,數據庫中的數據是一致的,事務結束時,數據庫的數據也應該是一致的

    隔離性 (Isolation): 多個事務并發的獨立運行,而不能互相干擾,一個事務修改,新增,刪除數據在根據當前事務的事務隔離級別基礎上,其余事務能看到相應的結果(這里為什么這么說,下面我會給我具體的例子進行分析)

    持久性 (Durability) : 事務被提交后,數據會被永久保存

    ?

  • 事務的開始和結束

  • Oracle的默認事務開啟和結束是跟mysql不一樣的。

    回顧:mysql的事務是如何開啟的?

    MySQL默認采用autocommit模式運行。這意味著,當您執行一個用于更新(修改)表的語句之后,MySQL立刻把更新存儲到磁盤中,不需要手動提交。

    如果需要手動管理事務,需要顯式的關閉自動事務:Set autocommit false,然后顯式的手動開啟事務:START TRANSACTION,直到手動COMMIT或ROLLBACK結束事務為止。

    ?

    那么,Oracle的事務是如何開啟的?

    Oracle的事務默認是手動管理事務,事務是自動開啟(不需要顯式的開啟,隱式開啟),但一般需要手動提交關閉。

    ?

    Oracle事務的開始和結束的觸發條件:

    • 事務的開始:以第一個DML語句(insert update delete)的執行作為開始,即是自動開啟的事務。
    • 事務的結束(以下條件之一):
      • 顯式結束:commit, rollback(還是隱式commit)
      • 隱式結束(自動提交):DDL(create table…)和DCL(所以不能回滾 ),exit(事務正常退出)
      • 隱式回滾(系統異常終止):關閉窗口,死機,掉電。

    ?

    工具上的事務按鈕:

    ?

    隱式提交:

    ?

    提示:一般情況下,我們盡量使用手動提交事務。

    ?

  • 控制事務-保留點SAVEPOINT—了解

  • 事務過程中是可以控制的,通過SAVEPOINT語句。

    SAVEPOINT的作用:

    • 使用 SAVEPOINT 語句在當前事務中創建保存點,語法:SAVEPOINT 保留點名稱。
    • 使用 ROLLBACK 語句回滾到創建的保存點。語法:ROLLBACK TO 保留點名稱。

    ?

    【示例演示】

    SELECT * FROM TEST;

    INSERT INTO TEST VALUES(85,NULL);

    SELECT * FROM TEST;

    SAVEPOINT aa;--保留點

    INSERT INTO TEST VALUES(86,NULL);--后悔了,不插入了

    SELECT * FROM TEST;

    --回滾

    ROLLBACK TO aa;

    SELECT * FROM TEST;

    INSERT INTO TEST VALUES(87,NULL);

    SELECT * FROM TEST;

    --提交

    COMMIT;

    SELECT * FROM TEST;

    ?

    注:

    當前事務提交后,事務中所有的保存點將被釋放。

    ?

    JAVA中也有關于保留點的API,

    具體調用采用Connection對象來操作它,相關方法如下:

    ?

    ?

  • 數據庫對象-表(TABLE)

  • 什么是數據庫對象?

  • 數據庫對象,是數據庫的組成部分,有表(Table )、索引(Index)、視圖(View)、用戶(User)、觸發器(Trigger)、存儲過程(Stored Procedure)、圖表(Diagram)、缺省值(Default)、規則(Rule)等。

  • 表的命名規則和命名規范

  • 表名和列名的基本規范如下:

    【擴展】

    另外,每個公司都有自己特有的命名規范,比如,要求所有的數據庫對象都要加上一個前綴,用于快速識別對象的類別。

    比如表的命名:

    t_person :存放個人信息的表。

    t_crm_person:存放客服子系統模塊的人員信息表。

    視圖的命名:

    v_person:用來查詢人員信息的視圖。

    ?

    命名規范的作用:

    • 良好的命名規范便于識別和管理,對于系統開發和維護都有很大的幫助。
    • 使用工具的提示功能也更容易快速定位到所需要的對象。

    ?

  • 創建表CREATE TABLE

  • 基本語法

  • 創建表的要求條件:

    • 必須具備CREATE TABLE權限、存儲空間。
    • 必須指定表名、列名、數據類型、數據類型的大小

    ?

  • 復制表

  • 語法:

    Create table 新表 as select from 舊表 條件(如果條件不成立,則只復制結構,如果條件成立,復制結構和值)

    ?

    ?

    使用子查詢創建表,而且還可以將創建表和插入數據結合起來。

    【示例】

    --復制一張和原來一模一樣的新表,包含數據

    --復制一張和原來一模一樣的新表,包含數據

    CREATE TABLE t_dept AS SELECT * FROM dept;

    SELECT * FROM t_dept

    ?

    --復制一張和原來一模一樣的新表,不要數據,只要結構

    CREATE TABLE t_dept_empty AS SELECT * FROM dept WHERE 1<>1;

    SELECT * FROM t_dept_empty;

    ?

    ?

    ---t_dept,在現網(正式環境)確實要測試一下數據.一般我們可以在建立一張和這個一模一樣的表.c

    ?

    --能不能只復制部分字段建立新表?可以!

    --復制表的部分字段

    CREATE TABLE t_dept_part AS SELECT deptno,dname FROM dept;

    SELECT * FROM t_dept_part;

    ?

    提示:

    復制表有沒有數據的區別,是select子句結果有沒有數據。如果子句結果沒有數據,則僅創建表,如果有數據,則創建表的同時也插入符合條件的數據。

    ?

    注意:

    • 指定的列和子查詢中的列要一一對應
    • 通過列名和默認值定義列

    關于where 1=1的寫法,一般我們用來拼湊條件的。

    1<>1是為了營造一個永遠不成立的條件。

    ?

  • Oracle的數據類型

  • ?

  • 修改表ALTER TABLE

  • 基本語法

  • 修改表的列:

    ?

    修改表的列的能力:

    • 追加新的列
    • 修改現有的列
    • 刪除一個列

    ?

    修改對象的名稱:

    作用:

    • 執行RENAME語句改變表, 視圖, 序列, 或同義詞的名稱。
    • 要求必須是對象的擁有者

    【示例】

    RENAME t_dept TO t_dept_new;

    Table renamed.

    ?

  • 通過工具來修改表

  • 操作方式:

    ?

  • 刪除表DROP TABLE

  • 基本語法

  • 注意:

    • 數據和結構都被刪除。
    • 所有正在運行的相關事物被提交。(ddl語句)
    • 所有相關索引被刪除。(表附屬對象會被刪除)
    • DROP TABLE 語句不能回滾,但是可以閃回。

    ?

    完整的oracle數據庫的版本的情況下,普通用戶刪除的表,會自動放入回收站

    你可以從回收站還原(閃回)。

    ?

    友情提示:

    日常操作中,刪除操作一定要小心,一旦刪除了且沒有放入回收站,則意味著數據的丟失!

    記住一句話:數據無價!!!

  • 約束

  • 約束的概念作用

    • 約束是可以更好的保證數據庫數據的完整性和一致性的一套機制。
    • 約束可以限制加入表的數據的類型。
    • 如果存在依賴關系,約束可以防止錯誤的刪除數據,也可以級聯刪除數據。

    ?

    數據庫的約束可以認為是對表的數據的一種規則。

  • 約束創建的時機

    • 創建表的時候,同時創建約束。
    • 表結構創建完成后,可以再添加約束。
  • 常見的約束類型

    • NOT NULL
    • UNIQUE
    • PRIMARY KEY
    • FOREIGN KEY
    • DEFAULT
    • CHECK—用來檢查一個字段的值是否符合某表達式,表達式的結果必須是布爾值。

    ?

    其中:check約束是Oracle特有的約束。

    ?

  • 通過工具快速添加約束

  • ?

    通過工具快速得到SQL的代碼:

    插入數據測試Check約束

    ?

    ?

  • 約束的應用選擇

  • 在應用開發中,主鍵約束一般要設置,其他如非空、唯一、默認值、檢查等約束,可以根據實際情況來添加。而外鍵約束是否要設置,是存在一點爭議的。(爭議在性能上

    一般建議:

    • 在大型系統中(性能要求不高,安全要求高),可以使用外鍵;在大型系統中(性能要求高,安全自己控制),不用外鍵;小系統隨便。
    • 不用外鍵的話,可以用程序控制數據一致性和完整性,可以在代碼的數據層通過代碼來保證一致性和完整性。
    • 用外鍵要適當,不能過分追求。

    ?

    從JAVA開發的角度上說,一般不建議使用外鍵,除了性能外,使用程序控制業務更靈活。

    比如客戶和訂單,這兩個之間的關聯雖然可以建立外鍵關系,實現級聯效果(如級聯刪除)。

    • 如果有外鍵約束,則刪除客戶的時候,必須先刪除客戶下的訂單,否則,不允許刪除。
    • 從數據完整一致性的角度上說,如果客戶被刪除了,訂單也無意義了,這是合理的。
    • 但從業務角度上說,客戶被刪除了,是否意味這訂單也必須刪除呢?單純保留訂單的行為也是合理的。

    ?

  • 序列-sequence

  • 需求:

    Mysql中主鍵有自增長的特性.

    Oracle中,主鍵沒有自增長這個特性.那么如何解決這個問題.使用序列可以解決.

  • 概念和作用

  • 序列:可供多個用戶來產生唯一數值的數據庫對象

    . 自動提供唯一的數值

    . 共享對象

    . 主要用于提供主鍵值

    . 將序列值裝入內存可以提高訪問效率

    ?

    這個是Oracle特色的。Mysql是沒有的。

    簡單的說,他可以用來高效的生成主鍵值。

    ?

  • 語法

  • 將序列提前裝入內存,可以提高效率。

  • 創建序列

  • 【示例】

    創建一個簡單的序列

    CREATE SEQUENCE seq_test;

    ?

  • 序列的使用

  • 在ORACLE中為序列提供了兩個偽列

  • NEXTVAL 獲取序列對象的下一個值(指針向前移動一個,并且獲取到當前的值。)
  • CURRVAL 獲取序列對象當前的值
  • ?

    【示例】

    為什么?

    原因是:序列初始化之后指針在第一個數之前。必須先向前移動才可以查詢的到。

    數組的指針默認在1之前,并沒有指向第一個值,要想使用必須向前移動一下。(指針只能向前不能向后)

    [1,2,3….20][

    *

    操作指針:

    [1,2,3….20][

    *

    ?

    SELECT seq_test.nextval FROM dual;

    移動一位并且取值。

    ?

  • 序列的應用

  • Oracle建表的時候是否能像mysql那樣設定一個自增長的列嗎?

    不行!

    那如何解決呢?使用序列!

    ?

    【示例】在插入數據的時候插入序列主鍵.

    --在插入數據的時候插入序列主鍵.

    INSERT INTO TEST VALUES(seq_test.nextval,'Jack');

    ?

    問題:為什么這個值不是從1開始?

    原因: 共享對象 序列是個獨立對象.誰都能用,誰都能共享它.

    ?

  • 序列的裂縫

  • 序列是一個共有對象,多個表都可以調用。但實際開發中,可以避免多個表用一個序列(創建多個序列)。序列是獨立的對象。任意表都可以使用,但是編號就不能保證有序
  • 2,當插入記錄時報錯,序列對象值也被使用,下一次再使用時,序列的值就會+1

    ?

    【示例】序列的裂縫

    INSERT INTO T_TESTSEQ VALUES(seq_test.nextval,'張三1');

    ROLLBACK;

    INSERT INTO T_TESTSEQ VALUES(seq_test.nextval,'張三2');

    COMMIT;

    SELECT * FROM T_TESTSEQ;

    也就是說,用序列插入數據庫的值不一定是連續的

    補充:

    Mysql的自增長列也可以是不連續的.

    ?

    序列出現裂縫的條件:

    • 事務回滾。
    • 系統異常。
    • 多個表同時使用同一個序列。

    ?

    這個序列是公用的對象。如果你很在意的話,就一個表用一個序列,但大多數情況下,這個主鍵值(代理主鍵)沒有什么意義的話,可以多個表公用一個序列。

    ?

  • Oracle的體系結構-了解

  • Oracle數據庫和Oracle實例

  • Oracle 服務器軟件部分由兩大部分組成, Oracle 數據庫 和 Oracle 實例。

    兩者的解釋如下:

    • Oracle 數據庫(物理概念): 位于硬盤上實際存放數據的文件和相應的程序文件, 這些文件組織在一起, 成為一個邏輯整體, 即為 Oracle 數據庫. 因此在 Oracle 看來, "數據庫" 是指硬盤上文件的邏輯集合, 必須要與內存里實例合作, 才能對外提供數據管理服務。
    • Oracle 實例(邏輯概念): 位于物理內存里的數據結構. 它由一個共享的內存池和多個后臺進程所組成, 共享的內存池可以被所有進程訪問. 用戶如果要存取數據庫(也就是硬盤上的文件) 里的數據, 必須通過實例才能實現, 不能直接讀取硬盤上的文件。實例的唯一標識也稱之為SID(OSID)。

    ?

    一個實例只能對應一個數據庫,一個數據庫可以有多個實例(RAC集群),但大多數情況下, 一個數據庫上只有一個實例對其進行操作。我們就是通過連接到實例來操作數據庫的。

    ?

  • Oracle常見的存儲文件

  • 常見的存儲文件主要為三類:

    • 數據文件。存儲數據用的。

    例:表

    • 控制文件。記錄數據文件存放的位置。例:數據庫名稱、數據文件名稱及位置。

    • 日志文件。記錄數據信息變化的。例:因故障問題造成一些數據沒有及時寫入到數據文件,可以使用日志文件恢復(Oracle日志回滾:如果你的數據被delete掉并且提交了,數據還是可以恢復的,可以通過日志來恢復的)。

    ?

  • 表空間(Tablespace)的管理

  • 表空間的概念

  • ORACLE是屬于文件存儲。ORACLE中的數據是存放在一個個數據文件中,數據文件存放在磁盤中。

    如果說數據文件是物理概念,那么表空間就是邏輯概念,Oracle通過表空間來對數據文件中的數據進行CRUD。

    表空間是一種邏輯結構,是Oracle最大的邏輯單元,可以理解為:所有的數據都存儲在表空間中。

    表空間的屬性特點:

    • 一個數據庫可以包含多個表空間,一個表空間只能屬于一個數據庫。
    • 一個表空間可以由一個或多個數據文件組成,一個數據文件只能屬于一個表空間。
    • 表空間可以劃分成更細的邏輯存儲單元。(了解)

    ?

  • 數據庫的存儲結構--了解

  • 官方數據存儲結構圖:

    各對象之間的存儲對應關系圖:

    • 所有的數據庫對象都存儲在表空間中,而表空間被數據庫服務管理。
    • 一個表空間可以對應N個數據文件,表空間是邏輯概念,而數據文件是物理概念。
    • 方案(SCHEMA模式)是表、視圖、索引等數據庫對象的邏輯集合,它通過數據庫服務來間接管理這些對象。
    • 一個用戶(user)創建時會同時創建一個同名的方案(schema),即,你甚至可以認為用戶和方案是同一個東西(事實上不是,用戶主要是做權限等相關管理的)。當用戶登錄后,就立刻擁有了該同名方案下所有對象。
    • 方案(用戶)和表空間沒有什么必然關系,一個方案擁有一個默認的表空間,但同時可以使用多個表空間來存儲它的對象。一個表空間可以為不同的方案來存儲其所屬對象

    ?

    【補充閱讀】下面有個很形象的比喻,是從網上摘的,不妨一看:

    我們可以把database看做是一個大倉庫,倉庫分了很多很多的房間,schema就是其中的房間,一個schema代表一個房間,table可以看做是每個schema中的床,table被放入每個房間中,不能放置在房間之外,那豈不是晚上睡覺無家可歸了,然后床上可以放置很多物品,就好比table上可以放置很多列和行一樣,數據庫中存儲數據的基本單元是table,顯示中每個倉庫放置物品的基本單位就是床,user就是每個schema的主人,(所以schema包含的是object,而不是user),user和schema是一一對應的,每個user在沒有特別指定下只能使用自己schema的東西,如果一個user想使用其他schema的東西,那就要看那個schema的user有沒有給你這個權限了,或者看這個倉庫的老大(DBA)有沒有給你這個權限了。換句話說,如果你是某個倉庫的主人,那么這個倉庫的使用權和倉庫中的所有東西都是你的,你有完全的操作權,可以扔掉不用東西從每個房間,也可以防止一些有用的東西到某個房間,你還可以給每個user分配具體的權限,也就是他到某一個房間能做些什么,是只能看(read-only),還是可以像主人一樣有所有控制權(R/W),這個就要看這個user所對應的角色Role了。

    ?

    作業: 課后了解 用戶和方案的關系

    ?

    數據操作的過程:

    【小結】

    表空間:屬于一種邏輯結構。記錄物理文件的邏輯單位。是Oracle最大的邏輯單位.

    也就是說,我們所有的數據都存儲在表空間中.

    ?

  • 常見的表空間分類—了解

    • (永久)數據表空間,主要用來永久存儲正式的數據文件。
    • 臨時數據表空間,主要用來存儲臨時數據的,比如數據的排序、分組等產生的臨時數據,不能存放永久性對象。
    • UNDO表空間,保存數據修改前的鏡象。

    ?

    臨時表空間和UNDO表空間的異同:(了解)

    • 相同之處:兩者都不會永久保存數據。
    • 不同之處:UNDO表空間用于存放UNDO數據,當執行DML操作時,oracle會將這些操作的舊數據寫入到UNDO段,以保證可以回滾和事務隔離讀取等,主要用于數據的修改等;而臨時表空間主要用來做查詢和存放一些緩沖區數據。
  • Oracle對表空間的管理方式—了解

  • 字典管理:全庫所有的空間分配都放在數據字典中。容易引起字典爭用,而導致性能問題。

    本地管理:空間分配不放在數據字典,而在每個數據文件頭部的第3到第8個塊的位圖塊,來管理空間分配。oracle公司推薦使用本地管理表空間。

    ?

  • 表空間的創建

  • 注:表空間的創建一般是由DBA來操作完成的,而且需要管理員權限(我們一般用sys)。

    三種表空間中,UNDO表空間通常是由Oracle自動化管理的,而另外兩種表空間則一般需要手動創建。

    【常用參數語法】:

    --創建永久數據表空間

    CREATE TABLESPACE TABLESPACE_NAME

    [DATAFILE DATAFILE1,[DATAFILE 2]…]

    [LOGGING | NOLOGGING]

    [ONLINE|OFFLINE]

    [EXTENT_MANAGEMENT_CLAUSE]

    ?

    參數說明:

    • TABLESPACE_NAME,表空間名稱隨意,但最好遵循一定的規范,如tbl_itcast18_dat、tbl_itcast18_tmp等。
    • DATAFILE,表空間的類型
    • DATAFILE1 數據文件需要有如下格式:文件名 SIZE 初始文件大小 [AUTOEXTEND OFF| ON] [MAXSIZE|NEXT SIZE MAXSIZE SIZE]
      • 文件名是數據文件的路徑名,可以是絕對路徑,也可以是相對路徑,如"路徑\xxx.dbf",注意路徑必須先建立好。
      • 初始化文件大小,是數據文件剛建立起來的時候所占物理磁盤空間的大小;
      • AUTOEXTEND,是否自動擴展數據文件的大小,OFF表示關閉自動擴展,數據文件只能是初始大小,ON表示開啟自動擴展,當數據文件超過初始大小的時候,會自動增大。默認值為OFF。
      • 如果設置自動擴展,則需要設置最大值MAXSIZE,如設置2000m,當然也可以設置為UNLIMITED,表示無限表空間。如果要指定每次擴展的大小,可以使用NEXT SIZE MAXSIZE SIZE語法,表示每次擴展多少尺寸,最大能擴展到多大(大小上限)。
    • [LOGGING | NOLOGGING]該子句用來聲明這個表空間上所有的用戶對象的日志屬性,即當操作包括表,索引,分區,物化視圖,物化視圖上的索引,分區等是否記錄日志。缺省值為LOGGING。
    • [ONLINE|OFFLINE]表空間的狀態,ONLINE表示表空間創建后立即有效,OFFLINE表示表空間創建后暫時無效,即不能使用,只有設置為ONLINE后才有效,默認值為ONLINE。
    • EXTENT_MANAGEMENT_CLAUSE表空間如何管理范圍,推薦設置為本地管理,值為EXTENT MANAGEMENT LOCAL,如果不指定該值,則ORACLE會根據初始化時內部的其他參數進行自動設置一個默認值,生產環境下建議指定該值為本地管理。

    ?

    --創建臨時數據表空間

    CREATE TEMPORARY TABLESPACE TABLESPACE_NAME

    TEMPFILE DATAFILE1,[DATAFILE 2]…

    EXTENT_MANAGEMENT_CLAUSE

    參數說明:

    • DATAFILE1數據文件的格式語法:文件名 SIZE 初始文件大小,注意臨時數據表空間的數據文件一般不需要指定最大值,Oracle對其采用了貪吃算法策略,因此,該表空間會自動逐漸增大。當然你也可以手動指定。
    • 其他參數見永久數據表空間的。
    • 臨時表空間默認是不記日志的。

    【最簡語法】

    Create tablespace 表空間名稱

    表空間類型

    '物理文件全路徑'

    Size 初始文件大小

    ?

    【示例】

    永久數據表空間和臨時數據表空間的建立。

    --建立一個數據表空間。

    CREATE TABLESPACE tbl_itcast_dat

    DATAFILE

    'D:\Applications\Oracle\mydata\itcast_dat01.dbf'

    SIZE 50m

    AUTOEXTEND ON

    NEXT 5m

    MAXSIZE 2000m

    EXTENT MANAGEMENT LOCAL

    ?

    --創建臨時數據表空間。

    CREATE TEMPORARY TABLESPACE tbl_itcast_tmp

    TEMPFILE

    'D:\Applications\Oracle\mydata\itcast__tmp.dbf'

    SIZE 20m

    EXTENT MANAGEMENT LOCAL

    ?

    解釋:

    ?

    ?

    【提示】:

    文件路徑(data目錄)必須提前存在,否則:

    ?

    注意:

    實際企業開發中,不要用最簡化的方式來進行表空間的創建。

    【參考示例1】

    --創建數據表空間

    CREATE TABLESPACE TBS_CSP_BS_DAT

    DATAFILE '/dev/rlv_dat001' SIZE 2000M REUSE AUTOEXTEND OFF,

    LOGGING

    ONLINE

    PERMANENT

    EXTENT MANAGEMENT LOCAL;

    --創建臨時數據表空間

    CREATE TEMPORARY TABLESPACE TBS_CSP_BS_TMP

    TEMPFILE '/dev/rlv_dat009' SIZE 2000M REUSE AUTOEXTEND OFF

    EXTENT MANAGEMENT LOCAL UNIFORM SIZE 10M;

    注:

    PERMANENT是顯式的指定創建的是永久的表空間,用來存放永久對象。默認值。

    【參考示例2】

    --創建數據表空間

    create tablespace tbs_user_data

    logging

    datafile 'D:\oracle\oradata\Oracle9i\user_data.dbf'

    size 50m

    autoextend on

    next 50m maxsize 20480m

    extent management local;

    --創建臨時數據表空間

    create temporary tbs_user_temp

    tempfile 'D:\oracle\oradata\Oracle9i\user_temp.dbf'

    size 50m

    autoextend on

    next 50m maxsize 20480m

    extent management local;

    ?

  • 刪除表空間

  • 語法:

    DROP TABLESPACE

    ?

    ?

    【示例】

    --刪除表空間以及下面所有數據和數據文件(全刪,寸草不生)

    DROP TABLESPACE tbl_itcast_tmp INCLUDING CONTENTS AND DATAFILES;

    提示:如果不加后面的一堆,則,只是將表空間進行了邏輯刪除(Oracle無法管理使用這個表空間了,但數據文件還存在)。

    ?

  • 表空間的一個應用

  • 【示例】

    建立表的時候指定表空間。

    ?

    企業開發中,一定不要用默認的表空間,一定使用要指定表空間。

    最簡的一個建表腳本:

    注意:

    寫建表的語句的時候,可以指定存儲的表空間,但不建議指定表空間的參數。

    ?

  • 用戶和權限

  • 用戶角色權限的關系

  • 預備知識:

  • 預定義用戶(賬戶)

  • Oracle預定義有很多用戶,用于不同的用途。這些用戶大都默認是禁用的(如scott,hr等),但有兩個最重要的用戶是默認開啟的,這兩個用戶就是SYS和SYSTEM。

    ?

    • SYS 帳戶(數據庫擁有者):
      • 擁有 DBA 角色權限
      • 擁有 ADMIN OPTION 的所有權限
      • 擁有 startup, shutdown, 以及若干維護命令
      • 擁有數據字典
    • SYSTEM 帳戶
      • 擁有 DBA 角色權限.

    ?

    注意:這些帳戶通常不用于常規操作。

    ?

    Sys和system賬戶的區別:

    • sys用戶是數據庫的擁有者,是系統內置的、權限最大的超級管理員帳號
    • system用戶只是擁有DBA角色權限的一個管理員帳號,其實它還是歸屬于普通用戶。

    ?

  • 操作用戶

    • 創建用戶的語句

    create user 用戶名

    identified by 密碼(不要加引號)

    default tablespace 默認表空間名 quota 5M on 默認表空間名

    [temporary tablespace 臨時表空間名]

    [profile 配置文件名] //配置文件

    [default role 角色名] //默認角色

    [password expire] //密碼失效

    //如果設置失效,那么第一次登錄的時候,會提醒你更改密碼。

    [account lock] //賬號鎖定(停用)

    • 修改用戶

    alter user 用戶名 identified by 密碼 quota 10M on 表空間名

    alter user 用戶名 account lock/unlock

    • 刪除用戶

    drop user 用戶名 [cascade].如果要刪除的用戶中有模式對象,必須使用cascade.

    ?

    【示例】最簡方式創建一個用戶

    切換到sys用戶下:

    注:未指定的參數都采用默認值。

    ?

    【示例】借助工具創建一個用戶

    ?

    創建用戶的時候指定的表空間,會成為以后在該用戶下建立對象(表)的默認存儲表空間。

    ?

    -- 語句:Create the user

    /*創建用戶并指定表空間 */

    create user itcast19

    identified by itcast19

    default tablespace TBL_ITCAST19_DAT

    temporary tablespace TBL_ITCAST19_TMP; --上鎖解鎖改密碼等

    ?

    注意:

    一般企業開發中,建表要手動指定表空間,可以讓不同模塊、不同功能的對象存儲在不同的數據文件中,可以提高性能。

    ?

    ?

    【示例】刪除用戶

    --刪除用戶及其下面所有的對象

    drop user itcasttest cascade;

    ?

    提示,每個數據庫用戶帳戶具備:

    • 一個唯一的用戶名
    • 一個驗證方法
    • 一個默認的表空間
    • 一個臨時表空間
    • 權限和角色
    • 每個表空間的配額.

    ?

  • 配置角色和權限

  • 使用上面創建的用戶登錄測試:

    結果報錯。

    提示說:該用戶沒有創建會話的權限,登錄被拒絕。

    ?

    那該如何賦權呢?賦什么權限呢?

    Oracle內置有大量的權限屬性:

    常見權限:

    我們可以將create session權限賦權給新建的用戶.新建的用戶就可以登錄了.

    我們再建立一張表看看:

    結果又提示是權限不足。= =...

    再添加建表的權限:

    再次測試建表:

    再添加一條數據看看:

    竟然又沒有權限!

    。。。

    結論:這樣一個個添加權限非常的麻煩!

    是否可以使用比較簡單的方式將普通用戶的權限賦予給一個用戶呢?

    可以!通過預定義內置角色就可以實現。

    ?

    需要分配 unlimited tablespaces 權限

    如何選擇預定義的角色呢?

    普通用戶就選擇:connect和Resource角色即可。

    管理員用戶選擇:connect和Resource、dba角色。

    ?

    /*給用戶授予權限 */

    grant connect,resource to username;

    再次登錄、各種操作測試,均正常了!

    ?

    【提示】

    如果遇到這個錯誤:

    說明當前用戶沒有操作該表空間的權限,需要手動加入這個權限:

    ????

    ?

    梳理回顧建立一個普通用戶的過程:

    1.創建用戶—2.賦權限(connect和resourece角色)

    ?

  • Oracle用戶(user)和方案(schema)

  • 幾個概念:

    • 方案就是屬于某一用戶的所有對象(表、視圖等)的集合.
    • 用戶名和方案名往往是通用的.
    • 一個用戶只能關聯一個方案.
    • 創建用戶時系統會自動創建一個同名方案(schema)

    ?

    提示:

    Scott用戶的方案名也是scott,因此,后面我們將這兩個概念放在一起用,即我們可以說,某表是scott用戶下的對象,也可以說是scott方案下的對象。

    ?

    ?

  • 跨域訪問對象

  • 跨域訪問也稱之為跨用戶訪問、跨方案訪問,訪問的方式為:用戶名.對象名,

    ?

    如在itcast用戶下訪問scott用戶下的emp表的數據:

    Select * from scott.emp;

    原因:沒有對象訪問權限。

    ?

    ?

    Oracle用戶的權限分為兩種:

    • 系統權限(System Privilege): 允許用戶執行對于數據庫的特定行為,例如:創建表、創建用戶等
    • 對象權限(Object Privilege): 允許用戶訪問和操作一個特定的對象,例如:對其他方案下的表的查詢

    ?

    ?

    【示例】需求:itcast用戶要讀取scott用戶中emp表的數據。

    --scott用戶登錄賦權:

    --Sql語句:

    ?

    --itcast用戶登錄測試:

    ?

    注意:

    賦權的時候,只能是自己擁有的權限、或者該權限是可以傳遞的,才可以將其賦予別人。

    ?

  • 視圖VIEW

  • 問題:

    Itcast用戶現在只需要查詢10部門的員工數據就行了,scott也不想將所有數據都開放給itcast用戶。

  • 視圖的概念和作用

  • 概念:

    • 視圖是一種虛表.
    • 視圖建立在已有表的基礎上, 視圖賴已建立的這些表稱為基表
    • 向視圖提供數據內容的語句為 SELECT 語句, 可以將視圖理解為存儲起來的 SELECT 語句.
    • 視圖向用戶提供基表數據的另一種表現形式

    作用:

  • 語法

  • ?

    語法: create VIEW 視圖名稱 as select ….

    ?

    提示:

    子查詢可以是任意復雜的 SELECT 語句。

    ?

    語法詳細分析:

    糾正:默認值不是只讀。

    ?

  • 操作視圖

  • 視圖只能創建、替換和刪除,不能修改。

  • 創建視圖

  • 【示例】創建10號部門的視圖

    --sql語句建立視圖

    CREATE VIEW v_emp10

    AS

    SELECT * FROM emp WHERE deptno=10

    ;

    ?

    提示:如果提示權限不足而導致無法添加視圖,則需要添加權限,一般為學習方便,我們會直接添加dba角色權限。

    --切換到sys用戶下,為scott添加dba權限:

    ?

  • 查詢視圖

  • 【示例】查詢視圖

    ?

    ?

    【示例】視圖的真實內容查看

    結論:

    可以看出,視圖的本質就是sql語句。

  • 替換視圖

  • 視圖沒有修改功能。

    【示例】要將視圖改為可以查詢10號部門的員工信息且工資要大于2000:

    CREATE OR REPLACE VIEW v_emp10

    AS

    SELECT * FROM emp WHERE deptno=10 AND sal >2000;

    提示:

    平時我們在編寫建立視圖的語句時候,一般直接把replace加上,即直接CREATE OR REPLACE。

    ?

  • 刪除視圖

  • 【示例】刪除10好部門的這個視圖

    DROP VIEW v_emp10;

    SELECT * FROM v_emp10;

    ?

  • 幾個參數說明

  • ?

    --先創建視圖再創建表:一般用的不多,一般我們都是先有表再創建視圖。

    CREATE OR REPLACE FORCE VIEW v_test2015

    AS

    SELECT * FROM test2015;

    ?

    SELECT * FROM v_test2015

    ?

    --視圖默認情況下和表一樣,擁有表類似的功能,可以crud

    SELECT t.*,ROWID FROM v_emp10 t;

    SELECT * FROM emp;

    CREATE OR REPLACE VIEW v_emp10

    AS

    SELECT * FROM emp WHERE deptno=10

    WITH CHECK OPTION;--數據的增加和修改,必須滿足子查詢的條件

    ?

    --一般視圖,我們主要用來查詢的,一般不維護它。

    CREATE OR REPLACE VIEW v_emp10

    AS

    SELECT * FROM emp WHERE deptno=10

    WITH READ ONLY;

  • 只讀視圖

  • 一般情況下,視圖主要用來提供查詢的,并不希望用戶去修改它,因此,我們可以創建只讀視圖。創建只讀視圖只需要添加with read only 選項即可,這樣就可以屏蔽對視圖的DML操作。

    【示例】將已有的視圖修改為只讀視圖

    CREATE OR REPLACE VIEW v_emp_dept10

    AS

    SELECT * FROM emp WHERE deptno=10 AND sal >2000

    WITH READ ONLY ;

    ?

    友情提示:

    其實,很多大的系統中,比如銀行,某些客戶會告訴你,這個表存這個數據,那個表存哪個數據,但實際上,可能不是真正的表,而是視圖,而且還是只讀的。

    為什么給視圖?原因是:

    如果是存錢的表,那么放開給你,是不是非常危險。如果業務需要確實是需要更改這個表的數據呢?一般來調用存儲過程(一般有提供,有一定特定功能,還能記錄日志)來改表,為了安全!不能直接改表。

  • 跨域訪問視圖

  • 【示例】只放開scott下的emp表的部分數據給itcast14用戶查詢,開放的數據要求為:20號部門的員工,字段只顯示員工號和姓名,且要求這兩個字段的標題顯示為中文。(要求本例使用工具來操作)

    --在scott下創建視圖(視圖名稱參考為:v_emp_dept20)

    --將生成的腳本如下:

    create or replace view v_emp_dept20 as

    select empno "編號",ename "姓名"

    from emp

    where deptno=20

    WITH READ ONLY;

    --scott下查詢驗證一下:

    SELECT * FROM v_emp_dept20;

    --將該視圖賦予itcast用戶:在scott用戶下操作:

    grant select on v_emp_dept20 to itcast;

    ?

    --切換到itcast用戶下進行查詢驗證:

    Select * from scott.v_emp_dept20;

    ?

    ?

    另外補充:

    視圖可以屏蔽篩選不同字段、字段名稱等,因此,你看到的時候的字段也未必是真實表中存在的!

    CREATE OR REPLACE VIEW v_emp10

    AS

    SELECT empno 編號,ename empname FROM emp WHERE deptno=10

    WITH READ ONLY;

    ?

    ?

  • 視圖小結

  • 視圖和表的區別:

    視圖是實體表的映射,視圖和實體表區別就是于視圖中沒有真實的數據存在

    ?

    什么時候使用視圖:

  • 在開發中,有一些表結構是不希望過多的人去接觸,就把實體表映射為一個視圖。
  • 在項目過程中,程序人員主要關注編碼的性能、業務分析這方面。對于一些復雜的SQL語句,設計人員會提前把這些語句封裝到一個視圖中,供程序人員去調用
  • ?

    注意:在企業中,你查詢的對象(表)他可能不是一張的表,可能是視圖;你看到的視圖的字段可能也不是真實的字段。

    ?

  • 同義詞SYNONYM

  • 問題:我們想偽裝一下這個視圖的名字,或者是嫌調用的這個對象名字太長,怎么辦?

  • 同義詞的概念和作用

  • 同義詞就是(對象的)別名,可以對表、視圖等對象起個別名,然后通過別名就可以訪問原來的對象了。

    作用:

    • 方便訪問其它用戶的對象
    • 縮短對象名字的長度

    ?

  • 語法

  • ?

  • 操作同義詞

  • 同義詞只有創建和刪除操作。

    【需求】在itcast用戶下為視圖scott.v_emp_dept20創建一個同義詞emp20;

    --查詢驗證:

    ?

    友情提示:

    如果工作中,你遇到一張"表"來查詢數據,那么它一定是表么?不一定,可能是視圖,也可能是同義詞.

    另外,任何對象都能起別名。下面的例子對emp表起個別名:

    ?

    ?

    ?

    ?

    ?

    重點:

    ?

  • 多表關聯查詢(oracle的語法,左外,右外 自連接)
  • 子查詢:any和all的面試題,子查詢和多表查詢的選擇(面試)
  • 分頁:rownum+子查詢!!!
  • rowid:刪除重復數據(面試)
  • 兩個新語法:批量插入(insert into table select ...) 復制表(create table tablename as select ....)
  • delete和truncate的區別(面試),高水位,如何消除高水位(truncate,move)
  • Oracle的事務和mysql的事務的不同(oracle在dml時隱式開啟,必須手動提交(不建議隱式提交))
  • 約束的使用(外鍵是否要增加)(面試)
  • 序列:創建(create sequence 序列名字)和插入數據的使用。
  • 表空間-了解
  • 創建用戶:創建用戶+賦予角色(connect,resource,注意:unlimited tablespace權限如果沒有加上)
  • 用戶和方案的關系
  • 跨域訪問
  • 視圖,
  • 同義詞
  • 轉載于:https://www.cnblogs.com/beyondcj/p/6271086.html

    創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎

    總結

    以上是生活随笔為你收集整理的Oracle第二天的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。