1. 程式人生 > >oracle資料庫物件詳解(一)——表、檢視、同義詞、約束、索引

oracle資料庫物件詳解(一)——表、檢視、同義詞、約束、索引

oracle資料庫物件是資料庫的組成部分。資料庫物件包括表,檢視,同義詞,約束、索引,序列,遊標,觸發器,函式,變數,(控制塊,異常),儲存過程,包。對資料庫的操作可以基本歸結為對資料物件的操作,常常用CREATE命令進行建立,可以使用ALTER命令修改,用DROP執行刪除操作等。

一、表
表相當於轉載資料的容器,當一張表建立好之後如果需要修改這個容器的結構就要更改表結構了。
1.建立表:

          create table  student(
           id   number ;
           name varchar(10),
           age  number,
           time of enrollment  date,
           class_name varchar(20) ,
           class_id    
          );
2.刪除表:drop table students
3.新增表字段:alter table student add age number;
4.刪除表字段:alter table student drop column time of enrollment;
5.更改表名稱:alter table student rename to students;
6.更改表字段名稱:alter table student rename column  name to names;
7.更改表字段型別:alter table student time of enrollment modify  number;
8.更改表字段長度:alter table student name modify varchar(20);

二、檢視
    檢視是有一個或者多個表組成的虛擬表,這些組成檢視的表叫做該檢視的基表。檢視不佔用物理空間,其本身的定於語句還是儲存在資料字典裡。每次使用時都是重新執行SQL語句,一個檢視也可以從另外的一個檢視中產生。基於多個表的檢視不建議對檢視作增刪改查。
1.建立檢視:create(or replace) view <view_name> view_stu as <select 語句> select * from student;
2.刪除檢視:drop view <view_name>;
3.授予使用者建立檢視的許可權:grant create view  to cww;
4.通過檢視查詢資料:select * from view_name;
5.通過檢視插入資料:insert into view_stu values('cww','20','2000年10月1日');
6.通過檢視修改資料:update view_stu set age = 15 where id = 1;

檢視具有以下優點:
1.可以限制使用者只能通過檢視檢索資料。這樣就可以對終端使用者遮蔽建表時底層的基表。
2.可以將複雜的查詢儲存為檢視。可以對終端使用者遮蔽一定的複雜性。
3.限制某個檢視只能訪問基表中的部分列或者部分行的特定資料。這樣可以實現一定的安全性。
4.從多張基表中按一定的業務邏輯抽出使用者關心的部分,形成一張虛擬表。

三、同義詞
   同義詞是一種資料庫物件,它是為一個數據庫物件定義的別名,使用同義詞的主要目的是為了簡化SQL語句的書寫。Oracle 可以為表、檢視、序列、過程、函式、程式包等指定一個別名。同義詞有兩種型別:

