Oracle 第4章 同義詞、序列、視圖、索引


Oracle 第3章 鎖、表分區

Oracle 第5章 使用PL/SQL

Oracle 第4章 同義詞、序列、視圖、索引


1、技術目標

  • 使用同義詞
  • 使用序列
  • 創建視圖
  • 創建索引


2、什麼是Oracle數據庫對象?

Oracle 數據庫對象又稱模式對象,
數據庫對象是邏輯結構的集合,最基本的數據庫對象是表,
其他數據庫對象包括:

  • 同義詞
  • 序列
  • 視圖
  • 索引


3、同義詞

同義詞是表、視圖、序列、過程、程序包或者其他同義詞的別名,使用
同義詞訪問對象無需指定模式前綴 ,例如,user1訪問user2的表Test,
必須使用user2.Test,創建一個名爲Test的同義詞代表user2.Test,user1
就可使用Test來訪問user2.Test

同義詞的作用:

  • 簡化SQL語句
  • 隱藏對象的名稱和所有者
  • 爲分佈式數據庫的遠程對象提供位置透明性
  • 提供對對象的公共訪問


注意:在使用同義詞之前要確保用戶已得到訪問對象的權限

同義詞有兩種類型:

  • 私有同義詞
  • 公有同義詞


4、私有同義詞

私有同義詞只能被當前模式用戶訪問,其名稱不能與當前模式的對象名相同,
其語法如下:
create [or replace] synonym [schema.] synonym_name
for [shema.]object_name;

語法說明:

  • or replace 表示在同義詞存在的情況下替換原同義詞
  • synonym_name 要創建的同義詞名稱
  • object_name 指定要爲其創建同義詞的對象名


例如:



注意:要創建私有同義詞必須擁有CREATE ANY SYNONYM系統權限

5、公有同義詞

公有同義詞可被所有數據庫用戶訪問,公有同義詞可隱藏基表的身份,
降低SQL語句的複雜性,系統在安裝時會創建一些字典公有同義詞,
比如,同義詞"TAB"可用來查詢用戶所擁有的表和視圖對象。
語法:
create [or replace] public synonym synonym_name
for [schema.]object_name;

例如:



注意:要創建公有同義詞,必須擁有CREATE PUBLIC SYNONYM系統權限

6、同義詞的使用

使用1: 顯示當前用戶所擁有的表和視圖,使用公有同義詞"TAB"
select * from TAB;

注意:如果該用戶已經創建了名爲TAB的表(本地對象),本地對象優先


使用2:
可查詢字典視圖USER_SYNONYMS來查看用戶創建的同義詞詳細信息

使用3: 刪除同義詞EMP
drop synonym EMP;

注意:刪除同義詞的語法爲,
drop [public] synonym [shema.]synonym_name;

7、序列

  • 序列是用於生成唯一、連續序號的對象
  • 序列通常用來自動生成主鍵或唯一鍵的值
  • 序列可以是升序的,也可以是降序的

使用CREATE SEQUENCE語句創建序列,語法爲:
    create sequence sequence_name
        [start with integer]
        [increment by integer]
        [MAXVALUE integer|NOMAXVALUE]
        [MINVALUE integer|NOMINVALUE]
        [cycle|nocycle]
        [cache integer|nocache];

語法說明:

start with,指定第一個序列號,對於升序序列,默認值爲序列的
    最小值,對於降序序列,默認值爲序列最大值
increment by,指定序號之間的間隔,默認值爲1,如給負數值則
    序列按降序排列
MAXVALUE,指定序列可生成的最大值
NOMAXVALUE(默認選項),如果指定了NOMAXVALUE,升序序列的
    最大值將爲10的27次方
MINVALUE,指定序列的最小值,MINVALUE必須小於或等於start with
    指定的值以及MAXVALUE
NOMINVALUE(默認選項),如果指定了NOMINVALUE,升序序列的
    最小值將爲1,降序序列的最小值將爲-10的26次方
cycle,指定序列在達到最大值或最小值後,繼續從頭開始生成值
nocycle(默認選項),指定序列在達到最大值或最小值後,不會再
    繼續生成值
cache,該選項可預先分配一組序號,並將其保留在內存中,可
    更快的訪問序列號,當用完緩存中的所有序號時,將生成
    另一組數值,並將其保留在緩存中
