1. 程式人生 > >Oracle之建立表、序列、索引和檢視

Oracle之建立表、序列、索引和檢視

本文主要包括:

   · 建立、修改和刪除表

   · 如何建立並使用序列:序列可以生成一系列數字

   · 如何建立並使用索引:索引可以提高查詢的效能

   · 如何建立並使用檢視:檢視是預定義的查詢

   · 閃回資料歸檔將一段時間內對錶所做的改變儲存

一、 表

1. 建立表

可以使用 CREATE TABLE 語句建立表,CREATE TABLE 語句的簡化語法如下:

CREATE [GLOBAL TEMPORARY] TABLE table_name 
(

   column_name type [CONSTRAINT constraint_def DEFAULT default_exp]

   [, column_name type [CONSTRAINT constraint_def DEFAULT default_exp] ... ]

)

[ON COMMIT [DELETE | PRESERVE] ROWS]

[TABLESPACE tab_space];

注:ON COMMIT 控制臨時表中行的有效期,DELETE 說明這些行在事務結束時被刪除

       PRESERVE 說明這些行被保留到使用者會話結束時才被刪除

       如果對臨時表沒有指定 ON COMMIT 選項,那麼預設值是 DELETE

2. 建立表的同時建立約束

2.1 五種具體的約束:
   ·

主鍵    PRIMARY KEY
                這個欄位是非空的 並且是唯一的
                一個表的主鍵只能有一個 
   · 唯一    UNIQUE 

                這個欄位的值 是不能重複的     

   · 非空    NOT NULL
                這個欄位的值  不能是NULL值 
   · 檢查    CHECK
                這個欄位的值 必須符合檢查條件     
   · 外來鍵    REFERENCES        
                on delete cascade  
                on delete set  null


2.2 列級別約束:在定義表的一列時,直接在這一列的後面加約束限制

CRAETE TABLE orders

(

   id INTEGER CONSTRAINT orders_pk PRIMARY KEY

);

2.3  表級約束:在定義完所有的列之後,再選擇某些列加約束

CREATE TABLE orders2 

(

   id INTEGER,

   CONSTRAINT orders2_pk PRIMARY KEY(id)

);

2.4 外來鍵約束

外來鍵約束涉及到兩張表   一張叫父表  (主表), 另一張叫子表   (從表)    
定義了外來鍵的表就是子表,如果兩張表建立了主外來鍵關係,則外來鍵欄位的值
要麼引用自父表,要麼是空值

CREATE TABLE products

(
   product_id INTEGER CONSTRAINT products_pk PRIMARY KEY
   product_type_id INTEGER CONSTRAINT products_fk_product_types
  REFERENCES product_types(product_type_id)

);

2.5 建立臨時表

CREATE GLOBAL TEMPORARY TABLE order_satatus_temp

(

   id INTEGER,

   status VARCHAR2(10),

   last_modified DATE DEFAULT SYSDATE

)

ON COMMIT PRESERVE ROWS;     --  保留到回話結束時才會被刪除

3. 獲得有關表的資訊

   · user_tables     系統裡所有表的資訊,需要 DBA 許可權才能查詢

   · all_tables        當前使用者下能夠查詢的所有表的資訊

   · dba_tables      當前使用者下的所有表的資訊

4. 獲取表中列的資訊

從 user_tab_columns 檢視中可以獲得有關表中各列的資訊

all_tab_columns

5. 修改表

ALTER TABLE 語句可以用於對錶進行修改,ALTER TABLE 語句可以執行以下任務:

   · 新增、修改或刪除列

   · 新增或刪除約束

   · 啟用或禁用約束

5.1 新增列

範例:向 order_status2 表中新增名為 modified_by 的列,資料型別是 INTEGER

ALTER TABLE order_status2 ADD modified_by INTEGER;

範例:向 order_status2 表中新增名為 initially_created 列

ALTER TABLE order_status2 ADD initially_created DATE DEFAULT SYSDATE NOT NULL;

5.2 新增虛擬列

Oracle 11g 引入了虛擬列,虛擬列只引用表中已有的其他列

範例:向 salary_grades 表中新增名為 average_salary 的虛擬列

