- OCA/OCP認(rèn)證考試指南全冊(第3版) Oracle Database 12c(1Z0-061,1Z0-062,1Z0-063) (計算機與信息)
- (美)John Watson等
- 1302字
- 2021-03-26 13:10:19
5.9 同義詞
同義詞是對象的備選名稱。如果對象存在同義詞,那么任何SQL語句都能通過實際名稱或通過同義詞來訪問該對象。同義詞看上去似乎沒有什么作用,然而實際情況并非如此。使用同義詞意味著應(yīng)用程序可以對任何用戶起作用,而不考慮哪個模式擁有視圖和表,甚至不考慮表駐留在哪個數(shù)據(jù)庫中。分析如下語句:
select * from hr.employees@prod;
發(fā)出該語句的用戶必須知道員工表由數(shù)據(jù)庫鏈接PROD標(biāo)識的數(shù)據(jù)庫中的HR模式擁有(不需要關(guān)心數(shù)據(jù)庫連接的細(xì)節(jié),它們是一種訪問不是目前所登錄數(shù)據(jù)庫的其他數(shù)據(jù)庫中對象的方式)。如果用如下語句創(chuàng)建公有同義詞:
create public synonym emp for hr.employees@prod;
那么所有用戶都需要輸入如下語句:
select * from emp;
這個語句既提供了數(shù)據(jù)無關(guān)性,又提供了位置透明性。用戶必須有訪問底層對象的權(quán)限,才能成功使用基于同義詞的引用。只要調(diào)整同義詞,就可以在不修改代碼的情況下重命名或重定位表和視圖。
與SELECT語句一樣,DML語句可以像訪問同義詞引用的對象一樣訪問同義詞。
私有同義詞是模式對象。它們要么必須在自己的模式中,要么必須用模式名限定。公有同義詞的存在與模式無關(guān)。任何具有查看權(quán)限的用戶都可以引用公有同義詞,不需要用模式名限定。私有同義詞必須在模式中有唯一的名稱,而公有同義詞可以與模式對象同名。當(dāng)執(zhí)行訪問不帶模式限定符的對象的語句時,Oracle會先在局部模式中查找對象,只有在局部模式中找不到時才會在公有模式中查找。因此在前面的示例中,如果用戶碰巧擁有名為EMP的表,它看到的就是這個表——而不是公有同義詞指向的名為EMP的表。
創(chuàng)建同義詞的語法如下:
CREATE [PUBLIC] SYNONYM synonym FOR object ;
需要為用戶授予創(chuàng)建私有同義詞的權(quán)限,并且進(jìn)一步授予創(chuàng)建公有同義詞的權(quán)限。通常,只有數(shù)據(jù)庫管理員能夠創(chuàng)建(或刪除)公有同義詞。這是因為是否存在公有同義詞會影響每個用戶。
考點:
“公有同義詞”中的“公有”意味著它不是模式對象,因此不能用模式名做前綴。這并不意味著每個人都具有對公有同義詞的訪問權(quán)限。
刪除同義詞的語法如下:
DROP [PUBLIC] SYNONYM synonym ;
如果同義詞引用的對象(表或視圖)被刪除,同義詞仍然存在。這時試圖使用這樣的同義詞會返回一個錯誤。在這一方面,同義詞的行為方式與視圖相同。如果重新創(chuàng)建對象,那么在使用同義詞前必須重新編譯。與視圖一樣,在下次訪問同義詞時自動重新編譯,也可以使用如下語句顯式地完成編譯:
ALTER SYNONYM synonym COMPILE;
練習(xí)5-8 創(chuàng)建和使用同義詞
在本練習(xí)中,將用HR模式中的對象創(chuàng)建和使用私有同義詞。可以使用SQL*Plus或SQL Developer。
(1) 作為用戶HR連接到數(shù)據(jù)庫。
(2) 為練習(xí)5-7中創(chuàng)建的三個視圖創(chuàng)建同義詞:
create synonym emp_s for emp_anon_v; create synonym dept_s for dept_anon_v; create synonym dsum_s for dep_sum_v;
(3) 確認(rèn)同義詞等同于底層對象:
describe emp_s; describe emp_anon_v;
(4) 通過對同義詞而不是視圖運行練習(xí)5-7中的語句,來確認(rèn)同義詞有效(甚至到產(chǎn)生相同錯誤的程度):
select * from dsum_s; insert into dept_s values (99, 'Temp Dept',1800 ); insert into emp_s values (sysdate, 'AC_MGR',10000,0,99); update emp_s set salary=salary*1.1; rollback; select max(salaries / staff) from dsum_s;
(5) 刪除兩個視圖:
drop view emp_anon_v; drop view dept_anon_v;
(6) 查詢基于已刪除視圖的復(fù)雜視圖:
select * from dep_sum_v;
可以注意到查詢失敗。
(7) 嘗試重新編譯被破壞的視圖:
alter view dep_sum_v compile;
此次編譯嘗試也會失敗。
(8) 刪除DEP_SUM_V視圖:
drop view dep_sum_v;
(9) 查詢已刪除視圖的同義詞:
select * from emp_s;
該查詢會失敗。
(10) 重新編譯被破壞的同義詞:
alter synonym emp_s compile;
注意,雖然這樣做不會拋出錯誤,而是從第(9)步開始重新運行查詢。該同義詞無疑仍然處于破壞狀態(tài)。
(11) 通過刪除同義詞進(jìn)行整理:
drop synonym emp_s; drop synonym dept_s; drop synonym dsum_s;
5.10 序列
序列是生成唯一整數(shù)值的結(jié)構(gòu)。由于只有一個會話能夠讀取下一個值,因此強制該值遞增。這是序列化的要點,因此生成的每個值都將是唯一的。
序列是用來生成主鍵的寶貴工具。很多應(yīng)用程序都需要自動生成主鍵值。日常業(yè)務(wù)數(shù)據(jù)處理的一個示例是客戶編號或訂單編號:業(yè)務(wù)分析師會指出,每個訂單必須有唯一的編號,編號應(yīng)連續(xù)地遞增。其他應(yīng)用程序可能沒有這樣的行規(guī)要求,但是仍然需要序列來實施關(guān)系完整性。以電話賬單系統(tǒng)為例:在行規(guī)中的唯一標(biāo)識符是電話號碼(字符串),一次電話呼叫的標(biāo)識符將是主叫電話號碼和通話開始時間(時間戳)。這些數(shù)據(jù)類型太復(fù)雜,對于通過電話交換系統(tǒng)的大流量的主鍵來說,沒必要采用這么復(fù)雜的類型。盡管使用這些數(shù)據(jù)類型也能夠記錄信息,但是使用簡單的數(shù)值列來定義主鍵和外鍵要快得多。這些列中的值可以作為序列的基礎(chǔ)。
序列機制與表、行鎖機制及提交或回滾過程無關(guān)。這意味著序列每分鐘能發(fā)出數(shù)千個唯一值,這比任何涉及從表中選擇列、更新列并提交修改的方法快得多。
圖5-12顯示了兩個從一個序列SEQ1中選擇值的會話。