nocache,使用該選項,將不會預先分配序列號,如果忽略cache
    和nocache,Oracle將默認緩存20個序列號

8、序列的使用

通過序列的僞列可訪問序列的值,僞列有:

  • NEXTVAL:創建序列後第一次使用nextval時,將返回該序列的初始值,以後再使用時,將使用increment by中的值遞增
  • CURRVAL:返回序列的當前值


使用1: 給學員表信息表創建序列,在添加學員信息是使用序列生成學號,

--創建studentId序列(類似標識列,其值可自動增長)
create sequence studentId
start with 1
increment by 1;
--添加學員信息,使用序列的值作爲學號
insert into tbl_stuInfo
(stuId, stuName, stuBirthday)
values (studentId.NEXTVAL, '張4', '15-9月-2010');

使用2: 查看序列的當前值
select studentId.CURRVAL from dual;

9、更改序列

修改序列的定義使用alter sequence語句,可執行如下操作:

  • 設置或刪除MINVALUE或MAXVALUE
  • 修改增量值
  • 修改緩存中的序列號數量

語法如下:
    alter sequence sequence_name
        [increment by integer]
        [MAXVALUE integer | NOMAXVALUE]
        [MINVALUE integer | NOMINVALUE]
        [CYCLE | NOCYCLE]
        [CACHE integer | NOCACHE];

注意:不能修改序列的 start with 參數,升序序列的最小值應小於最大值

使用: 爲序列設置一個新的MAXVALUE,並打開CYCLE,
alter sequence 序列名
    MAXVALUE 5000
    CYCLE;

提示:可通過查詢USER_SEQUENCES視圖獲取用戶所建序列的詳細信息

10、刪除序列

使用drop sequence語句可刪除序列,還可使用此語句重新開始一個序列,
就是先刪除序列,再重新創建該序列,語法 爲:
drop sequence [schema.]sequence_name;

11、視圖

視圖相當於將一個查詢(select)語句存儲下來,將該查詢的結果
當成一張表("虛擬表"),可以針對這張表進行各種查詢等操作,
所以視圖可以視爲"虛擬表"或"存儲的查詢",創建視圖所依據的
表稱爲"基表"(查詢語句中出現的表)

視圖的優點有:

  • 提供了另外一種級別的表安全性
  • 隱藏的數據的複雜性
  • 簡化的用戶的SQL命令
  • 隔離基表結構的改變
  • 通過重命名列,從另一個角度提供數據


創建視圖的語法如下:
create [or replace] [force | noforce] view view_name
[(alias[, alias]...)]
as
select_statement(查詢語句)
[with check option [CONSTRAINT constraint]]
[with read only];

語法說明:

or replace,如果視圖存在就重新創建該視圖
force,無論基表是否存在都將創建視圖
noforce(默認值),基表存在纔會創建視圖
view_name,視圖名
alias,查詢中的表達式或列的別名,其數量必須與
    查詢中出現的表達式數目匹配
select_statement,select語句
with check option,指定只能添加或更新視圖可訪問的行,
    constraint表示check option約束指定的名稱
with read only,確保不能在此視圖上執行任何修改操作

使用1: 創建一個名爲view_ven的試圖,該視圖與vendorMaster
表具有相應結構,可以通過該視圖訪問基表所有行,
create view view_ven
as
select * from vendorMaster;

使用2: 創建一個視圖,只包含訂單表中的"暫掛"訂單記錄
create view view_pause
as
select * from orderMaster
where ostatus = 'P'

說明: 該視圖只顯示ostatus列值爲P的行

注意:如果使用該視圖更新(update)orderMaster
表中的其他行(ostatus列值不爲P的行)的值,也會成功,
所以,儘量不通過視圖修改基表數據


使用3: 防止修改視圖中可顯示的行
--創建一個試圖可顯示ostatus爲p的行
create or replace view view_pause
as
select * from orderMaster
where ostatus = 'p'
with check option CONSTRAINT chk_pv;
--通過視圖修改ostatus的值
update view_pause set ostatus = 'd'
where ostatus = 'p'

執行update語句後會顯示如下內容:

ERROR 位於第...行
ORA-01402:視圖WITH CHECK OPTION違反WHERE子句

