SQL進階五:SQL完整性約束

完整性約束用於加強數據的完整性,Oracle提供了5種完整性約束:    數據庫

            Check
NOT NULL
Unique
Primary
Foreign keyoracle

  完整性約束是一種規則,不佔用任何數據庫空間。完整性約束存在數據字典中,在執行SQL或PL/SQL期間使用。用戶能夠指明約束是啓用的仍是禁用的,當約束啓用時,他加強了數據的完整性,不然,則反之,但約束始終存在於數據字典中。ide

  禁用約束,使用ALTER語句函數

ALTER TABLE table_name DISABLE CONSTRAINT constraint_name;
性能


spa

ALTER TABLE policies DISABLE CONSTRAINT chk_gender

若是要從新啓用約束:對象

ALTER TABLE policies ENABLE CONSTRAINT chk_gender

刪除約束索引

ALTER TABLE table_name DROP CONSTRAINT constraint_name

事務

ALTER TABLE policies DROP CONSTRAINT chk_gender;

Check 約束ci

  在數據列上Check 約束須要  一個特殊的布爾條件或者將數據列設置成TRUE,至少一個數據列的值是NULL,Check約束用於加強表中數據內容的簡單的商業規則。用戶使用Check約束保證數據規則的一致性check約束能夠涉及該行同屬Check約束的其餘數據列但不能涉及其餘行或其餘表,或調用函數SYSDATE,UID,USER,USERENV。若是用戶的商業規則須要這類的數據檢查,那麼可使用觸發器。Check約束不保護LOB數據類型的數據列和對象、嵌套表、VARRY、ref等。單一數據列能夠有多個Check約束保護,一個Check約束能夠保護多個數據列。

  建立表的Check約束使用CREATE TABLE語句,更改表的約束使用ALTER TABLE語句。

  語法:

CONSTRAINT [constraint_name] CHECK  (condition);

Check約束能夠被建立或增長爲一個表約束,當Check約束保護多個數據列時,必須使用表約束語法。約束名是可選的而且若是這個名字不存在,那麼oracle將產生一個以SYS_開始的惟一的名字。

  例:

CREATE TABLE policies
(policy_id NUMBER,
holder_name  VARCHAR2(40),
gender VARCHAR2(1) constraint chk_gender CHECK (gender in  ('M','F'),
marital_status VARCHAR2(1),
date_of_birth DATE,
constraint  chk_marital CHECK (marital_status in('S','M','D','W'))
);

NOT  NULL約束

  NOT  NULL約束應用在單一的數據列上,而且他保護的數據列必需要有數據值。缺省情況下,ORACLE容許任何列均可以有NULL值。某些商業規則要求某數據列必需要有值,NOT  NULL約束將確保該列的全部數據行都有值。

  例:

CREATE TABLE policies
(policy_id NUMBER,
holder_name VARCHAR2(40) NOT  NULL,
gender VARCHAR2(1),
marital_status VARCHAR2(1),
date_of_birth  DATE NOT NULL
);

對於NOT NULL的ALTER TABLE語句與其餘約束稍微有點不一樣。

ALTER TABLE policies MODIFY holder_name NOT NULL
 惟一性約束(Unique  constraint)

  惟一性約束能夠保護表中多個數據列,保證在保護的數據列中任何兩行的數據都不相同。惟一性約束與表一塊兒建立,在惟一性約束建立後,可使用ALTER  TABLE語句修改。

  語法:

column_name data_type CONSTRAINT constraint_name  UNIQUE

若是惟一性約束保護多個數據列,那麼惟一性約束要做爲表約束增長。語法以下:

CONSTRAINT constraint_name (column) UNIQUE USING INDEX TABLESPACE  (tablespace_name) STORAGE (stored clause)


惟一性約束由一個B-tree索引加強,因此能夠在USING子串中爲索引使用特殊特徵,好比表空間或存儲參數。CREATE  TABLE語句在建立惟一性約束的同時也給目標數據列創建了一個惟一的索引。

CREATE TABLE insured_autos
(policy_id NUMBER CONSTRAINT pk_policies  PRIMARY KEY,
vin VARCHAR2(10),
coverage_begin DATE,
coverage_term  NUMBER,
CONSTRAIN unique_auto UNIQUE (policy_id,vin) USING INDEX TABLESPACE  index STORAGE (INITIAL 1M NEXT 10M PCTINCREASE 0)
);


用戶能夠禁用未以性約束,但他仍然存在,禁用惟一性約束使用ALTER TABLE 語句

ALTER TABLE insured_autos DISABLE CONSTRAIN unique_name;


刪除惟一性約束,使用ALTER TABLE....DROP CONSTRAIN語句

ALTER TABLE insured_autos DROP CONSTRAIN unique_name;


注意用戶不能刪除在有外部鍵指向的表的惟一性約束。這種狀況下用戶必須首先禁用或刪除外部鍵(foreign key)。

  刪除或禁用惟一性約束一般同時刪除相關聯的惟一索引,於是下降了數據庫性能。常常刪除或禁用惟一性約束有可能致使丟失索引帶來的性能錯誤。要避免這樣錯誤,能夠採起下面的步驟:

  一、在惟一性約束保護的數據列上建立非惟一性索引。

  二、添加惟一性約束

  主鍵(Primary Key)約束

  表有惟一的主鍵約束。表的主鍵能夠保護一個或多個列,主鍵約束可與NOT NULL約束共同做用於每一數據列。NOT  NULL約束和惟一性約束的組合將保證主鍵惟一地標識每一行。像惟一性約束同樣,主鍵由B-tree索引加強。

  建立主鍵約束使用CREATE TABLE語句與表一塊兒建立,若是表已經建立了,可使用ALTER TABLE語句。

CREATE TABLE policies
(policy_id NUMBER CONSTRAINT pk_policies PRIMARY  KEY,
holder_name VARCHAR2(40),
gender VARCHAR2(1),
marital_status  VARCHAR2(1),
date_of_birth DATE
);


與惟一性約束同樣,若是主鍵約束保護多個數據列,那麼必須做爲一個表約束建立。

CREATE TABLE insured_autos
(policy_id NUMBER,
vin  VARCHAR2(40),
coverage_begin DATE,
coverage_term NUMBER,
CONSTRAINT  pk_insured_autos PRIMARY KEY (policy_id,vin)
USING INDEX TABLESPACE  index
STORAGE (INITIAL 1M NEXT 10M PCTINCREASE 0)
);


禁用或刪除主鍵必須與ALTER TABLE 語句一塊兒使用

ALTER TABLE policies DROP PRIMARY KEY;


ALTER TABLE policies DISABLE PRIMARY KEY;


外部鍵約束(Foreign key constraint)

  外部鍵約束保護一個或多個數據列,保證每一個數據行的數據包含一個或多個null值,或者在保護的數據列上同時擁有主鍵約束或惟一性約束。引用(主鍵或惟一性約束)約束能夠保護同一個表,也能夠保護不一樣的表。與主鍵和惟一性約束不一樣外部鍵不會隱式創建一個B-tree索引。在處理外部鍵時,咱們經常使用術語父表(parent  table)和子表(child table),父表表示被引用主鍵或惟一性約束的表,子表表示引用主鍵和惟一性約束的表。

  建立外部鍵使用CREATE TABLE語句,若是表已經創建了,那麼使用ALTER TABLE語句。

CREATE TABLE insured_autos
(policy_id NUMBER CONSTRAINT  policy_fk
REFERENCE policies(policy_id
ON DELETE CASCADE,
vin  VARCHAR2(40),
coverage_begin DATE,
coverage_term NUMBER,
make  VARCHAR2(30),
model VARCHAR(30),
year NUMBER,
CONSTRAIN auto_fk FROEIGN  KEY (make,model,year)
REFERENCES automobiles (make,model,year)
ON DELETE  SET NULL
);


ON DELETE子串告訴ORACLE若是父紀錄(parent  record)被刪除後,子記錄作什麼。缺省狀況下禁止在子記錄還存在的狀況下刪除父紀錄。

  外部鍵和NULL值

  在外部鍵約束保護的數據列中NULL值的處理可能產生不可預料的結果。ORACLE 使用ISO standar Match  None規則加強外部鍵約束。這個規則規定若是任何外部鍵做用的數據列包含有一個NULL值,那麼任何保留該鍵的數據列在父表中沒有匹配值。

  好比,在父表AUTOMOBILES中,主鍵做用於數據列MAKE,MODEL,YEAR上,用戶使用的表INSURED_AUTOS有一個外部約束指向AOTOMOBILES,注意在INSURES_AUTOS中有一數據行的MODEL列爲NULL值,這一行數據已經經過約束檢查,即便MAKE列也沒有顯示在父表AUTOMOBILES中,以下表:

  表1 AUTOMOBILES

MAKE
MODEL
YEAR

Ford  
Taurus
2000

Toyota
Camry
1999


表2 INSURED_AUTOS

POLICY_ID
MAKE
MODEL
YEAR

576
Ford
Taurus  
2000

577
Toyota
Camry
1999

578
Tucker  
NULL
1949


延遲約束檢驗(Deferred Constraint Checking)

  約束檢驗分兩種狀況,一種是在每一條語句結束後檢驗數據是否知足約束條件,這種檢驗稱爲當即約束檢驗(immediately  checking),另外一種是在事務處理完成以後對數據進行檢驗稱之爲延遲約束檢驗。在缺省狀況下Oracle約束檢驗是當即檢驗(immediately  checking),若是不知足約束將先是一條錯誤信息,但用戶能夠經過SET CONSTRAINT語句選擇延遲約束檢驗。語法以下:

SET CONSTRAINT constraint_name|ALL DEFEERRED|IMMEDIATE --;

相關文章
相關標籤/搜索