私有同義詞:擁有 CREATE SYNONYM 許可權的使用者(包括非管理員使用者)即可建立私有同義詞,建立的私有同義詞只能由當前使用者使用。
公有同義詞:系統管理員可以建立公有同義詞,公有同義詞可以被所有使用者訪問。
1.建立同義詞;
create [or replace] [public] sysnonym [schema.]sysnonym_name for [schema.]object_name;
(1)建立同義詞時,如果同義詞存在則用新的同義詞替換舊的同義詞;
(2)一個使用者或該使用者下所有的資料庫物件的集合稱為schema(模式或方案),使用者名稱為schema名,一個數據庫物件的全稱為使用者名稱.物件名,即schema.object_name;同義詞作為一種資料庫物件,它的相關資訊被儲存在資料字典中。
2.與同義詞有關的資料字典有三個: user_synonyms 、all_synonyms 、dba_synonyms。
其中在資料字典user_synonyms 中記錄了當前使用者所擁有的同義詞。這個表的各列定義及其意義如下所示:
synonym_name 同義詞名稱
table_owner  所指向的物件屬主
table_name   所指向物件的名稱
db_link      資料庫連結
(注:db_link 列是指在建立同義詞synonym時,table_name 是通過dblink獲得的。)
3.查詢當前使用者建立了的同義詞,它們各代表哪個使用者的哪個物件:
SELECT synonym_name, table_owner, table_name FROM user_synonyms;
在資料字典all_synonyms 中記錄了當前使用者所能使用的所有同義詞,包括私有同義詞和公共同義詞。
在資料字典dba_synonyms 中記錄了資料庫中所有的同義詞,包括每個使用者建立的私有同義詞和DBA 建立的公共同義詞。
這個檢視只有DBA 能夠訪問,它的結構除了包含資料字典user synonyms的所有列外,還有一個列owner代表同義詞的建立者。
如果要在整個資料庫範圍內查詢某個同義詞的資訊,可以對資料字典dba_synonyms進行查詢。
例如:SELECT synonym_name, table_owner, table_name FROM dba_synonyms WHERE owner='SCOTT';
如果要查詢使用者scott的表dept具有哪些同義詞,可以執行下面的SELECT語句:
SELECT synonym_name, table_owner FROM dba_synonyms WHERE owner='SCOTT' AND table_name='EMP';
如果要查詢系統中所有的公共同義詞,可以執行下面的SELECT語句:
SELECT synonym_name, table_owner FROM dba_synonyms WHERE owner='PUBLIC';
注:table_owner和owner之前的區別:
table_owner是指同義詞所指向資料庫物件的屬主,一般就是指該物件的建立者,而owner是指同義詞的建立者 
如果要建立一個遠端的資料庫上的某張表的同義詞,需要先建立一個Database Link(資料庫連線)來擴充套件訪問,然後再使用如下語句建立資料庫
create synonym table_name for

[email protected]_Link;
當然,你可能需要在user1使用者中給當前使用者(user2)授權: grant select/delete/update on user2 ;
4.建立資料庫連結:
Create database link [資料庫鏈名] connect to [使用者名稱] identified by [密碼] using '[要連結的資料庫名]';
create database link db_link connect to tpss_bill identified by 123 using 'crmcxdb2';

四、約束
   約束是加在表上的一種強制性規則,是保證資料完整性的一種手段,當向表中插入或修改資料時,必須滿足約束說規定的條件。在設計表結構時,需要考慮在表上新增必要的約束。保證資料完整性的方法有三種:使用程式程式碼,觸發器,新增約束。其中新增約束是一種較為靈活的方式,而且效能也比較高,是保證資料完成性的最佳選擇,新增約束時最好是在設計表的時候,如果在插入資料後再新增約束,可能會因為資料不滿足約束而不能新增。