使用4: 創建視圖,只顯示基表中指定的列
create or replace view_pause
as
select orderNo, oDate from orderMaster;

注意:通過該視圖只能更新(update)orderNo, oDate兩列

使用5: 創建只讀視圖,該視圖只能查詢(select)
create or replace view view_pause
as
select * from orderMaster
with read only;

12、強制創建視圖

在創建視圖過程中使用force項,即使出現以下情況也會創建視圖:

  • 視圖使用的查詢語句引用了不存在的表
  • 視圖使用的查詢語句引用了表中無效的列
  • 視圖所有者沒有所需權限

這時,Oracle只檢查create view語句中的語法錯誤,語法正確將
創建該視圖,但是該視圖卻不能使用,這種視圖稱爲"帶錯誤創建"
的試圖

13、基於視圖進行添加(insert)、修改(update)、刪除(delete)的限制

  • 只能修改一個底層基表
  • 違法基表的約束條件,無法更新
  • 如視圖中包含連接運算符、distinct、集合運算符、聚合函數、group by    子句,無法更新
  • 如視圖中包含僞列或表達式,無法更新
  • 如視圖中的select爲聯表查詢(這種視圖又稱"聯接視圖"),只能修改單個基表,解決這個問題可使用insert of觸發器來實現視圖同時對多個表進行修改


14、鍵保留表

在聯接視圖中,如果視圖包含了一個表的主鍵,且該鍵也是視圖的主鍵,
則這個鍵被保留,鍵所在的表稱爲"鍵保留表",Oracle可通過該視圖向
表中添加行,含外聯接的視圖一般不含鍵保留表

15、刪除視圖
語法:drop view 視圖名;

16、索引

  • 索引是與表相關的一個可選結構
  • 通過創建索引,可加快對錶執行SQL語句的速度,這好比圖書的目錄可幫我們定位內容一樣
  • 合理使用索引是減少磁盤I/O的主要方法
  • 索引是在邏輯上和物理上都獨立於表的數據
  • Oracle會自動維護索引


創建索引的語法:

create index index_name
on table_name (column_list)
[tablespace tablespace_name];

語法說明:

index_name,索引名稱
table_name,表名
column_list,需要創建索引的列名,可基於多列創建索引
tablespace_name,爲索引指定表空間

使用: 在ItemFile表的itemCode列上創建索引,
create index item_index on ItemFile (itemCode);

Oracle在創建索引的步驟:

  • 獲取要索引的列,對其進行排序
  • 將ROWID連同每一行的索引值存儲起來


如對ItemFile表的itemCode列創建索引,Oracle基於itemCode列對錶進
行排序,然後按排序順序用itemCode及其ROWID值加載索引,
使用索引時,Oracle先通過已排序的itemCode值執行快速搜索,然後使用
相關聯的ROWID值來定位所要查找的itemCode值的行

索引在邏輯上和物理上都獨立於表中的數據,創建或刪除索引不會影響表
或其他的索引

一旦創建好索引,Oracle會自動維護,如添加新行、更新現有行或刪除行,
Oracle會自動更新索引

注意:爲表創建過的的索引會降低更新、刪除、添加的性能

刪除索引,語法:
drop index 索引名;

重建現有索引,語法:
alter index 索引名 rebuild;
該語句的性能要優於使用drop index和create index重建

17、索引的類型

