MySQL 數據完整性

數據庫實驗回顧sql

  1. 實體完整性數據庫

    實體完整性即主碼的屬性不能爲空。而主碼就可保證元組是不重複的,即主碼值是不能重複的。設計

  2. 參照完整性code

    參照完整性保證外碼的值要麼是被參照關係中的主碼值,要麼取空值。it

  3. 用戶自定義完整性table

    能夠按系統的需求設計各類自定義的完整性檢查。class

1、實體完整性

一、主鍵約束

主鍵(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;

2、參照完整性

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;

3、用戶自定義完整性

像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 ;

image-20201221175756723

附加

不用外鍵,而利用觸發器實現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 ;

image-20201221180203382

image-20201221180218115

相關文章
相關標籤/搜索