約束的型別有五種:not null (非空約束)、unique(唯一性約束、primary key(主鍵約束)、foreifn key(外來鍵約束)、check(檢查約束)
1.主鍵(primary key)是定位表中單個行的方式,可唯一確定表中的某一行,關係型資料庫要求所有表都應該有主鍵,不過Oracle沒有遵循此範例要求,Oracle中的表可以沒
有主鍵(這種情況不多見)。關於主鍵有幾個需要注意的點:
(1)鍵列必須必須具有唯一性,且不能為空,其實主鍵約束,相當於UNIQUE+NOT NULL
(2)一個表只允許有一個主鍵
(3)主鍵所在列必須具有索引(主鍵的唯一約束通過索引來實現),如果不存在,將會在索引新增的時候自動建立新增主鍵(約束的新增可在建表時建立,也可在建表後新增,一般推薦建表後新增,靈活度更高一些,建表時新增某些約束會有限制)
alter table student add constraint pk_stu_name primary key(name);
主鍵約束指定表中的一列或者幾列的組合的值在表中具有唯一性。但組合的列最多有16列。例如:將id和name作為主鍵約束
alter table student add constraint pk_stu_id_name primary key (id,name);
2.唯一性約束(unique)可以作用在一列或多列組合上,用來保證每一行的唯一性。唯一性約束可作用在單列或多列上,對於這些列或列組合,唯一性約束保證每一行的唯一性。
UNIQUE需要注意:
(1)對於UNIQUE約束來講,索引是必須的。如果不存在,就自動建立一個(UNIQUE的唯一性本質上是通過索引來保證的)
(2)UNIQUE允許null值,UNIQUE約束的列可存在多個null。這是因為,Unique唯一性通過btree索引來實現,而btree索引中不包含null。當然,這也造成了在where語句中用null值進行過濾會造成全表掃描。

新增唯一約束:
create table student add constaint pk_stu_id unique(id);
3.非空約束(not null)非空約束作用的列也叫強制列。強制鍵列中必須有值,當然建表時候若使用default關鍵字指定了預設值,則可不輸入。
alter table student modify name not null;
4.外來鍵約束(foreifn key)外關鍵字約束定義了表之間的關係。當一個表中的一個列或多個列的組合和其它表中的主關鍵字定義相同時,就可以將這些列或列的組合定義為外關鍵字,並設定它適合哪個表中哪些列相關聯。這樣,當在定義主關鍵字約束的表中更新列值,時其它表中有與之相關聯的外關鍵字約束的表中的外關鍵字列也將被相應地做相同的更新。外關鍵字約束的作用還體現在,當向含有外關鍵字的表插入資料時,如果與之相關聯的表的列中無與插入的外關鍵字列值相同的值時,系統會拒絕插入資料。與主關鍵字相同,不能使用一個定義為 TEXT 或IMAGE 資料型別的列建立外關鍵字。外關鍵字最多由16 個列組成。
定義外關鍵字約束的語法如下:
 constraint constraint_name
 foreign key (column_name1[,column_name2,…,column_name16])
 references ref_table [(ref_column1[,ref_column2,…, ref_column16])]
 [on delete {cascade | no action } ]
 [on update {cascade | no action } ]]
 [not for replication ]
 各引數說明如下:
 references 指定要建立關聯的表的資訊。
 ref_table 指定要建立關聯的表的名稱。
 ref_column 指定要建立關聯的表中的相關列的名稱。
 on delete {cascade | no action} 指定在刪除表中資料時,對關聯表所做的相關操作。在子表中有資料行與父表中的對應資料行相關聯的情況下,如果指定了值cascade,則在刪除父表資料行時會將子表中對應的資料行刪除;如果指定的是no action,則sql server 會產生一個錯誤,並將父表中的刪除操作回滾。no action 是預設值。
 not for replication 指定列的外關鍵字約束在把從其它表中複製的資料插入到表中時不發生作用。
 例如:建立一個課程表,與前面班級表關聯
 create table class(
  class_name varchar(20),
  class_id number ,
  teacher_name varchar(20),
  constraint pk_class_id primary key(class_id),
  foreign key pk_class_name_id (class_name,class_id)references student(class_name,class_id)
 ) on primary
5.檢查約束(check)可用來實施一些簡單的規則,比如列值必須在某個範圍內。檢查的規則必須是一個結果為true或false 的表示式,比alter table student add constraint stu_sex_ck check(sex in('男','女'));

五、索引
(1)索引是資料庫物件之一,用於加快資料的檢索,類似於書籍的索引。在資料庫中索引可以減少資料庫程式查詢結果時需要讀取的資料量,類似於在書籍中我們利用索引可以不用翻閱整本書即可找到想要的資訊;
(2)索引是建立在表上的可選物件;索引的關鍵在於通過一組排序後的索引鍵來取代預設的全表掃描檢索方式,從而提高檢索效率;
(3)索引在邏輯上和物理上都與相關的表和資料無關,當建立或者刪除一個索引時,不會影響基本的表;
(4)索引一旦建立,在表上進行DML操作時(例如在執行插入、修改或者刪除相關操作時),oracle會自動管理索引,索引刪除,不會對錶產生影響;
(5)索引對使用者是透明的,無論表上是否有索引,sql語句的用法不變
(6)oracle建立主鍵時會自動在該列上建立索引
1.建立最佳的索引
 create  index index_name on table_name(column_name)
 tablespace tablespace_name
 pctfree 5
 initrans 2
 maxtrans 255
 storage(
 minextents 1
 maxextents 16382
 pctincrease 0);