ALTER TABLE salary_grades ADD (average_salary AS ((low_salary + high_salary)/2));

5.3 修改列

下面列出了使用 ALTER TABLE 語句可以對列進行修改的內容:

   · 修改列的長度(條件是該列的資料型別的長度可以修改,如 CHAR 或 VARCHAR2) 

   · 修改數值列的精度

   · 修改列的資料型別

   · 修改列的預設值

5.4 修改列的長度

範例:將 order_status2.status 列的最大長度增加為 15 個字元

ALTER TABLE order_status2 MODIFY status VARCHAR2(15);

5.5 修改數值的精度

範例:將 order_status2.id 列的精度修改為 5

ALTER TABLE order_status2 MODIFY id NUMBER(5);

5.6 修改列的資料型別

範例:將 order_status2.status 列的資料型別修改為 CHAR

ALTER TABLE order_status2 MODIFY status CHAR(15);

注:如果表中沒有任何行或該列只包含空值,就可以將列修改為任何一種資料型別

否則,就只能將列的資料型別修改為一種相容的資料型別

5.7 修改列的預設值

範例:將 last_modified 列的預設值修改為 SYSDATE - 1 

ALTER TABLE order_status2 MODIFY last_modified DEFAULT SYSDATE-1;

5.8 刪除列

ALTER TABLE order_status2 DROP COLUMN initially_created;

5.9 新增約束

   · 上述 5 種約束

   · CHECK OPTION   通過檢視對錶行所做的改變必須先經過檢查

   · READ ONLY        指定檢視是隻讀的

5.10 新增 CHECK 約束

範例:向 order_status2 表新增 CHECK 約束

ALTER TABLE order_status2 ADD CONSTRAINT order_status2_status_ck

CHECK (status IN ('PLACED','PENDING','SHIPPED'));

注:CHECK 約束確保 status 列的值始終設定為 PLACED、PENDING 或 SHIPPED

在 CHECK 約束中,可以使用其他比較運算子

範例:新增 CHECK 約束強制 id 的值大於 0 

ALTER TABLE order_status2 ADD CONSTRAINT order_status2_id_ck CHECK(id > 0);

5.11 新增 NOT NULL 約束

範例:向 order_status2 表中的 status 列新增 NOT NULL 約束,注意要使用 MODIFY 來新增此約束

ALTER TABLE order_status2 MODIFY status CONSTRAINT order_status2_status_nn NOT NULL; 

5.12 新增 FOREIGN KEY 約束

範例:先刪除 order_status2 表的 modified_by 列,接著新增 FOREIGN KEY 約束

ALTER TABLE order_status2 DROP COLUMN modified_by;

          新增一個引用了   employees 表的 employee_id 列的 FOREIGN KEY 約束

ALTER TABLE order_status2 ADD CONSTRAINT order_status2_modified_by_fk

modified_by REFERENCES employees(employee_id);

使用帶有 ON DELETE CASCADE子句的 FOREGIN KEY 約束,可以指定在父表中刪除一行時,

子表中匹配的所有行也被將被刪除

範例:先刪除 modified_by 列,然後使用 ON DELETE CASCADE 子句的 ALTER TABLE 語句

ALTER TABLE order_status2 DROP COLUMN modified_by;

ALTER TABLE order_status2 ADD CONSTRAINT order_status2_modified_by_fk

modified_by REFERENCES employees(employee_id) ON DELETE CASCADE;

注:當從 employees 表中刪除一行時,order_status2 表中所匹配的行也都將被刪除

使用帶有 ON DELETE SET NULL 子句的 FOREIGN KEY 約束,可以指定在父表中刪除一行時,

子表中匹配行的外來鍵都將被設定為空值

ALTER TABLE order_status2 DROP COLUMN modified_by;

ALTER TABLE order_status2 ADD CONSTRAINT order_status2_modified_by_fk

modified_by REFERENCES employees(employee_id) ON DELETE SET NULL;

注:當從 employees 表中刪除一行時,order_status2 表中所有匹配的 modified_by 列都將被設定為空值

5.13 新增 UNIQUE 約束

ADD

