數據庫實驗回顧sql
實體完整性數據庫
實體完整性即主碼的屬性不能爲空。而主碼就可保證元組是不重複的,即主碼值是不能重複的。設計
參照完整性code
參照完整性保證外碼的值要麼是被參照關係中的主碼值,要麼取空值。it
用戶自定義完整性table
能夠按系統的需求設計各類自定義的完整性檢查。class
主鍵(promary key)用於惟一的標識表中的某一條記錄,在兩個表的關係中,主鍵用來在一個表中引用來自另外一個表中的特定記錄。一個表的主鍵能夠由多個關鍵字共同組成,而且主鍵的列不能包含空值。主鍵的值能惟一標識表中的每一行,這就比如全部人都有身份證,每一個人的身份證號是不一樣的,能惟一標識每個人。原理
添加主鍵date
ALTER TABLE 表名 ADD PRIMARY KEY(列名);
設置主鍵select
ALTER TABLE orders ADD PRIMARY KEY(列名);
在建立表的時候,設置主鍵
-- 單個字段的主鍵 CREATE TABLE 表名( 字段名 數據類型 PRIMARY KEY ); -- 多個字段組合的主鍵 CREATE TABLE 表名( 字段名1 數據類型, 字段名2 數據類型, ..... PRIMARY KEY(字段名1, 字段名2, 字段名n) );
惟一約束用於保證數據表中字段值的惟一性,在 MySQL 中使用 UNIQUE 關鍵字添加惟一約束。在建立表時爲某個字段添加惟一約束的具體語法格式以下:
CREATE TABLE 表名( 字段名 數據類型 UNIQUE, .... );
注意:被定義成惟一約束的字段,字段值不能相同。可是能夠爲 NULL。
惟一約束也能夠添加到已經建立完成的表中,語法格式以下:
ALTER TABLE 表名 ADD UNIQUE(列名);
數據表中的 id 字段通常從1開始插入,不斷增長,每次插入新數據時,都要添加一個 id 字段的值,當數據內容龐大時,容易出錯。爲了解決這個問題,能夠將 id 字段的值設置爲自動增長。在 MySQL 中使用 AUTO_INCREMENT 關鍵字設置表字段值自動增長。在建立表時將某個字段的值設置爲自動增加,語法格式以下:
CREATE TABLE 表名( 字段名 數據類型 AUTO_INCREMENT, .... );
此外,也能夠爲已經建立完成的表字段設置自動增加列,語法格式以下:
ALTER TABLE 表名 MODIFY 字段名 數據類型 PRIMARY KEY AUTO_INCREMENTL;
MySQL參照完整性通常是經過MySQL外鍵(foreign key)實現的
刪除參照約束
ALTER 表 DROP FOREIGN KEY fg_fk;
給現有表增長參照約束
ALTER TABLE`score`ADD CONSTRAINT`score_fk2`FOREIGN KEY (`sid`) REFERENCES`student`(`sid`);
數據庫系統的外鍵值更新模式通常有3種:
默認的外鍵管理是Restict,即限制方式。前面實驗咱們已經見識了這種方式的做用。
CASCADE,即級聯方式,能夠理解爲株連九族,即主鍵改變後,引用它的外鍵值自動改變成新主鍵值來保證參照完整性。
SET NULL,置空,即主鍵值改變後,引用它的外鍵值自動改成NULL來保證參照完整性。
eg
alter table 表名 add constraint fk_js foreign key(任課教師編號) references teacher (工號) on update cascade;
像MS SQL Server等數據庫管理系統有CHECK約束能夠很方便地實現用戶自定義完整性約束。但MySQL沒有提供真正的CHECK約束。但用戶自定義約束的原理都差很少,經過觸發器就能夠實現。
例如:學生年齡不能取負值的約束
-- insert 觸發器 年齡不能爲負 delimiter ; delimiter $$ create trigger st_ins_chk_age before insert on student for each row begin if new.年齡 is not NULL and new.年齡 < 0 then signal sqlstate 'HY000' set message_text = "年齡不能爲負"; end if; end$$ -- update 觸發器 年齡不能爲負 delimiter ; delimiter $$ create trigger st_up_chk_age before update on student for each row begin if new.年齡 is not NULL and new.年齡 < 0 then signal sqlstate 'HY000' set message_text = "年齡不能爲負"; end if; end$$ delimiter ;
不用外鍵,而利用觸發器實現socre的課號要級聯參照course中的課號?
score 表
-- 觸發器 實現 score 外鍵 學號 參照 student 學號 -- score delimiter ; delimiter $$ create trigger sc_fk_ins_xh before insert on score for each row begin if (select count(*) from student where 學號=new.學號)=0 and new.學號 is not NULL then signal sqlstate 'HY000' set message_text = "Cannot add or update a child row: a foreign key constraint ..."; end if; end$$ create trigger sc_fk_up_xh before update on score for each row begin if (select count(*) from student where 學號=new.學號)=0 and new.學號 is not NULL then signal sqlstate 'HY000' set message_text = "Cannot add or update a child row: a foreign key constraint ..."; end if; end$$ delimiter ;
注意:score 中是 new ,student 中是 old
student 表
-- 觸發器 實現 score 外鍵 學號 參照 student 學號 -- student delimiter ; delimiter $$ create trigger st_del_xh before delete on student for each row begin if (select count(*) from score where 學號=old.學號)>0 then signal sqlstate 'HY000' set message_text = "Cannot delete or update a child row: a foreign key constraint ..."; end if; end$$ create trigger st_up_xh before update on student for each row begin if (select count(*) from score where 學號=old.學號)>0 then signal sqlstate 'HY000' set message_text = "Cannot delete or update a child row: a foreign key constraint ..."; end if; end$$ delimiter ;