Oracle約束Constraints
阿新 • • 發佈:2019-02-20
資料庫中的六大約束主鍵約束(Primary Key Constraint) 唯一約束 (Unique Constraint)非空約束(Not Null Constraints)外來鍵約束 (Foreign Key Constraint)
檢查約束 (Check Constraint) 預設約束 (Default Constraint)
檢查約束 (Check Constraint) 預設約束 (Default Constraint)
主鍵約束(PRIMARY KEY)
主鍵是定位表中單個行的方式,可唯一確定表中的某一行,關係型資料庫要求所有表都應該有主鍵,不過Oracle沒有遵循此範例要求,Oracle中的表可以沒有主鍵(這種情況不多見)。關於主鍵有幾個需要注意的點:- 鍵列必須必須具有唯一性,且不能為空,其實主鍵約束 相當於 UNIQUE+NOT NULL
- 一個表只允許有一個主鍵
- 主鍵所在列必須具有索引(主鍵的唯一約束通過索引來實現),如果不存在,將會在索引新增的時候自動建立
SQL> alter table emp add constraint emp_id_pk primary key(id);
唯一性約束(UNIQUE)
唯一性約束可作用在單列或多列上,對於這些列或列組合,唯一性約束保證每一行的唯一性。 UNIQUE需要注意:- 對於UNIQUE約束來講,索引是必須的。如果不存在,就自動建立一個(UNIQUE的唯一性本質上是通過索引來保證的)
- UNIQUE允許null值,UNIQUE約束的列可存在多個null。這是因為,Unique唯一性通過btree索引來實現,而btree索引中不包含null。當然,這也造成了在where語句中用null值進行過濾會造成全表掃描。
SQL> alter table emp add constraint emp_code_uq unique(code);
非空約束(NOT NULL)
非空約束作用的列也叫強制列。顧名思義,強制鍵列中必須有值,當然建表時候若使用default關鍵字指定了預設值,則可不輸入。
新增非空約束,語法較特別
SQL> alter tableemp modify ename not null;
外來鍵約束(FOREIGN KEY)
外來鍵約束定義在具有父子關係的子表中,外來鍵約束使得子表中的列對應父表的主鍵列,用以維護資料庫的完整性。不過出於效能和後期的業務系統的擴充套件的考慮,很多時候,外來鍵約束僅出現在資料庫的設計中,實際會放在業務程式中進行處理。外來鍵約束注意以下幾點:
- 外來鍵約束的子表中的列和對應父表中的列資料型別必須相同,列名可以不同
- 對應的父表列必須存在主鍵約束(PRIMARY KEY)或唯一約束(UNIQUE)
- 外來鍵約束列允許NULL值,對應的行就成了孤行了
其實很多時候不使用外來鍵,很多人認為會讓刪除操作比較麻煩,比如要刪除父表中的某條資料,但某個子表中又有對該條資料的引用,這時就會導致刪除失敗。我們有兩種方式來優化這種場景:
第一種方式簡單粗暴,刪除的時候,級聯刪除掉子表中的所有匹配行,在建立外來鍵時,通過 on delete cascade 子句指定該外來鍵列可級聯刪除:
SQL> alter table emp add constraint emp_deptno_fk foreign key(deptno) references dept (deptno) on delete cascade;
第二種方式,刪除父表中的對應行,會將對應子表中的所有匹配行的外來鍵約束列置為NULL,通過 on delete set null 子句實施:
SQL> alter table emp add constraint emp_deptno_fk foreign key(deptno) references dept(deptno) on delete set null;
實際上,外來鍵約束列和對應的父表列可以在同一張表中,常見的就是表的業務邏輯含義是一棵樹,最簡單的例子如下(id為主鍵id,fid為父id,fid儲存對id的引用),這種結構的表根據業務要求可通過Oracle的遞迴查詢來獲取這種層級關係
檢查約束(CHECK)
檢查約束可用來實施一些簡單的規則,比如列值必須在某個範圍內。檢查的規則必須是一個結果為true或false 的表示式,比如:
SQL> alter table emp add constraint emp_sex_ck check(sex in('男','女'));
SQL> alter table test31 add constraint chkk check (sex ='男' or sex='女');
SQL> alter table test34 add constraint ch_test34 check(age>0 and age<120);
SQL> alter table test34 add constraint ch_test34 check(age between 12 and 30); --在一個範圍中間
SQL> alter table test36 add constraint ch_test36 check(length(password)=6); --長度大於某個值
SQL> alter table test36 add constraint email check (email like '%@%'); --電子郵箱要含有@符號
SQL> alter table test36 add constraint password check((password like '00[0-9][0-9]/_[a-z,A-Z][a-z,A-Z][a-z,A-Z]%' escape '/')and(length(password)=8) )