數據庫一致性被破壞:
- 系統故障
- 許多用戶的并發訪問
- 人為破壞
- 事務本身不正確
保護數據庫一致性的方法:
- 視圖/查詢修改
- 訪問控制
- 普通用戶
- 擁有資源特權的用戶
- DBA
數據庫的安全問題
- 身份驗證
- 口令
- 物理設備
GRANT CONNECT TO John IDENTIFIED BY 123456;
GRANT SELECT on TABLES table-name TO user-name WITH GRANT OPTION
--with grant option 表示用戶具有將對這張表的操作權限轉給其他用戶的能力
- 角色
- 數據加密
- 審計追蹤
統計數據庫
個體追蹤器
通用追蹤器
完整性約束
每一個合法實例都必須滿足的條件
如果不滿足完整性約束,DBMS不會允許進入數據庫
- 靜態約束
- 數據模型固有的約束
- 隱含約束:域完整性約束、主鍵約束(實體完整性約束)、外鍵約束(引用完整性約束)
- 顯式約束
- 動態約束:數據庫在轉換過程中應該遵循的規則
靜態約束
當有引用完整性約束的時候,如果要刪除所引用的表中的元組,需要檢查該元組的主鍵是否在引用表的外鍵中出現,如果出現,有兩個選擇:
- 報錯(默認)
- 級聯刪除(需要進行設置)
引用完整性約束更新主鍵:
- 報錯(默認)
- 級聯更新
顯式約束
- 程序進行限制
- 使用DBMS斷言ASSERTION
ASSERT balanceCons ON account:balance>=0; //balanceCons是斷言的名字
- 使用
CHECK
:在建表的時候
CREATE TABLE Reserves
(sname CHAR(10),
bid INTEGER,
day DATE,
PRIMARY KEY (bid,day),
CONSTRAINT noInterlakeRes
CHECK('Interlake' <> (SELECT B.bnameFROM Boats BWHERE B.bid=bid)))
--規定名字為Interlake的船不能外借
如果牽涉到兩個以上的表的約束就不能在CREATE
語句中使用CHECK
,因為這樣只有對其中一個表進行增刪改的時候才會觸發CHECK
約束,如果不進行增刪改就沒法保持約束。應該使用斷言進行約束。
CREATE ASSERTION smallClub
CHECK
((SELECT COUNT(*) FROM Sailors) +
(SELECT COUNT(*) FROM Boats)<100)
可以保證在兩個表任何一個進行增刪改操作的時候都要滿足約束
動態約束+觸發器
主動數據庫:數據庫中的數據達到某種狀態的時候主動進行一些動作
觸發器:E(事件)C(檢查數據庫)A(動作)規則
--監視水手這張表,更新年輕水手表
CREATE TRIGGER youngSailorUpdate
AFTER INSERT ON Sailors -- ON 后面跟需要監視的表
--AFTER/BEFORE控制動作發生之前還是之后
--INSERT/DELETE/UPDATE 控制發生什么動作
REFERENCING NEW TABLE NewSailors
--NEW表示插入操作的新值,OLD表示老值
--TABLE表示把前面引用的值看作一張表
FOR EACH STATEMENT
--還可以是FOR EACH ROW 當操作涉及多個元組的時候可以分別進行不同的操作
--可以使用WHEN子句進行檢查
INSERT INTO YoungSailors VALUES SELECT * FROM NewSailors N WHERE N.age<=18
實現方法:
- 立即執行(常見)
- 延遲
- 分離
觸發器的連鎖觸發:
- 根據觸發圖,限制觸發器執行
- 連續觸發的次數進行限制
觸發器的定義需要小心,不能定義太多的觸發器
觸發器實現方法:
- 松耦合
- 緊耦合
- 嵌套