圖5-12 兩個會話并發(fā)使用序列
注意,圖5-12中SEQ1.NEXTVAL的每個選擇項生成一個唯一數(shù)值。這些數(shù)值按選擇的時間順序連續(xù)發(fā)出,數(shù)值會全局地遞增,而不是僅在一個會話中遞增。
5.10.1 創(chuàng)建序列
創(chuàng)建序列的完整語法如下:
CREATE SEQUENCE [schema.]sequencename [INCREMENT BY number] [START WITH number] [MAXVALUE number | NOMAXVALUE] [MINVALUE number | NOMINVALUE] [CYCLE | NOCYCLE] [CACHE number | NOCACHE] [ORDER | NOORDER] ;
可以看出,序列的創(chuàng)建可以非常簡單。例如,圖5-12中使用的序列是用如下語句創(chuàng)建的:
create sequence seq1;
各選項如表5-2所示。
表5-2 創(chuàng)建序列的選項

對INCREMENT BY、START WITH,以及MAXVALUE或MINVALUE的適當(dāng)設(shè)置取決于業(yè)務(wù)分析師。
CYCLE很少使用,因為它使序列發(fā)出重復(fù)值。如果用序列來生成主鍵值,那么只有當(dāng)數(shù)據(jù)庫中存在刪除原有行比序列重新發(fā)出數(shù)值快得多的例程時,CYCLE才有意義。
緩存序列值對于性能至關(guān)重要。從序列中選擇是應(yīng)用程序代碼中串行化的要點:一次只能有一個會話產(chǎn)生這個序列值。這種機制非常有效率:相比于先鎖住行,再更新行,然后用COMMIT解鎖行,使用這種機制會快很多。但是即便如此,從序列中選擇仍然會造成會話之間的資源爭用。CACHE關(guān)鍵字通知Oracle在緩存中預(yù)先生成序號。這意味著如果需要根據(jù)要求生成序號,則可以更快速地發(fā)出這些序號。
提示:
要緩存的默認(rèn)序號個數(shù)是20。經(jīng)驗表明這個數(shù)量并不夠。如果應(yīng)用程序每秒鐘從序列中選擇10次,那么要將緩存值設(shè)置為50 000。不要羞于承認(rèn)這一點。
5.10.2 使用序列
為使用序列,會話可以用強制序列遞增的偽列NEXTVAL選擇下一個值,也可以用偽列CURRVAL選擇發(fā)送給該會話的上一個(或“當(dāng)前”)值。NEXTVAL將是全局唯一值:選擇它的每個會話的每個SELECT會得到不同的、遞增的值。直到再次選擇NEXTVAL前,CURRVAL將是某個會話的常量。無法找出序列發(fā)出的上一個值是什么值:可以使用NEXTVAL遞增來獲得下一個值,也可以使用CURRVAL來重新調(diào)用發(fā)送給會話的上一個值,但是無法找到發(fā)出的上一個值。
考點:
序列的CURRVAL是發(fā)送給當(dāng)前會話的上一個值,不一定是發(fā)出的上一個值。直到選擇了NEXTVAL后才能選擇CURRVAL。
序列的一種典型用途是用于主鍵值。本例使用序列CUST_SEQ生成唯一客戶號,使用序列ORDER_SEQ生成唯一訂單號,使用LINE_ SEQ生成該訂單的行條目的唯一行號。先創(chuàng)建序列,這是只執(zhí)行一次的操作:
create sequence order_seq start with 10; create sequence line_seq start with 10;
然后插入訂單,每個訂單所在的行作為單個事務(wù):
insert into orders (order_id, order_date, customer_id) values (order_seq.nextval, sysdate, '1000' ); insert into order_items (order_id, order_item_id, product_id) values (order_seq.currval, line_seq.nextval, 'A111'); insert into order_items (order_id, order_item_id, product_id) values (order_seq.currval, line_seq.nextval, 'B111'); commit;
第一條INSERT語句生成了一個訂單,它具有從客戶編號1000的序列ORDER_SEQ得到的唯一訂單號。第二條和第三條語句插入訂單的兩行:使用前面從ORDER_SEQ發(fā)出的訂單號作為將這兩行連接到訂單的外鍵,并使用LINE_SEQ中的下一個值生成每一行的唯一標(biāo)識符。最后,提交事務(wù)。
序列沒有綁定到任何一個表。在前面的示例中,從技術(shù)上來說沒有理由不使用一個序列來生成訂單和行的主鍵值。
對于持久遞增序列來說,COMMIT并不是必需的語句:序列遞增是持久的操作,一旦發(fā)生就對其余部分可見,并且不能回滾。序列更新的發(fā)生與事務(wù)管理系統(tǒng)無關(guān)。由于這個原因,序列中總是存在間隔。如果數(shù)據(jù)庫重啟并且使用CACHE子句,那么間隔會比較大。當(dāng)數(shù)據(jù)庫關(guān)閉時,所有已生成并緩存但還沒有發(fā)出的數(shù)值會丟失。下次重啟時,序列的當(dāng)前值是上次生成的數(shù)值,而不是上次發(fā)出的數(shù)值。因此,如果使用默認(rèn)的CACHE 20,那么每次關(guān)閉/啟動會丟失20個數(shù)值。
如果業(yè)務(wù)分析師指出序列中不能有間隔,那么必須使用另一種生成唯一數(shù)值的方式。對于前面生成訂單的示例,當(dāng)前訂單號可以存儲在該表中,并將它初始化為10:
create table current_on(order_number number); insert into current_on values(10); commit;
然后創(chuàng)建訂單的代碼將變成:
update current_on set order_number=order_number + 1; insert into orders (order_number, order_date, customer_number) values ((select order_number from current_on), sysdate, '1000'); commit;
作為一種生成唯一訂單號的方式,當(dāng)然可以采用這樣的代碼,因為訂單號的遞增在插入訂單的事務(wù)中,所以必要時可以使用插入回滾它:除非故意刪除訂單,否則訂單號中不會有間隔。但是,這樣做的效率遠(yuǎn)不如使用序列,而且眾所周知的是,像這樣的代碼會引起致命的爭用問題。如果有很多會話試圖鎖定并遞增包含當(dāng)前編號的一行,那么當(dāng)隊列在等待輪到自己時,整個應(yīng)用程序就會掛起。
創(chuàng)建和使用序列后,可以對序列進(jìn)行修改。語法如下:
ALTER SEQUENCE sequencename [INCREMENT BY number] [START WITH number] [MAXVALUE number | NOMAXVALUE] [MINVALUE number | NOMINVALUE] [CYCLE | NOCYCLE] [CACHE number | NOCACHE] [ORDER | NOORDER] ;
ALTER命令與CREATE命令基本相同,只有一點區(qū)別:ALTER命令不能設(shè)置起始值。如果要重啟該序列,唯一的方法是刪除并重新創(chuàng)建它。為調(diào)整默認(rèn)緩存值以改進(jìn)前面的訂單條目示例的性能,可以使用如下代碼:
alter sequence order_seq cache 1000;
然而,如果希望將該序列重置為它的起始值,唯一的方法是先刪除它:
drop sequence order_seq;
然后創(chuàng)建該序列。
練習(xí)5-9 創(chuàng)建和使用序列
在本練習(xí)中,創(chuàng)建一些序列并使用它們。需要兩個并發(fā)會話,可以使用SQL Developer或SQL*Plus。
(1) 在單獨的會話中作為HR登錄到數(shù)據(jù)庫兩次。將其中一次登錄看成A會話,另一次看成B會話。
(2) 在A會話中,創(chuàng)建如下所示的序列:
create sequence seq1 start with 10 nocache maxvalue 15 cycle;
NOCACHE的使用會降低性能。如果指定了MAXVALUE,那么有必要用CYCLE防止到達(dá)MAXVALUE時出錯。
(3) 在適當(dāng)?shù)臅捴邪凑_的順序執(zhí)行表5-3中的命令,以觀察NEXTVAL和CURRVAL的使用以及序列的循環(huán)。
表5-3 執(zhí)行命令