範例:向 status 列新增 UNIQUE 約束

ALTER TABLE order_status2 ADD CONSTRAINT order_status2_status_uq UNIQUE(status);

5.14 刪除約束

DROP

ALTER TABLE order_status2 DROP CONSTRAINT order_status2_status_uq;

5.15 禁用約束

DISABLE

範例:向 order_status2 新新增一個約束,並禁用這個約束

ALTER TABLE order_status2 ADD CONSTRAINT order_status2_status_uq UNIQUE (status) DISABLE;

範例:禁用已存在的 order_status2_status_nn 約束

ALTER TABLE order_status2 DISABLE CONSTRAINT order_status_status2_nn;

注:在禁用作為外來鍵約束的一部分的主鍵約束或唯一性約束時,必須使用 CASCADE;

5.16 啟用約束

ENABLE

範例:啟用 order_sales2_status_uq 約束

ALTER TABLE order_status2 ENABLE CONSTRAINT order_status2_status_uq;

注:要啟用約束,表中所有的行必須能滿足約束條件

範例:通過 ENABLE NOVALIDATE,可以選擇只對新資料應用某個約束

ALTER TABLE order_status2 ENABLE NOVALIDATE CONSTRAINT order_status2_status_uq;

5.17 延遲約束

延遲約束 ( deferrable constraint ) 是在事務被提交時強制執行的約束

約束一旦新增之後,就不能再修改為 DEFERRABLE了;相反,只能先將其刪除,再重新建立這個約束

注:

在新增 DEFERRABLE 約束時,可以將其標識為 INITIALLY IMMEDIATE 或 INITIALLY DEFERRABLE

INITIALLY IMMEDIATE 的意思是每次向表中新增資料、修改表的資料或從表中刪除資料時都要檢查這個

約束( 這與約束的預設行為相同 );

INITIALLY DEFERRABLE 的意思是隻有在事務被提交時,才會檢查這個約束

範例:先刪除 order_status2_status_uq 約束,再新增該約束並將其設定為 DEFERRABLE INITIALLY DEFERRED

ALTER TABLE order_status2 DROP CONSTRAINT order_status2_status_uq;

ALTER TABLE order_status2 ADD CONSTRAINT order_status2_status_uq UNIQUE(status)

DEFERRABLE INITIALLY DEFERRED;

注:

如果向 order_status2 表中新增行,那麼只有在執行 commit 命令時,才會對 

order_status2_status_uq 約束進行檢查

5.18 獲得有關約束的資訊

   · user_constraints

   · all_constraints

5.19 獲得有關列的約束的資訊

   · user_cons_columns

   · all_cons_colums

6. 重命名錶

範例:將 order_status2 重新命名為 order_state

RNAME order_status2 TO order_state;

7. 向表中添加註釋

使用 COMMENT 語句可以為表或列添加註釋

範例:為表 order_status2 添加註釋

COMMENT ON TABLE order_status2 IS

'order_status2 stores the state of an order';

範例:為列 last_modified 添加註釋

COMMENT  ON COLUMN order_status2.last_modified IS

'last_modified stores the date and time the order was modified last';

7.1 獲得表的註釋

   · user_tab_comments

7.2 獲得列的註釋

   · user_col_comments

8. 截斷表

   · TRUNCATE

9. 刪除表

   · DROP

   · DROP .... PURGE

10. 使用 BINARY_FLOAT 和 BINARY_DOUBLE 資料型別

11. 使用 DEFAULT ON NULL 列

Oracle 12c 的一項新功能是 DEFAULT ON NULL 列子句,這個子句指定當 INSERT 語句提供

該列 NULL 值時,這個列被分配的預設值

範例:建立名為 purchases_default_null 的表,當 quantity 列被提供空值時,該列被設定為預設值 1

CREATE TABLE purchases_default_null 

(

   product_id INTEGER CONSTRAINT purch_default_product_fk

      REFERENCES products(product_id),

   quantity INTEGER DEFAULT ON NULL 1 NOT NULL,

      CONSTRAINT purch_default_pk PRIMARY KEY (product_id)

);

12. 在表中使用可見及不可見列