索引類型圖:

    17.1)唯一索引:

  • 唯一索引確保在定義索引的列中沒有重複值
  • Oracle 自動在表的主鍵列上創建唯一索引
  • 用CREATE UNIQUE INDEX語句創建唯一索引

   
    使用: 爲ItemFile表的itemCode列創建唯一索引
    create unique index item_index on ItemFile (itemCode);

    17.2)組合索引:

  • 組合索引是在表的多個列上創建的索引
  • 索引中列的順序是任意的
  • 如果SQL語句的WHERE子句中引用了組合索引的所有列或大多數列,則可以提高檢索速度

   
    使用: 爲ItemFile表創建組合索引,當查詢該表的where子句同時包含
    pCategory, itemRate兩列或pCategory一列時,該索引將用於檢索數據,
    如只含itemRate列,該索引不會用於檢索
    create index comp_index on ItemFile(pCategory, itemRate);
   
    17.3)反向鍵索引

  • 一種特殊類型的索引,在索引基於含有序數的列時非常有用
  • 反向鍵索引反轉索引列鍵值的每個字節,在反向後的新數據上進行索引,因爲新數據在值範圍上的分佈會比原來的有序數更均勻
  • 通常建立在值是連續增長的列上,使數據均勻地分佈在整個索引上,例如,列中的值是由序列產生的
  • REVERSE關鍵字創建反向索引

   
    使用1: 爲ItemFile表創建反向索引rev_index
    create index rev_index on ItemFile (itemCode) reverse;

    提示:使用關鍵字NOREVERSE可將反向鍵索引重建爲標準索引

    如,alter index rev_index rebuild NOREVERSE;

    注意:標準索引不能重建爲反向索引

    17.4)位圖索引

    該索引用於不同值的數目比表的行數少的列,如某列的值重複
    了超過100次,可考慮位圖索引,如果表有100萬行,而某列
    有小於1000個不同的值,可考慮位圖索引
   
    位圖索引使用每個列值的位圖,而不使用ROWID, 位圖中的
    每個位對應一個可能的ROWID,如果設置了這個位,表示擁有
    此ROWID的行包含該列值
   
    create bitmap index語句創建位圖索引

    使用: 爲訂單明細表的訂單號(itemCode)一列創建位圖索引
    create bitmap index bit_index on orderDetail(itemCode);

    位圖索引的優勢:

  • 對於大批量即席查詢,可減少響應時間,在將所生成的位圖轉換爲ROWID前,通過在位圖上直接執行相應的布爾運算,可快速解析查詢條件中的AND和OR條件,如果查詢結果中的行很少,可很快的響應查詢,而不用對錶進行完全掃描
  • 相比其他索引技術,佔用空間明顯減少,使用標準索引對一個大型表進行完全索引極其浪費空間,因爲索引數據可能比表中的數據大幾倍,而位圖索引的大小通常僅是表中被索引數據的一小部分
  • 即使在配置很低的硬件上也能獲得顯著的性能
  • 位圖索引最適合於數據倉庫和決策支持系統


    注意:位圖索引不應用在頻繁發生insert、update、delete操作
    的表上,這些操作在性能方面代價很高,他們會引起位圖級的加
    鎖發生,而且要求動態重建所有可能值的位圖


    17.5)基於函數的索引

    有時需要在where子句的條件中使用表達式,如果在where子
    句的表達式或函數中已經包含了某個列,則不會使用該列上的
    索引,爲了此類操作,可以基於一個或多個列上的函數或表達
    式創建索引

    用於創建索引的函數可以使算術表達式、PL/SQL函數、程序包
    函數或SQL函數的表達式,該表達式有如下限制:

  • 不能包含聚合函數
  • 不能在LOB列、REF列或包含LOB或REF的對象類型上創建基於函數的索引

   
    問題: venName是vendorMaster表的一列,用於存儲供應商
    姓名,已爲該列創建了唯一索引以加快查詢速度,假設所有
    供應商的姓名都以混合大小寫的形式存儲(如:John Smith、
    Dave Jones、Tony Greig等),同時假設需要經常根據供應
    商的姓名來查詢表數據,由於採用了混合大小寫的形式存儲,
    可能很難給出姓名的正確大小寫形式,如果在where子句中
    使用upper()函數,則查詢要花費很長時間,因爲索引值是混
    合大小寫形式,由於索引中沒有適合於大寫姓名的條目,因此
    Oracle無法使用該列的標準索引
   
    解決: 基於upper函數創建索引,
    create index vn_index on vendorMaster (upper(venName));
   
    使用: 將列值轉換爲全大寫,然後與輸入值進行比較
    select * from venderMaster
    where upper(venName) = 'DAVE
JONES';
    注意:列值進行比較時會區分大小寫
   
    另一種用法: 基於表達式創建索引,
    create index exp_index on ItemFile (qtyHand * itemRate);
   
    注意:要創建基於函數或表達式的索引,必須具有QUERY REWRITE系統權限

18、索引組織表

索引組織表與普通表的不同之處在於,該表的數據存儲在於其關聯的索引
中,對錶數據進行的修改,如添加、更新、刪除,只會對索引進行更新