2.建立基於函式的索引,常常與upper、lower、to_char(date)等函式一起用,例如:
 create index idx_name on student  (to_char(birthday)) tablespace tablespace_name;
3.建立點陣圖索引,對於基數小且基數相對穩定的列建立索引時應該先考慮點陣圖索引,例如:
 create bitmap index  idx_bit_classno on class(classno) tablespace tablespace_name;
4.建立唯一索引
 create unique index idx_uni_stuid student (studentid) tablespace tablespace_name;
5.建立與約束相關的索引
 alter table class
 add constraint pk_primary_key_classid primary key (classid) using index tablespace tablespace_name;
6.使用不等於操作符(<>, !=)
下面這種情況,即使在列dept_id有一個索引,查詢語句仍然執行一次全表掃描
select * from dept where staff_num <> 1000;
通過把用 or 語法替代不等號進行查詢,就可以使用索引,以避免全表掃描:上面的語句改成下面這樣的,就可以使用索引了。
7.使用 is null 或 is not null
使用 is null 或is nuo null也會限制索引的使用,因為資料庫並沒有定義null值。如果被索引的列中有很多null,就不會使用這個索引(除非索引是一個
點陣圖索引)。在sql語句中使用null會造成很多麻煩。解決這個問題的辦法就是:建表時把需要索引的
列定義為非空(not null)
8.使用函式
如果沒有使用基於函式的索引,那麼where子句中對存在索引的列使用函式時,會使優化器忽略掉這些索引。下面的查詢就不會使用索引:
select * from staff where trunc(birthdate) = '01-MAY-82';
但是把函式應用在條件上,索引是可以生效的,把上面的語句改成下面的語句,就可以通過索引進行查詢。
select * from staff where birthdate < (to_date('01-MAY-82') + 0.9999);
9.比較不匹配的資料型別
比較不匹配的資料型別也是難於發現的效能問題之一。下面的例子中,dept_id是一個varchar2型的欄位,在這個欄位上有索引,但是下面的語句會執行全表掃描。
select * from dept where dept_id = 900198;
這是因為oracle會自動把where子句轉換成to_number(dept_id)=900198,這樣就限制了索引的使用。把SQL語句改為如下形式就可以使用索引
select * from dept where dept_id = '900198';
10.使用like子句
使用like子句查詢時,資料需要把所有的記錄都遍歷來進行判斷,索引不能發揮作用,這種情況也要儘量避免。
like 的字串中第一個字元如果是‘%’則用不到索引
column1 like ‘aaa%’ 是可以的,column1 like ‘%aaa%’用不到。
11.使用in
儘管in寫法要比exists簡單一些,exists一般來說效能要比in要高的多,
當in的集合比較小的時候,或者用exists無法用到選擇性高的索引的時候,用in要好,否則就要用exists
例:select count(*) from person_info where xb in (select xb_id from dic_sex);
select count(*) from n_acntbasic a where shbxdjm =:a and exists(select 1 from person_info where pid=a.pid and …);
假定test表的dt欄位是date型別的並且對dt建了索引。
12.如果能不用到排序,則儘量避免排序
用到排序的情況有集合操作。Union ,minus ,intersect等,注:union all 是不排序的。
Order by、Group by、Distinct、In 有時候也會用到排序確實要排序的時候也儘量要排序小資料量,儘量讓排序在記憶體中執行。