Oracle 12c 的一項新功能是在表中定義可見和不可見列的能力

可使用 VISIBLE 表明一列可見,使用 INVISIBLE 表明一個列不可見,沒有指定則預設列為可見

範例:建立名為 employees_hidden_example 的表,salary 列設定為不可見,title 列顯示設定為可見

CREATE TABLE employees_hidden_example

(

   employee_id INTEGER CONSTRAINT employee_hidden_example PRIMARY KEY,

   title VARCHAR2(20) VISIBLE,

   salary NUMBER(6,0) INVISIBLE

);

使用DESCRIBE 命令檢視的時候,可以使以下命令

   · SET COLINVISIBLE ON   檢視不可見的列

   · SET COLINVISIBLE         隱藏不可見的列

範例:檢視結果集中的不可見列,必須明確指明該列 

SELECT employee_id,title,salary FROM employees_hidden_example;

範例:更改表,使可見的列變為不可見

ALTER TABLE employees_hidden_example MODIFY

(

   title INVISIBLE,

   salary VISIBLE

);

二、 序列

序列 (sequence) 是一種資料庫項,可以生成整數序列,序列生成的整數通常可以用來

填充數字型別的主鍵列

1. 建立序列

語法如下:

CRAETE SEQUENCE sequence_name

[ START WITH start_num ] 

[ INCREMENT BY increment_num ] 

[ { MAXVALUE maximum_num | NOMAXVALUE } ]

[ { MINVALUE minimum_num | NOMINVALUE } ]

[ { CYCLE | NOCYCLE } ]

[ { CACHE cache_num | NOCACHE } ]

[ { ORDER | NOORDER } ];

其中:

   · sequence_name   指定序列名

   · start_num   指定序列從哪個整數開始,起始值預設為1

   · increment_num   指定序列每次增加的整數數量,增量值預設為1

   · maximum_num   指定序列的最大整數

   · minmum_num   指定序列的最小整數

   · NOMAXVALUE   指定升序序列的最大值為10^28 - 1

   · NOMINVALUE   指定升序序列的最小值為 1

   · CYCLE   指定序列即使已經達到最大值或最小值也繼續生成整數

                      當升序序列達到最大值時,下一個生成的值是最小值

                      當降序序列達到最小值時,下一個生成的值是最大值

   · NOCYCLE   指定序列在達到最大值或最小值之後就不能再生成整數了,NOCYCLE 是預設值

   · CACHE   指定快取,這個選項為序列預分配整數

   · cache_num   指定要保留在記憶體中的整數的個數,預設要快取的整數為 20 個

   · NOCACHE   指定不快取任何整數,這可以阻止資料庫為序列預分配值,從而避免序列產生不連續的情況

   · ORDER   確保按照請求次序生成整數

   · NOORDER   不確保按照請求次序生成整數,NOORDER 為預設值

2. 獲取序列的資訊

   · user_sequences

   · all_sequences

3. 使用序列

序列生成一系列數字,序列中包含兩個 “偽列”,分別是 CURRVAL NEXTVAL 

可以分別用來獲取序列的當前值和下一個值

在檢索序列的當前值之前,必須通過檢索序列的下一個值對序列進行初始化

範例:SELECT s_test.NEXTVAL FROM DUAL; = 1

當查詢 CURRVAL 時,NEXTVAL 保持永不變,只有在檢索下一個值時 NEXTVAL 才會改變

4. 使用序列填充主鍵

注:在使用序列填充主鍵時,通常應該使用 NOCACHE 選項,這樣可以避免序列產生不聯絡的情況

5. 使用序列指定預設列值

Oracle 12c 的一項新功能是使用序列指定預設列值的能力

6. 修改序列

ALTER SEQUENCE 語句可以用來修改序列

在修改序列是,可以修改的序列內容有如下限制:

   · 不能修改序列的初值

   · 序列的最小值不能大於當前值

   · 序列的最大值不能小於當前值

範例:將 s_test 序列的增量修改為 2

ALTER SEQUENCE s_test INCREMENT BY 2;

7. 刪除序列

DROP SEQUENCE 語句可以用來刪除序列

三、 索引

