妳對ORACLE約束的了解如何?比較模糊還是相當透徹?如果妳對下面幾個問題了如指掌的話,恭喜妳,妳已經對約束掌握得比較好了,不用看這篇文章了。ORACLE的約束有啥功能作用? 有哪些類型約束(不同版本ORACLE是否不同)?視圖有約束嗎?約束是否會影響SQL性能? 約束信息存儲在哪些系統視圖、數據字典中?約束能否修改名稱?能否禁用約束?延遲約束有啥好處.......
約束定義
約束是強加在表上的規則或條件。確保數據庫滿足業務規則。保證數據的完整性。當對表進行DML或DDL操作時,如果此操作會造成表中的數據違反約束條件或規則的話,系統就會拒絕執行這個操作。約束可以是列壹級別的 也可以是表級別的。定義約束時沒有給出約束的名字,ORACE系統將為該約束自動生成壹個名字,其格式為SYS_Cn,其中n為自然數(強烈建議各位在創建表或增加約束時,給約束定義名稱。).
約束功能
約束的功能:實現壹些業務規則,防止無效的垃圾數據進入數據庫,維護數據庫的完整性(完整性指正確性與壹致性)。從而使數據庫的開發和維護都更加容易。
約束分類
約束分為6類: 非空(NOT NULL)約束、 唯壹(UNIQUE)約束、主鍵(PRIMARY KEY)約束、外鍵(FOREIGN KEY)約束、條件(CHECK)約束、REF約束。
非空(NOT NULL)約束:顧名思義,所約束的列不能為NULL值。否則就會報錯
唯壹(UNIQUE)約束:在表中每壹行中所定義的這列或這些列的值都不能相同。必須保證唯壹性。否則就會違法約束條件。
主鍵(PRIMARY KEY)約束:唯壹的標識表中的每壹行,不能重復,不能為空。 創建主鍵或唯壹約束後,ORACLE會自動創建壹個與約束同名的索引(UNIQUENES為UNIQUE唯壹索引)。需要註意的是:每個表只能有且有壹個主鍵約束。
外鍵(FOREIGN KEY)約束:用來維護從表(Child Table)和主表(Parent Table)之間的引用完整性. 外鍵約束是個有爭議性的約束,它壹方面能夠維護數據庫的數據壹致性,數據的完整性。防止錯誤的垃圾數據入庫; 另外壹方面它會增加表插入、更新等SQL性能的額外開銷,不少系統裏面通過業務邏輯控制來取消外鍵約束。例如在數據倉庫中,就推薦禁用外鍵約束。
條件(CHECK)約束:表中每行都要滿足該約束條件。條件約束既可以在表壹級定義也可以在列壹級定義。在壹列上可以定義任意多個條件約束。
REF約束的定義:REF column by definition references an object in another object type or in a relational table. A REF constraint lets you further describe the relationship between the REF column and the object it references.
ORACLE 11 數據庫的約束類型如下:
ORACLE 10 數據庫的約束類型如下:
在oracle 官方文檔/cd/B19306_01/server.102/b14237/statviews_1037.htm下
C (check constraint on a table)
P (primary key)
U (unique key)
R (referential integrity)
V (with check option, on a view)
O (with read only, on a view)
/cd/B28359_01/server.111/b28286/clauses002.htm
/cd/B28359_01/server.111/b28320/statviews_1044.htm#REFRN20047
C Check constraint on a table
P Primary key
U Unique key
R Referential integrity
V With check option, on a view
O With read only, on a view
H Hash expression
F Constraint that involves a REF column
S Supplemental logging
對於H、S類型,尚不清楚情況,而且從上面我在11g數據庫實驗結果看,也沒發現這兩種類型。(有了解的朋友可以告知壹二)
約束命名規範
約束名稱建議自己定義壹套命名規則,否則使用系統生成的約束名,很難能把它和對應的表、字段聯系起來。
非空約束 NN_表名_列名
唯壹約束 UK_表名_列名
主鍵約束 PK_表名
外鍵約束 FK_表名_列名
條件約束 CK_表名_列名
默認約束 DF_表名_列名
如果約束名稱超過32位長度,建議應該縮寫表名,而不應用NN_表名_數字。不過具體視情況而定,很多時候 DF_表名_列名 這樣命名,往往超出了32字符。所以有時候需要縮寫表面或是采用其它規則。
約束操作
約束管理
創建各類約束
先看壹下如何創建主鍵約束
復制代碼
CREATE TABLE "DM"."DEPT"
(
"DEPTNO" NUMBER(2,0) PRIMARY KEY,
"DNAME" VARCHAR2(14),
"LOC" VARCHAR2(13)
) TABLESPACE "TBS_DM_DAT" ;
COMMENT ON TABLE "DM"."DEPT" IS '部門表';
COMMENT ON COLUMN "DM"."DEPT"."DEPTNO" IS '部門編號';
COMMENT ON COLUMN "DM"."DEPT"."DNAME" IS '部門名稱';
COMMENT ON CLOUMN "DM"."DEPT"."LOC" IS '部門所在地方';
復制代碼
此時它的約束名稱是系統創建的。如圖所示:
如果我們以下面的腳本創建,此時約束如下所示
復制代碼
1 CREATE TABLE "DM"."DEPT"
2 (
3 "DEPTNO" NUMBER(2,0) ,
4 "DNAME" VARCHAR2(14) ,
5 "LOC" VARCHAR2(13) ,
6 CONSTRAINT "PK_DEPT" PRIMARY KEY ("DEPTNO") USING INDEX TABLESPACE TBS_DM_IN
7 ) TABLESPACE "TBS_DM_DAT" ;
8
9
10
11
12 COMMENT ON TABLE "DM"."DEPT" IS '部門表';
13
14 COMMENT ON COLUMN "DM"."DEPT"."DEPTNO" IS '部門編號';
15
16 COMMENT ON COLUMN "DM"."DEPT"."DNAME" IS '部門名稱';
17
18 COMMENT ON CLOUMN "DM"."DEPT"."LOC" IS '部門所在地方';
19
復制代碼
如果壹個表的約束類型比較多,妳會看到壹堆SYS_CN這樣的約束,如果不仔細核對後面的字段,很難壹眼看出約束類型、約束對應字段。
主鍵約束的限制
文檔原文如下: (翻譯在下)
Restrictions on Primary Key Constraints Primary constraints are subject to the following restrictions:
A table or view can have only one primary key.
壹個表或視圖有且只有壹個主鍵
None of the columns in the primary key can be LOB, LONG, LONG RAW, VARRAY, NESTED TABLE, BFILE, REF, TIMESTAMP WITH TIME ZONE, or user-defined type. However, the primary key can contain a column of TIMESTAMP WITH LOCAL TIME ZONE.
主鍵字段不能為LOB、LOG、LOG RAW、VARRAY、NESTED TABLE、BFILE、REF、TIMESTAMP WITH TIME ZONE或用戶定義類型。然而它可以包含TIMESTAMP WITH LOCAL TIME ZONE類型的字段。
The size of the primary key cannot exceed approximately one database block.
主鍵大小不能超過壹個數據塊大小。
A composite primary key cannot have more than 32 columns.
主鍵組合鍵不能超過32列。
You cannot designate the same column or combination of columns as both a primary key and a unique key.
妳不能指定壹列或組合列既是主鍵又是唯壹鍵。
You cannot specify a primary key when creating a subview in an inheritance hierarchy. The primary key can be specified only for the top-level (root) view.
創建壹個繼承層次結構中的子視圖時,妳不能指定壹個主鍵。主鍵可以唯壹指定的頂層(根)視圖。
外鍵約束
ALTER TABLE childTable
ADD CONSTRAINT FK_xxxx_xxx
FOREIGH KEY(columnName)
REFERENCES parentTalbe(primaryKeyColumn) [ON DELETE CASCADE|SET NULL];
ON DELETE SET NULL子句:當主表中的壹行數據被刪除時,Oracle系統會自動地將所有從表中依賴於它的數據記錄的外鍵改成空值;
ON DELETE CASCADE:當主表中的壹行數據被刪除時,Oracle系統會自動地將所有從表中依賴於它的數據記錄刪除;
註:如果在外鍵定義中使用了ON DELETE SET NULL 或ON DELETE CASCADE,無論刪除操作是在父表這壹端還是子表這壹端都不會產生違反引用完整性的問題,但是卻留下了安全隱患。這兩個子句要謹慎使用,只有在不得已時使用,謹記謹記!!!
外鍵約束對DML與DDL的影響:
INSERT:只有操作是在子表或從表這壹端時才會產生違反引用完整性約束的問題,父表則不然。
DELETE:只有操作是在父表或主表這壹端時才會產生違反引用完整性約束的問題,子表則不然。
UPDATE:子表父表直接操作都會違反引用完整性約束。兩種解決方法:
1)先更新子表的引用列為空,再更新父表的主鍵的列的值,然後把子表的引用列更新成新的父表的值;
2)使用ON DELETE SET NULL,先更新父表,然後將子表外鍵為空的記錄更新為新的值。
DDL語句:DROP TABLE與TRUNCATE TABLE,操作父表,違反引用完整性約束,子表則不然。
外鍵約束的限制:
Restrictions on Foreign Key Constraints Foreign key constraints are subject to the following restrictions:
None of the columns in the foreign key can be of LOB, LONG, LONG RAW, VARRAY, NESTED TABLE, BFILE, REF, TIMESTAMP WITH TIME ZONE, or user-defined type. However, the primary key can contain a column of TIMESTAMP WITH LOCAL TIME ZONE.
外鍵字段不能為LOB, LONG, LONG RAW, VARRAY, NESTED TABLE, BFILE, REF, TIMESTAMP WITH TIME ZONE, or user-defined type類型,主鍵可以包含數據類型為TIMESTAMP WITH LOCAL TIME ZONE的字段。
The referenced unique or primary key constraint on the parent table or view must already be defined.
引用唯壹或主鍵約束,必須是父表中已經定義的。
A composite foreign key cannot have more than 32 columns.
外鍵的組合列不能超過32列。
The child and parent tables must be on the same database. To enable referential integrity constraints across nodes of a distributed database, you must use database triggers. See CREATE TRIGGER.
字表和父表必須在同壹個數據庫。分布式數據庫中,外鍵不能跨節點,但觸發器可以
If either the child or parent object is a view, then the constraint is subject to all restrictions on view constraints. See "View Constraints".
You cannot define a foreign key constraint in a CREATE TABLE statement that contains an AS subquery clause. Instead, you must create the table without the constraint and then add it later with an ALTER TABLE statement.
妳不能在CREATE TABLE語句中包含AS子查詢子句定義壹個外鍵約束。相反,妳必須創建壹個沒有約束的表,然後添加ALTER TABLE語句。
加上壹些類似其它約束的限制.
條件約束
非空約束
非空約束的限制:
1: 妳不能在視圖約束上指定字段為NULL或NOT NULL值
2: 妳不能指定壹個對象的屬性為NULL或NOT NULL。相反,而應使用的IS [NOT] NULL條件CHECK約束
條件約束中的條件與查詢語句中的條件相同,但是不能包括以下內容:
1)CURRVAL,NETXTVAL,LEVEL和ROWNUM這樣的偽列(PSEUDOCOLUMNS);
2)引用其它行中值的查詢語句;
3)SYSDATE,USER,USERENV和UID的函數調用。
文檔原文如下:
Restrictions on NOT NULL Constraints NOT NULL constraints are subject to the following restrictions:
You cannot specify NULL or NOT NULL in a view constraint.
You cannot specify NULL or NOT NULL for an attribute of an object. Instead, use a CHECK constraint with the IS [NOT] NULL condition.
唯壹約束
唯壹約束的限制:
文檔原文如下:
Restrictions on Unique Constraints Unique constraints are subject to the following restrictions:
None of the columns in the unique key can be of LOB, LONG, LONG RAW, VARRAY, NESTED TABLE, OBJECT, REF, TIMESTAMP WITH TIME ZONE, or user-defined type. However, the unique key can contain a column of TIMESTAMP WITH LOCAL TIME ZONE.
當字段類型為LOB、LOG、LONG RAW、 VARRAY、NESTED TABLE、OBJECT、REF、TIMESTAMP、用戶定義類型時,不能在字段上定義唯壹性約束。當數據類型為TIMESTAMP WITH LOCAL TIME ZONE
A composite unique key cannot have more than 32 columns.
組合字段定義的唯壹索引,字段個數不能超過32個
You cannot designate the same column or combination of columns as both a primary key and a unique key.
妳不能指定同壹字段或組合字段即為主鍵又是唯壹鍵
You cannot specify a unique key when creating a subview in an inheritance hierarchy. The unique key can be specified only for the top-level (root) view.
約束管理
刪除約束
復制代碼
ALTER TABLE DM.EMP
DROP CONSTRAINT SYS_C00115525;
CASCADE子句用來刪除存在有完整性關系的約束。當然妳也可以用如下語法
ALTER TABLE DM.EMP
DROP UNIQUE (COMM);
復制代碼
添加約束
復制代碼
添加非空約束
ALTER TABLE DM.EMP
MODIFY(MGR CONSTRAINT CK_EMP_MGR NOT NULL);
添加其他約束
ALTER TABLE DM.EMP
ADD CONSTRAINT CK_EMP_SAL CHECK(SAL > 0 AND SAL <20000);
復制代碼
重命名約束
ALTER TABLE METAONE.T1
RENAME CONSTRAINT SYS_C0059699 TO PK_T1
約束維護
禁用約束
ALTER TABLE 表 DISABLE CONSTRAINT 約束名 [CASCADE];
ALTER TABLE DM.EMP
DISABLE CONSTRAINT UK_EMP_COMM;
ALTER TABLE TEST DISABLE PRIMARY KEY CASCADE;
參數CASCADE子句用來關閉存在有完整性關系的約束,比如DISABLE壹個主鍵,如果沒有CASCADE子句就會出錯,此時使用CASCADE子句DISABLE主鍵可以將該主鍵與相關外鍵壹起DISABLE掉。使用的情況:例如在數據庫系統中大規模裝入數據時,為了系統的效率您不得不犧牲數據的壹致性來關閉壹些約束,甚至刪除壹些約束將主表主鍵禁止的同時,也將禁止依賴於此主鍵的外鍵禁止了.
使用上面腳本禁用約束的時候會刪除索引,如果妳想禁用約束的時候,保留索引,可以使用如下腳本(當然妳再啟用約束的時候會重新重建索引,這對大表顯然開銷相當大)
ALTER TABLE DM.EMP
DISABLE CONSTRAINT UK_EMP_COMM KEEP INDEX;
啟用約束
如果關閉主鍵約束時使用了CASCADE,此時使用ENABLE不會將主鍵約束與外鍵約束同時打開,只能對主鍵約束與外鍵約束分別使用ENABLE CONSTRAINT 子句打開。
推遲約束
Deferring Constraint Checks
當前事務的Constraint Checks全部推遲
SET CONSTRAINTS ALL DEFERRED;
SET CONSTRAINT XXX DEFERRED;
當前會話的Constraint Checks.
ALTER SSSSION SET CONSTRAINTS ALL deferred;
ALTER SSSSION SET CONSTRAINT xxx deferred;
約束信息
復制代碼
SELECT * FROM DBA_CONSTRAINTS;
SELECT * FROM ALL_CONSTRAINTS;
SELECT * FROM USER_CONSTRAINTS;
SELECT * FROM DBA_CONS_COLUMNS;
SELECT * FROM ALL_CONS_COLUMNS;
SELECT * FROM USER_CONS_COLUMNS;
復制代碼
約束有四種狀態:ENABLE、VALID、INVALID、DISABLE
約束的檢查機制
IMMEDIATE語句級:Oracle performs its constraint checking after the statement has been completely executed.
DEFERRED(事務級):A constraint is deferred if the system checks that it is satisfied only on commit. If a deferred constraint is violated, then commit causes the transaction to rollback;(推遲到事務提交時才檢查約束,謹慎使用)