索引組織表與在一個或多個列上建立索引的普通表相似,但它無需爲表
和索引維護兩個獨立的存儲空間,數據庫只需維護一個索引,該索引包
含相應行的已編碼鍵值和與其關聯的列值

行的實際數據存儲在索引中,而不是將行的ROWID作爲索引條目的第二
個元素

可使用帶有organization index子句的create table命令來創建索引
組織表

使用: 創建索引組織表 indOrgTab
create table indOrgTab
(
    venCode number(4) primary key,
    venName varchar2(20)
)
organization index;
注意:primary key是創建索引組織表所必須的

索引組織表適合於通過主鍵來訪問數據,與唯一索引一樣,索引組織表
沒有重複的鍵值,因爲只有非鍵列的值與該鍵存儲在一起

操作索引組織表與操作普通表一樣,但是數據庫會通過操作相應的索引
來執行所有操作

常規表與索引組織表的區別 ,如下:

普通表                        索引組織表
=============================
ROWID 唯一地標識行    主鍵唯一地標識行
隱式的 ROWID 列         沒有隱式的 ROWID 列
基於 ROWID 的訪問      基於主鍵的訪問
順序掃描返回所有行       完全索引掃描返回所有行,並按主鍵順序排列
支持分區                     不支持分區

19、索引中的分區

與表分區類似,可以對索引進行分區,索引分區可存儲在不同的表空間
中,與分區有關的索引有3種類型:

  • 局部分區索引
  • 全局分區索引
  • 全局非分區索引


注意:對索引分區,取決於是否需要在索引結構上執行分區來保障分區後與分
區前有同樣的查詢響應時間


    19.1)局部分區索引

    局部分區索引是在分區表上創建的一種索引,該索引中,Oracle
    爲表的每個分區建立一個獨立的索引,所以這些索引對於分區來
    說是"局部"的,通過在create index語句中指定local屬性,可在
    分區上創建局部索引

    Oracle在於基礎表相同的列上對索引進行分區,創建相同數量
    的分區並指定相同的分區邊界

    添加、刪除或拆分基礎表的分區,Oracle會自動維護索引分區

    使用: 創建分區表,然後在分區表上創建局部索引
    --創建分區表
    create table orderMaster
    (
        orderNo number(4),
        venName varchar2(20)
    )
    partition by range(orderNo)
    (
        partition oe1 values less than (1000),
        partition oe2 values less than (2000),
        partition oe3 values less than (MAXVALUE)
    );
    --在分區表上創建局部索引
    create index my_index on orderMaster (orderNo) LOCAL;

    提示:可查詢"USER_SEGMENTS"字典視圖獲取索引信息
    select * from USER_SEGMENTS
    where segment_name = "my_index";
    觀察查詢結果可發現,該索引是作爲單獨的段爲所有分區創建的

    19.2)全局分區索引

    全局分區索引是指在分區表或非分區表上創建的索引,全局索引
    的鍵可以引用存儲在多個分區中的行,

    使用: 在之前創建的分區表orderMaster上創建全局索引,
    在有3個分區的表上創建兩個分區索引,
   
    create index glb_index on orderMaster (orderNo) GLOBAL
    partition by range (orderNo)
    (
        partition ip1 values less than (1500),
        partition ip2 values less than (MAXVALUE)
    );
    注意:不能在散列分區或子分區建立全局索引
   
    19.3)全局非分區索引

    在分區表上創建的全局普通索引,索引沒有被分區,索引結
    構不會被分割

20、獲取索引的信息

與索引有關的數據字典視圖有:

  • USER_INDEXES - 用戶創建的索引的信息
  • USER_IND_PARTITIONS - 用戶創建的分區索引的信息
  • USER_IND_COLUMNS - 與索引相關的表列的信息


使用:

select index_name, table_name, column_name
from USER_IND_COLUMNS
order by index_name, column_position;

21、總結

  • 同義詞是現有數據庫對象的別名
  • 序列用於生成唯一、連續的序號
  • 視圖是基於一個或多個表的虛擬表
  • 索引是與表相關的一個可選結構,用於提高 SQL 語句執行的性能
  • 索引類型有標準索引、唯一索引、反向鍵索引、位圖索引和基於函數的索引
  • 索引組織表基於主鍵訪問數據


Oracle 第3章 鎖、表分區

Oracle 第5章 使用PL/SQL

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章