當任何單個查詢要檢索的行少於或等於整個錶行數的10%時,就應當建立索引

1. 建立 B-樹 索引

CREATE [UNIQUE] INDEX index_name ON 

table_name(column_name[,column_name ... ])

TABLESPACE tab_space;

注:由於效能方面的原因,通常應該將索引與表儲存到不同的表空間中

2. 建立基於函式的索引

CREATE INDEX index_name ON 

table_name(function_name(column_name));

3. 獲取有關索引的資訊

   · user_indexes

   · all_indexes

4. 獲取列索引的資訊

   · user_ind_columns

   · all_ind_columns

5. 修改索引

ALTER INDEX 可以用來修改索引

範例:將索引 i_customers_phone 重新命名為 i_customers_phone_number

ALTER INDEX i_customers_phone RENAME TO i_customers_phone_number

6. 刪除索引

DROP INDEX index_name;

7. 建立點陣圖索引

點陣圖索引一般用於資料倉庫中,資料倉庫是包含大量資料的資料庫

四、 檢視

檢視實際上是一個或多個表上的預定義查詢,這些表稱為基表 ( base table )

注:檢視中並不儲存行,它們始終儲存在表中,檢視返回儲存在表中的行

檢視具有以下優點:

   · 可以將複雜查詢編寫為檢視,並授予使用者訪問檢視的許可權,這樣就可以對使用者遮蔽複雜性

   · 限制使用者只能訪問檢視,這樣就可以阻止使用者直接查詢基表

   · 限制某個檢視只能訪問基表中的某些行,這樣就可以對終端使用者遮蔽部分行

1. 建立並使用檢視

CREATE [ OR REPLACE ] VIEW [ {FORCE | NOFORCE} ] view_name

[ (alias_name[,alias_name ... ]) ] AS subquery

[ WITH {CHECK OPTION | READ ONLY} CONSTRAINT constraint_name ];

其中:

   · FORCE   說明即使基表不存在也要建立檢視

   · NOFORCE   說明如果基表不存在,就不建立檢視,NOFORCE 是預設值

   · WITH CHECK OPTION   說明只有子查詢檢索的行才能被插入、修改或刪除

                                          預設情況下,在插入、更新或刪除行之前並不會檢查這些行是否能被子查詢檢索

   · WITH READ ONLY   說明只能對基表中的行進行只讀訪問

1.1 授予對檢視的許可權

使用者必須具有 CREATE VIEW 特權才能建立檢視

1.2 建立並使用簡單檢視

簡單檢視只會訪問一個基表

1.3 對檢視執行查詢

建立好檢視之後,就可以用它來訪問基表了

1.4 對檢視執行 INSERT 操作

如果檢視沒有使用 WITH CHECK OPTION,則可以插入、更新或刪除檢視不能檢索的行

1.5 建立具有 CHECK OPTION 約束的檢視

通過為檢視新增 CHECK OPTION 約束,可以指定對檢視執行的 DML 操作必須滿足子查詢的條件

範例:建立檢視 cheap_products_view2,該檢視具有 CHECK OPTION 約束

CREATE VIEW cheap_products_view2 AS

SELECT * FROM products WHERE price < 15 

WITH CHECK OPTION CONSTRAINT cheap_products_view2_price;

範例:使用 cheap_products_view2 試圖插入價格為 19.5 的一行,會報錯,因為該檢視並不能檢索出這一行

INSERT INTO cheap_products_view2 VALUES(15,1,'Southern Front',19.5);

1.6 建立具有 READ ONLY 約束的檢視

通過對檢視新增 READ ONLY 約束,可以指定檢視是隻讀的 ( 不允許 DML 操作 )

1.7 獲取有關檢視定義的資訊

   · DESCRIBE

   · user_views

   · all_views

1.8 獲取有關檢視的約束資訊

   · user_constaints

1.9 建立並使用複雜檢視

   · 從多個基表中檢索資料

   · 使用 GROUP BY 或 DISTINCT 子句對行分組

2. 修改檢視 

   · CRAETE OR REPLACE 可以徹底替換檢視

   · ALTER VIEW 可以用來修改檢視的約束