(4) 創(chuàng)建一個帶主鍵的表:
create table seqtest(c1 number, c2 varchar2(10)); alter table seqtest add constraint seqtest_pk primary key (c1);
(5) 創(chuàng)建一個序列來生成主鍵值:
create sequence seqtest_pk_s;
(6) 在A會話中,向新表中插入一行并提交:
insert into seqtest values (seqtest_pk_s.nextval, 'first'); commit;
(7) 在B會話中,向新表中插入一行且不提交:
insert into seqtest values (seqtest_pk_s.nextval, 'second');
(8) 在A會話中,插入第三行并提交:
insert into seqtest values (seqtest_pk_s.nextval, 'third'); commit;
(9) 在B會話中,回滾第二個插入:
rollback;
(10) 在B會話中,查看表的內(nèi)容:
select * from seqtest;
這就演示了在事務(wù)控制機制外部遞增序列并立即發(fā)布下一個值。
(11) 整理表和序列:
drop table seqtest; drop sequence seqtest_pk_s; drop sequence seq1;
(12) 使用SQL Developer或SQL*Plus連接到HR模式,并創(chuàng)建三個將在后續(xù)練習(xí)中使用的序列。
create sequence prod_seq; create sequence cust_seq; create sequence order_seq;
5.11 本章知識點回顧
分類主要的數(shù)據(jù)庫對象
● 有些對象包含數(shù)據(jù),主要是表和索引。
● 編程對象(如存儲過程和函數(shù))是可執(zhí)行的代碼。
● 視圖和同義詞是能夠訪問其他對象的對象。
● 表是保存使用列定義的行的二維結(jié)構(gòu)。
● 表在模式中。模式名和表名形成唯一標(biāo)識符。
列舉列可用的數(shù)據(jù)類型
● 最常見的字符數(shù)據(jù)類型有VARCHAR2、NUMBER和DATE。
● 還有其他許多數(shù)據(jù)類型。
創(chuàng)建簡單的表
● 可以從頭開始創(chuàng)建表或者使用子查詢創(chuàng)建表。
● 創(chuàng)建之后,可以添加、刪除或者修改列定義。
● 表定義可以包含列的默認(rèn)值。
創(chuàng)建和使用臨時表
● 只有插入行的會話才能訪問臨時表中的行。
● 針對臨時表的DML不生成重做數(shù)據(jù)。
● 臨時表只存在于會話的PGA或臨時段中。
● 臨時表只在會話期間或事務(wù)期間(具體取決于創(chuàng)建方式)保存行。
索引
● 要實施唯一約束和主鍵約束,就必須使用索引。
● B*樹索引不包括NULL,但位圖索引包含NULL。
● B*樹索引可為唯一索引,也可為非唯一索引,這些將決定是否接受重復(fù)鍵值。
● B*樹索引適用于基數(shù)大的列,而位圖索引適用于基數(shù)小的列。
● 位圖索引可以采用復(fù)合形式,可以基于函數(shù),也可以降序排列。B*樹索引可以是唯一的、壓縮的和反向鍵。
約束
● 可以在創(chuàng)建表時定義約束,也可以在隨后添加。
● 可以與列一起定義約束,或者在列之后的表級別定義約束。
● 表級別約束可能比內(nèi)聯(lián)定義的約束更復(fù)雜。
● 表只能有一個主鍵,但可以有許多唯一鍵。
● 主鍵的功能等同于UNIQUE加上NOT NULL。
● 唯一約束不阻止多個空值的插入。
● 外鍵約束定義表之間的關(guān)系。
視圖
● 簡單視圖有一個明細(xì)表(或基表),既不使用函數(shù)也不使用聚合。
● 復(fù)雜視圖可以基于任何SELECT語句,不管多么復(fù)雜。
● 視圖是模式對象。要在另一個模式中使用視圖,必須用模式名限定視圖名。
● 可以像查詢表一樣查詢視圖。
● 可以將視圖聯(lián)接到其他視圖或者聯(lián)接到表,它們可以被聚合,在有些情況下它們可以接受DML語句。
● 視圖僅作為數(shù)據(jù)字典結(jié)構(gòu)存在。每當(dāng)查詢視圖時,必須運行底層SELECT語句。
同義詞
● 同義詞是視圖或表的另一個名稱。
● 私有同義詞是模式對象;公有同義詞存在于用戶模式之外,不需要指定模式名作為限定符就可以使用。
● 同義詞與視圖和表共享相同的名稱空間,因此可以與它們互換使用。
序列
● 序列生成唯一值——除非指定了MAXVALUE或MINVALUE和CYCLE。
● 遞增序列不需要提交,不能回滾。
● 任何會話都能通過讀取它的下一個值來遞增序列。可以獲得上次發(fā)送給會話的值,但不能獲得上次發(fā)出的值。
- 2019年對外漢語教師資格考試(中級)《現(xiàn)代漢語》筆記和典型題(含歷年真題)詳解【視頻講解】
- 2019年水利部黃河水利委員會招聘考試《公共基礎(chǔ)知識》過關(guān)必做習(xí)題集(含歷年真題)
- 企業(yè)人力資源管理師職業(yè)資格考試專用輔導(dǎo)教材(二級):教材精解(圖解版)+題庫解析+歷年真題+押題預(yù)測
- 新駕考:學(xué)車考證一本通(2022版)
- 2019年全國導(dǎo)游人員資格考試輔導(dǎo)教材-西藏導(dǎo)游基礎(chǔ)知識
- 《物業(yè)管理基本制度與政策》命題點全面解讀
- VR與3D教育藍(lán)皮書
- OCP認(rèn)證考試指南(1ZO-063) Oracle Database 12c高級管理
- 準(zhǔn)職業(yè)人導(dǎo)向訓(xùn)練教程(二):職業(yè)能力與職業(yè)素質(zhì)提升
- 魅力絲路:探尋歐亞名校之旅
- 智慧教育實踐
- 2019年房地產(chǎn)經(jīng)紀(jì)人協(xié)理《房地產(chǎn)經(jīng)紀(jì)綜合能力》過關(guān)必做500題
- 企業(yè)法律顧問《綜合法律知識》歷年真題與模擬試題詳解
- 準(zhǔn)職業(yè)人導(dǎo)向訓(xùn)練教程(一):基礎(chǔ)能力認(rèn)知與培養(yǎng)
- 2019年下半年全國統(tǒng)考教師資格考試《英語學(xué)科知識與教學(xué)能力》(高級中學(xué))題庫【歷年真題+章節(jié)題庫+模擬試題】