第22課 高級SQL特性
這一課介紹SQL
所涉及的幾個高級數據處理特性:約束、索引和觸發器。
約束
是實施引用完整性的重要部分。索引
可改善數據檢索的性能。觸發器
可以用來執行運行前後的處理。安全選項
可用來管理數據訪問。
22.1 約束
關係數據庫存儲分解爲多個表的數據,每個表存儲相應的數據。利用鍵來建立從一個表到另一個表的引用(由此產生了術語引用完整性referential integrity
)。
正確地進行關係數據庫設計,需要一種方法保證只在表中插入合法數據。
不能檢查合法的原因是:
- 如果在客戶端層面上實施數據庫完整性規則,則每個客戶觀都要被迫實施這些規則,一定會有一些客戶端不實施這些規則。
- 在執行
UPDATE
和DELETE
操作時,也必須實施這些規則。 - 執行客戶端檢查是非常耗時的,而
DBMS
執行這些檢查會相對高效。
約束
- 管理如何插入或處理數據庫數據的規則。
DBMS
通過在數據庫表上施加約束來實施引用完整性。
22.1.1 主鍵
主鍵
是一種特殊的約束,用來保證一列(或一組列)中的值是唯一的,而且永不改動。
表中任意列只要滿足以下條件,都可以用於主鍵。
- 任意兩行的主鍵值都不相同。
- 每行都具有一個主鍵值(即列中不允許
NULL
值)。 - 包含主鍵值的列從不修改或更新。
- 主鍵值不能重用。如果從表中刪除某一行,其主鍵值不分配給新行。一種定義主鍵的方法是創建它。
ALTER TABLE Vendors
ADD CONSTRAINT PRIMARY KEY (vend_id);
這裏定義相同的列爲主鍵,但使用的是CONSTRAINT
語法。此語法也可以用於CREATE TABLE
和ALTER TABLE
語句。
22.1.2 外鍵
外鍵
是表中的一列,其值必須列在另一表的主鍵中。外鍵是保證引用完整性的極其重要部分。
- 使用
REFERENCES
關鍵字 - 相同的工作也可以在
ALTER TABLE
語句中用CONSTRAINT
語法來完成。
22.1.3 唯一約束
唯一約束
用來保證一列(或一組列)中的數據是唯一的。
它們類似於主鍵,但存在以下重要區別。
- 表可包含多個唯一約束,但每個表只允許一個主鍵。
- 唯一約束列可包含
NULL
值。 - 唯一約束列可修改或更新。
- 唯一約束列的值可重複使用。
- 與主鍵不一樣,唯一約束不能用來定義外鍵。
唯一約束既可以用UNIQUE
關鍵字在表定義中定義,也可以用單獨的CONSTRAINT
定義。
22.1.4 檢查約束
檢查約束
用來保證一列(或一組列)中的數據滿足一組指定的條件。
檢查約束的常見用途有以下幾點:
- 檢查最小或最大值。
- 指定範圍。
- 只允許特定的值。
第1課介紹的數據類型限制了列中可保存的數據的類型。檢查約束在數據類型內又做了進一步的限制,這些限制極其重要,可以確保插入數據庫的數據正是你想要的數據。不需要依賴於客戶端應用程序或用戶來保證正確獲取它,DBMS
本身將會拒絕任何無效的數據。
- 使用
CHECK
語法。
22.2 索引
索引
用來排序數據以加快搜索和排序操作的速度。
主鍵數據總是排序的,這是DBMS
的工作。因此,按主鍵檢索特定行總是一種快速有效的操作。
可以在一個或多個列上定義索引,使DBMS
保存其內容的一個排過序的列表。在定義了索引後,DBMS
以使用書的索引類似的方法使用它。DBMS
搜索排過序的索引,找出匹配的位置,然後檢索這些行。
在開始創建索引前,應該記住以下內容。
- 索引改善檢索操作的性能,但降低了數據插入、修改和刪除的性能。在執行這些操作時,
DBMS
必須動態地更新索引。 - 索引數據可能要佔用大量的存儲空間。
- 並非所有數據都適合做索引。取值不多的數據(如州)不如具有更多可能值的數據(如姓或名),能通過索引得到那麼多的好處。
- 索引用於數據過濾和數據排序。如果你經常以某種特定的順序排序數據,則該數據可能適合做索引。
- 可以在索引中定義多個列(例如,州加上城市)。這樣的索引僅在以州加城市的順序排序時有用。如果想按城市排序,則這種索引沒有用處。
索引用CREATE INDEX
語句創建(不同DBMS
創建索引的語句變化很大)。
- 索引必須唯一命名。
- ON用來指定被索引的表,而索引中包含的列(此列中僅有一列)在表明後的圓括號中給出。
22.3 觸發器
觸發器
是特殊的存儲過程,它在特定的數據庫活動發生時自動執行。 觸發器可以與特定表上的INSERT
、UPDATE
和DELETE
操作(或組合)相關聯。
與存儲過程不一樣(存儲過程只是簡單的存儲SQL語句),觸發器與單個的表相關聯。
觸發器內的代碼具有以下數據的訪問權:
INSERT
操作中的所有新數據;UPDATE
操作中的所有新數據和舊數據;DELETE
操作中刪除的數據。
根據所使用的DBMS
的不同,觸發器可在特定操作執行之前或之後執行。
下面是觸發器的一些常見用途。
- 保證數據一致。
- 基於某個表的變動在其他表上執行活動。
- 進行額外的驗證並根據需要回退數據。
- 計算計算列的值或更新時間的戳。
提示:約束比觸發器更快
一般來說,約束的處理比觸發器快,因此在可能的時候,應該儘量使用約束。
22.4 數據庫安全
數據也必須允許需要訪問它的用戶訪問,因此大多數DBMS
都給管理員提供了管理機制,利用管理機制授予或限制對數據的訪問。
任何安全系統的基礎都是用戶授權和身份確認。這是一種處理,通過這種處理對用戶進行確認,保證他是有權用戶,允許執行他要執行的操作。有的DBMS
爲此結合使用了操作系統的安全措施,而有的維護自己的用戶及密碼列表,還有一些結合使用外部目錄服務服務器。
一般說來,需要保護的操作有:
- 對數據庫管理功能(創建表、更改或刪除已存在的表等)的訪問;
- 對特定數據庫或表的訪問;
- 訪問的類型(只讀、對特定列的訪問等);
- 僅通過視圖或存儲過程對錶進行訪問;
- 創建多層次的安全措施,從而允許多種基於登錄的訪問和控制;
- 限制管理用戶賬號的能力。
安全性使用SQL
的GRANT
和REVOKE
語句來管理,不過,大多數DBMS
提供了交互式的管理實用程序,這些實用程序在內部使用GRANT
和REVOKE
語句。