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 語句執行的性能
- 索引類型有標準索引、唯一索引、反向鍵索引、位圖索引和基於函數的索引
- 索引組織表基於主鍵訪問數據