維護數據完整性

1、數據完整性規則:域完整性(Domain 欄位列)、實體完整性(Entity 實體行)、參照完整性(Reference)
數據完整性三種方式:a.使用應用代碼;b.觸發器trigger通過一段代碼(過程)滿足某個事件行爲或動作來驗證數據是否滿足數據完整性;c.約束條件Constraint作爲表結構編碼的一部分記錄在數據字典中,Oracle會自動維護規則。一般來說,優選使用約束條件來維護數據完整性。

2、約束的類型:NOT NULL 非空、UNIQUE 唯一性、PRIMARY KEY 主鍵、FOREIGN KEY 外鍵、CHECK 檢查條件
sql>alter table authors add constraint pk_1 primary key(au_id); //主鍵約束
sql>alter table authors add constraint uk_1 unique(au_lname,au_fname); //唯一性約束
sql>alter table stores add constraint pk_sales primary key(stor_id);
sql>alter table sales add constraint fk_sales foreign key(stor_id) references stores(stor_id);//外鍵約束
sql>alter table stores add constraint ck_stores_1 check(stor_name like 'B%'); //數據不滿足驗證條件
sql>input enable novalidate; //新數據生效,表中已經存在的數據不生效。

3、約束狀態(4種)
disable novalidate 新數據也不做驗證,原來數據也不做驗證
disable validate 新數據可以不做驗證,原來數據要滿足驗證
enable novavlidate 新數據做驗證,原來數據可以不做驗證。
enable validate (默認)新數據做驗證,舊數據也做驗證。

sql>alter table stores drop constraint ck_stores_1;
sql>alter table stores add constraint ck_stores_1 check(stor_name like 'B%') disable novalidate;
sql>alter table stores modify constraint ck_stores_1 enable;
sql>alter table stores modify constraint ck_stores_1 enable novalidate

sql>alter table sales add constraint ck_sales_1 check(qty>10);
sql>alter table sales add constraint ck_sales_1 check(qty>10) enable novalidate;

sql>update sales set qty=9 where stor_id =6380; //qty=9違反檢查約束條件
sql>c /9/11
sql>run //qty=11滿足檢查約束條件

4、約束檢查過程:DML statement -> Check nondefered (當數據通過DML語句改變時,立即進行約束條件檢查)->commit執行-> Check deferred constraints 延遲檢查約束
sql>alter table sales drop constraint ck_sales_1;
sql>alter table sales add constraint ck_sales_1 check(qty>10) enalbe novalidate;
sql>commit
sql>/
sql>alter table sales add constraint ck_sales_1 check(qty>8) initially deferred;
sql>update sales set qty=5 where stor_id=6380;
sql>commit; //error:事務處理已執行,違反檢查約束條件

sql>rollback; //事務已經執行必須rollback回滾。
sql>alter table sales modify constraint ck_sales_1 initially immediate; //DML語句就立即檢查驗證
sql>update sales set qty=5 where stor_id=6380; //違反檢查約束條件。

sql>alter session set constraints=deferred;
sql>update sales set qty=5 where stor_id=6380;// 已經更新2行

sql>alter session set constraints=immediate;
sql>update sales set qty=5 where stor_id=6380; //違反檢查約束條件。

5、主鍵和唯一性約束的狀態保持:
鍵是否可用?如果可用,就看看是否正在使用一個索引(否則不使用索引)?如果是,就判斷約束是否可以延遲(否則也判斷約束是否可以延遲,如果可以就創建nonunique index,否則就創建unique index)?如果可以,就看看是否索引是non-unique的(否則,使用已存在的索引)?如果否,則使用一個已存在的索引。

6、外鍵考慮因素:
a.刪除Drop主鍵表,Cascade constraints 清除約束條件
b.清空Truncate主鍵表,Disable or drop 外鍵
c.刪除Drop包含主鍵表的表空間,使用CASCADE CONSTRAINTS 清除約束條件
d.在子表執行DML時,確認表空間中包含主鍵表的鍵是在線狀態的。

sql>drop table stores cascade constraints;
sql>truncate table stores; //外鍵和主鍵有關係,無法清空
sql>alter table sales disable constraint fk_sales;
sql>truncate table stores; //再次清空就沒問題了。

7、當創建表時定義約束條件:
CREATE TABLE hr.employee(id NUMBER(7) CONSTRAINT employee_id_pk PRIMARY KEY
DEFERRABLE
USING INDEX
STORAGE(INITIAL 100K NEXT 100K)
TABLESPACE indx,
last_name VARCHAR2(25)
CONSTRAINT emplyee_last_name_nn NOT NULL,dept_id NUMBER(7))
TABLESPACE users;

//定義主鍵可以是可以延遲的,指定索引,索引可以指定存儲參數。

8、定義約束的規則:
主鍵和唯一性約束:主鍵和唯一性約束的索引放在一個獨立的表空間中;如果經常使用快加載即有大量數據載入的,使用nonunique indexes 非唯一性約束。
如何自己關聯外鍵的三種方式:
初始加載以後定義或使用外鍵、延遲約束檢查(數據插入在提交時驗證)、允許外鍵爲空

9、如何使約束可用:
(1)ENABLE NOVALIDATE (允許在運行過程中約束條件起作用,不要約束已經存在的表數據):表不加任何鎖、主鍵和唯一性鍵必須使用非唯一性索引。
ALTER TABLE hr.departments ENABLE NOVALIDATE CONSTRAINT dept_pk;

sql>alter table sales enable novalidate constraint ck_sales_1;

(2)ENABLE VALIDATE (默認。在運行過程中約束條件必須滿足條件,同樣也讓已經存在的數據進行驗證):鎖定表、可以使用唯一也可以用非唯一索引、表裏的數據必須是有效的。
ALTER TABLE hr.employees ENABLE VALIDATE CONSTRAINT emp_dept_fk;

假定表中加的值不滿足條件的話,就是用EXCEPTIONS Table
sql>alter table sales drop constraint ck_sales_1;
sql>alter table sales add constraint ck_sales_1 check(qty>15)
enable validate //違反檢查約束條件(因爲有一些違背了約束條件)
/

如何查找這些違背了約束條件的行並重新滿足約束條件呢?

處理過程:
a.使用utlexcpt.sql 腳本來創建EXCEPTIONS TABLE

b.ALTER TABLE ...EXCEPTIONS .. 接收違反了規則的數據
c.通過使用在EXCEPTIONS的子查詢來定位無效數據的行
d.糾正錯誤(DML)

e.重新執行ALTER TABLE 來使約束條件滿足。

sql>start d:\oracle\ora90\rdbms\admin\utlexcpt.sql
sql>alter table sales add constraint ck_sales_1 check(qty>15)
enable validate
exceptions into exceptions; //無法驗證-違反檢查約束條件
sql>select * from exceptions
/
sql>update sales set qty=16 where rowid in (select row_id from exceptions);
sql>commit
sql>/

sql>alter table sales add constraint ck_sales_1 check(qty>15)
enalbe validate
exceptions into exceptions; //重新執行,使違反檢查約束的數據也滿足約束條件。

9、獲取約束信息:
DBA_CONSTRAINTS\DBA_CONS_COLUMNS
select * from user_contraints; //查找用戶加的約束條件
select * from user_cons_columns; //查找主外鍵的方式


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章