範例:使用 ALTER VIEW 從 cheap_products_view 中刪除 cheap_products_view 約束

ALTER VIEW cheap_products_view DROP CONSTRAINT cheap_products_view_price;

3. 刪除檢視

   · DROP VIEW 

4. 在檢視中使用可見列和不可見列

Oracle 12c 的一項新功能是在檢視中定義可見列和不可見列

VISIBLE 使一列可見,INVISIBLE 使一列不可見

注:要檢視檢視中的不可見列,必須明確指定該列

五、 閃回資料歸檔

   · 檢視行在特定時間戳的情況

   · 檢視行在兩個時間戳之間的情況

1. 建立閃迴歸檔

使用 CREATE FLASHBACK ARCHIVE 語句建立閃迴歸檔

範例:建立名為 test_archive 的閃迴歸檔

CONNECT system/oracle

CREATE FLASHBACK ARCHIVE test_archive

TABLESPACE example

QUOTA 1M

RETENTION 1 DAY;

範例:修改現有的表,將資料儲存在歸檔中

ALTER TABLE store.products FLASHBACK ARCHIVE test_archive;

隨後對錶 store.products 表所做的修改都會記錄在歸檔中

範例: INSERT 語句向 store.products 表新增一行

INSERT INTO store.products VALUES (15,1,'Using Linux','How to Use Linux',39.99);

範例:查詢表 store.products 在 5 min 前的情況

SELECT product_id,name,price FROM store.products

AS OF TIMESTAMP 

(SYSTIMESTAMP - INTERVAL '5' MINUTE);

範例:查看錶 store.products 在特定時間戳的情況

注:如果執行這個查詢,需要將時間戳修改為執行前面的 INSERT 語句之前的日期和時間

SELECT product_id,name,price FROM store.products

AS OF TIMESTAMP

TO_TIMESTAMP('2014-12-06 23:10:00','hh24:mi:ss');

範例:查看錶 store.products 在兩個時間戳之間的情況

SELECT product_id,name,price FROM store.products

VERSIONS BETWEEN TIMESTAMP

TO_TIMESTAMP('2014-12-06 23:15:00','yyyy-mm-dd hh24:mi:ss')

AND TO_TIMESTAMP('2014-12-06 23:20:00','yyyy-mm-dd hh24:mi:ss');

範例:查看錶 store.products 在某個時間戳和當前時間之間的情況

SELECT product_id,name,price FROM store.products

VERSIONS BETWEEN TIMESTAMP

TO_TIMESTAMP('2014-12-06 23:15:00','yyyy-mm-dd hh24:mi:ss')

AND MAXVALUE;

注:可以使用 ALTER TABLE 停止對錶的資料歸檔

ALTER TABLE store.products NO FLASHBACK ARCHIVE;

注:建立表時,可以為表指定閃迴歸檔

CREATE TABLE store.test_table

(

   id INTEGER,

   name VARCHAR2(10)

)

FLASHBACK ARCHIVE test_archive;

注:可以修改閃迴歸檔

範例:將資料保留時間設定為兩年

ALTER FLASHBACK ARCHIVE test_archive MODIFY RETENTION 2 YEAR;

注:可以從閃迴歸檔中清除給定時間戳之前的資料

範例:清除一天以前的資料

ALTER FLASHBACK ARCHIVE test_archive PURGE BEFORE TIMESTAMP(SYSTIMESTAMP - INTERVAL '1' DAY);

注:可以清除閃迴歸檔中的所有資料

ALTER FLASHBACK ARCHIVE test_archive PURGE ALL;

注:可以刪除閃迴歸檔

DROP FLASHBACK ARCHIVE test_archive;

附:使用下面的檢視可以檢視閃迴歸檔的詳細資訊

   · user_flashback_archive 和 dba_flashback_archive ,它們顯示閃迴歸檔的總體資訊

   · user_flashback_archive_ts 和 dba_flashback_archive_ts , 它們顯示包含閃迴歸檔的表空間的有關資訊

   · user_flashback_archive_tables 和 dba_flashback_archive_tables ,它們顯示啟用了閃迴歸檔的那些表的資訊