韓 杰
摘 要:數據完整性是數據庫安全中一個重要的部分,對保護數據正確性、一致性和有效性有重要作用,是在進行數據庫設計時要考慮的一個重要問題,就SQL Server中數據完整性的類型和實現作了闡述,并結合一個應用實例進行了示范。
關鍵詞:數據完整性;域完整性;實體完整性;引用完整性;用戶定義完整性
中圖分類號:TP311.13文獻標識碼:A文章編號:16723198(2009)22025902お
數據完整性是關系數據庫模型中數據安全的重要組成部分,能夠避免破壞數據項之間的結構,維持數據的正確性、一致性和有效性,保持同一數據的不同副本協調一致,從而可以極大地提高數據的可用性。數據完整性的控制機制一般包括三個方面內容:數據語義約束條件的定義;約束條件的檢查;違背約束條件時系統的異常處理。
1 數據完整性類型
(1)域完整性。對表字段取值進行約束,提供了一個給定域的有效入口,包括數據類型、取值范圍、格式、精度等的規定,例如設定學號必須全是數字等,因此保證了一個數據庫不可能包含任何無意義的或者不合理的值。
(2)實體完整性。以表記錄為單位進行約束,規定一個表中的每一行必須是唯一的。開發者需要指定一個表中的一列或一組列作為它的主鍵,表中的每行必須含有一個唯一的主鍵。主鍵首先不能為空值(NULL),其次不能與表中已有行的主鍵值相同。
(3)引用完整性。定義一個關系數據庫中不同的列和不同的表之間的關系,一列或一組列中的值引用相關的一列或一組列中的值,必須要與相關的一列或一組列中的值相匹配。從屬的一列或一組列稱作外鍵,被引用的列或一組列稱作父鍵。父鍵必須是一個主鍵或唯一值鍵,若父鍵和外鍵屬于同一個表,則稱作自引用完整性。
(4)用戶定義完整性。以上三種數據完整性約束能夠實現數據庫中大部分數據完整性,但總有一些約束條件是開發者不能應用以上數據完整性約束來實行的。如入學時間不能晚于畢業時間;又如當某一學生記錄從學生簡歷中被刪除時,需要同時在歷史表中登記被刪除的學生記錄。實現諸如此類的數據完整性保護,需要開發者自己通過創建存儲過程和觸發器等來實現。我們把這類完整性約束稱為用戶定義完整性。
2 數據完整性的實現
(1)聲明型數據完整性:作為數據庫說明的一部分在數據庫定義中實現,通過 CREATE TABLE和ALTER TABLE語句中使用表約束或列約束的方式來限制表中的值。這種方法實現數據完整性簡單,而且不容易出錯,可以直接將數據完整性的要求定義在表和列上。這種方法可以實現數據的實體完整性與參照完整性,部分實現域完整性與用戶定義完整性。
(2)過程型數據完整性:主要指通過缺省、規則和觸發器,或視圖和存儲過程實現。這一類完整性實現相對來說較復雜,但是具有更大的靈活性。主要用于實現域完整性與用戶完整性。
2.1 域完整性的實現
(1)缺省值(default constraint)約束:它與列值相關聯,而不是與數據類型相關聯,可以為任何數據類型(除timestamp和具有identity屬性的列外)定義缺省值約束。
(2)檢查(check)約束:它限制輸入到一列或多列中的可能值,從而保證SQL Server數據庫中數據的域完整性,在check約束中可以包含搜索條件,但是不能包含子查詢,一個表中可以包含多個check約束,對于列也可以定義多個check約束。
(3)缺省(default):缺省是一種數據庫對象,它與缺省值約束的作用類似,為INSERT 語句中未指定數據的列設置缺省值,缺省對象只適用受INSERT語句影響的行。定義缺省的格式為:
CREATE DEFAULT [owner] default_name AS constant_expression
其中default_name是新建的缺省的名字,constant_expression是一個常量表達式,在這個表達式中不包含有任何列名或其它數據庫對象名,但可使用不涉及數據庫的SQL Server內部函數。
缺省創建后,使用系統存儲過程sp_binddefault與表中的列捆綁,也可以與用戶定義的數據類型捆綁,其語法如下:
Sp_binddefault default_name, object_name
其中object_name是要指定與該缺省相綁定的列名或用戶定義的類型名,如果指定的是表中的列,其格式為table.column,否則被認為是用戶定義的數據類型名,如果名字中含有空格或標點符號或是保留字,則必須用引號將它放入引號中。
(4)規則(rule):規則是數據庫對象之一,指定向某列(或用與該規則綁定的用戶定義數據類型的所有列)插入或更新數據時,限制輸入新值的取值范圍。一個規則可以是:值的清單或值的集合、值的范圍、必須滿足的單值條件、用LIKE子句定義的編輯掩碼等。當數據庫中數據值被更新或插入時,就要檢查新值是否遵循規則,如果不符合規則就拒絕執行更新或插入操作。規則在實現功能上等同于CHECK約束。
(5)觸發器(trigger)是特定類型的存儲過程,作為數據修改(增、刪、改)語句的一部分而在相應操作執行時自動執行,是維護數據庫完整性最強大的工具,能在任何情況下去維護數據的完整性,應用程序不能繞過觸發器(除非是批量復制和TRUNCATE TABLE)不予執行,這也正是觸發器和一般存儲過程的一大區別。
2.2 實體完整性的實現
(1)列的Identity屬性說明為Identity的列由系統自動為其賦值,并保證其值在該表中的惟一性,每一個表中只允許有一個列定義為Identity的。定義時Identity后可跟seed和increment參數,前一參數表示該列的起始值,后一參數表示該列值每次的增量。
(2)主鍵(primary key)約束指定表中一列或數列作為數據表的主鍵,下面是對customers表中的customer id建立主鍵值約束。
CREATE TABLE customers (Customer_id INT Primary Key, Customer_name NVARCHAR (20), Customer_address NVARCHAR (20))
在這個customers表中customer_id的取值必須不相同且不能取空值。
(3)惟一性(unique)約束和primary key約束相類似,定義數據列值的惟一性約束,有一行可取NULL值,并且惟一性約束在一個表中可以使用多次,而主鍵值只可以在一個表中使用一次。在缺省的情況下,惟一約束產生非聚簇索引,而主鍵約束產生聚簇索引。
2.3 參照完整性的實現
通過在同一個數據庫的兩個表中進行主鍵約束和外鍵約束來實現,參照的列和被參照的列的名字必須相同。在被參照表中,主鍵值被其它表所參照時,該行不能被刪除,也不允許改變。
在參照表中,不允許參照不存在的主鍵值。下面例子在定義了orders表的customer_id列參照customers中的customer_id列。
CREATE TABLE orders(Order_id INT Primary Key,Customer_id INT RETERENCES customers(customer_id),Order_date DATETIME)