1. 程式人生 > >MySQL從刪庫到跑路_高階(一)——資料完整性

MySQL從刪庫到跑路_高階(一)——資料完整性

 

作者:天山老妖S

連結:http://blog.51cto.com/9291927

 

一、資料完整性簡介

1、資料完整性簡介

資料冗餘是指資料庫中存在一些重複的資料,資料完整性是指資料庫中的資料能夠正確反應實際情況。

資料完整性是指資料的可靠性和準確性,資料完整性型別有四種:

A、實體完整性:實體的完整性強制表的識別符號列或主鍵的完整性(通過唯一約束,主鍵約束或標識列屬性)。

B、域完整性:限制類型(資料型別),格式(通過檢查約束和規則),可能值範圍(通過外來鍵約束,檢查約束,預設值定義,非空約束和規則)。

C、引用完整性:在刪除和輸入記錄時,引用完整性保持表之間已定義的關係。引用完整性確保鍵值在所有表中一致,不能引用不存在的值。如果一個鍵。

D、定義完整性:使用者自己定義的業務規則,比如使用觸發器實現自定義業務規則。

2、資料完整性實現方式

MySQL不支援Check約束,雖然可以在列上新增check約束,但不起作用。

二、實體完整性實現

1、實體完整性的實現簡介

實體完整性的實現有兩種方式:

A、主鍵約束:一張表只能有一列設定主鍵,值必須唯一,不允許為空,innoDB儲存引擎,主鍵就是索引。

B、唯一值約束:一張表可以有多個列新增唯一值約束,一直允許一條記錄為空值。

實體完整性,由主鍵和唯一性約束來實現,確保表中記錄有一列唯一標識。主鍵又分為Primary key和AUTO_INCREMENT PRIMARY KEY兩種。

2、主鍵

MySQL的主鍵名總是PRIMARY,當建立主鍵約束時,如果表的儲存引擎是innoDB,系統預設會在所在的列和列組合上建立對應的唯一索引,

主鍵約束相當於唯一約束與非空約束的組合,主鍵約束列不允許重複,也不允許出現空值;多列組合的主鍵約束,列都不允許為空值,並且組合的值不允許重複。每個表最多隻允許一個主鍵,建立主鍵約束可以在列級別建立,也可以在表級別上建立。

A、建立表時指定主鍵

建立表時指定主鍵的方式一:

create table product
 (
 productID int PRIMARY KEY,
 pName VARCHAR(10),
 price DOUBLE
 )ENGINE=MyISAM default CHARSET=utf8;

建立表時指定主鍵的方式二:

create table product
 (
 productID int,
 pName VARCHAR(10),
 price DOUBLE, CONSTRAINT pk_s_productID PRIMARY KEY(productID)
 )ENGINE=MyISAM default CHARSET=utf8;

在指定主鍵的表中插入記錄時,不允許插入重複ID,如果不指定主鍵的值,預設為0。

MylSAM型別的儲存引擎不會在主鍵列上建立索引,表中記錄的儲存順序與插入順序相同。

InnoDB儲存引擎會自動在主鍵列上建立索引,插入的記錄會根據主鍵的值的順序排放。

alter table product ENGINE=InnoDB;

B、增加主鍵

alter table TStudent add primary key(studentid);

C、刪除主鍵

alter table TStudent drop primary key;

3、自增主鍵

AUTO_INCREMENT PRIMARY KEY

如果不指定主鍵值,會自動在現有的主鍵值的最大值上自動增加1作為新記錄的主鍵,主鍵值預設從1開始。可以在資料資料型別整數型的列上新增自增主鍵。

A、建立表時指定自增自增列

create table product
 (
 productID int PRIMARY KEY AUTO_INCREMENT not NULL,
 pName VARCHAR(10),
 price DOUBLE
 )ENGINE=MyISAM default CHARSET=utf8;

B、為現有的表指定自增列

alter table TStudent modify column studentID int PRIMARY KEY AUTO_INCREMENT;

C、刪除表中自增列

alter table TStudent modify column studentID int not NULL;

刪除自增列,仍然時主鍵,但是沒有自增長功能

4、複合主鍵

使用表的兩列或多列建立主鍵。

A、建立表時指定複合主鍵

create table student
 (
 studentID int, id INT,
 sname VARCHAR(10),
 score int,
 PRIMARY KEY(studentid,id)
 )ENGINE=MyISAM default CHARSET=utf8;

B、給表增加複合主鍵

alter table student add PRIMARY KEY(studentID,id);

C、刪除複合主鍵

alter table student drop PRIMARY KEY;

5、唯一約束

UNIQUE KEY,唯一約束,指定某列和幾列組合的資料不能重複。

A、建立表時指定唯一性約束

create table score
 (sname VARCHAR(10) UNIQUE,
 score int not NULL
 );

B、給現有列增加唯一性約束

alter table score add CONSTRAINT us_sname UNIQUE(sname);

如果表中現有記錄有重複值,不允許新增唯一性約束。可以通過聚合函式,查詢有重複的記錄,刪除,再建立唯一性約束。

C、建立複合唯一性索引

create table student
 (
 studentID int, id INT,
 sname VARCHAR(10),
 score int, CONSTRAINT uc_id UNIQUE(studentID, id)
 )ENGINE=MyISAM default CHARSET=utf8;

D、刪除列的唯一性約束

alter table score drop index uc_sname;

三、域完整性

1、預設值

在表中插入一條新1的記錄時,如果沒有為該欄位賦值,那麼資料庫系統會自動為該欄位賦一條預設值。

create table st
(sid INT not null primary key auto_increment,
sname varchar(10),
subject varchar(20) default '軟體工程',
entertime TIMESTAMP default now()
);

給表中一列新增預設值約束:

alert table st modify column subject VARCHAR(20) default '電腦科學與技術';

刪除表中一列的預設值約束:

alert table st modify column subject VARCHAR(20) default NULL;

2、建立非空約束

非空約束用於確保當前列的值不為空值,非空約束只能出現在表物件的列上。

Null型別特徵:所有的型別的值都可以是null,包括int、float等資料型別 空字串是不等於NULL,0也不等於NULL。

A、建立表時給列指定非空約束

create table score
 (sname VARCHAR(10) not NULL,
 score int not NULL
 );

B、給指定列指定非空約束

alert table score modify column score int not NULL;

C、刪除非空約束

alter table score modify column score int;

3、檢查check

check關鍵字,在插入新行或者更改已有行時才起作用,作用是阻止不滿足條件的值進入該列,對null值無效,因為插入null就相當於沒有插入。一個列可有多個check。

age int check(age between 10 and 20);

目前MySQL不支援check約束,微軟MSSQL支援Check約束,但建立表時可以指定Check約束,但不起作用。

四、參照完整性

1、參照完整性簡介

MySQL參照完整性一般是通過MySQL外來鍵(foreign key)實現的。

外來鍵(僅innoDB支援)所引用表的列必須是主鍵。

外來鍵宣告包括三個部分:

A、哪個列或列組合是外來鍵

B、指定外來鍵參照的表和列

C、參照動作[cascade(級聯操作),restrict(拒絕操作),set null(設為空),no action,set default]。

如果外來鍵約束指定了參照動作,主表記錄做修改,刪除,從表引用的列會做相應修改,或不修改,拒絕修改或設定為預設值。

引用表的列名必須是主鍵,且在刪除引用表時必須刪除引用關係或者刪除當前表。

2、建立表時指定外來鍵

建立兩張表,學生表student和成績表score,成績表的sid列的取值參照學生表(學生表student的sid列設定為主鍵,且表的儲存引擎為innodb,成績表score的儲存引擎也必須設定為innodb)。

create table student
(sid int not null primary key,
sname varchar(20)
) engine=innodb;create table score
(sid int not null,
mark INT,constraint score_fk FOREIGN KEY (sid)references student(sid) on delete cascade on update cascade) engine=innodb;

在學生表插入一條記錄

insert into student values (1,'孫悟空')

在成績表插入一條記錄,學號是1,成功。

instert into score values (1,98)

在成績表插入一條記錄,學號是2,失敗。

insert into score values (2,88)

在學生表插入學號是2的一條記錄

insert into student values (2,'唐僧')

再在成績表插入一條學號是2的記錄,成功,證明外來鍵參照成功。

insert into score values (2,88);

3、刪除參照約束

alter table score drop foreign key score_fk;

4、給現有表增加參照約束

alter table score add constraint score_fk2 foreing key (sid) references student (sid);

5、驗證級聯動作刪除和更新

在score表建立的參照完整性,刪除動作和更新動作的參照動作選擇了cascade(級聯操作),當學生表的sid更新時,分數表score的相應的sid也會更新,當學生被刪除,分數表對應的sid的記錄也會自動刪除。

更新學生表學號是1的學生的學號為10

update student set sid = 10 where sid = 1

檢視成績表,可以看到以前學號是1的已經變成了10

select * from score

刪除學生表學號是2的學生

delete from student where sid = 2

可以看到成績表,該學生的成績已經級聯刪除

select * from score

6、驗證級聯動作No Aaction

級聯動作設定為NO ACTION,如果子表中有匹配的記錄,則不允許對父表對應候選鍵進行update/delete操作。

Restrict動作同no action,都是立即檢查外來鍵約束。

將參照動作設定為no action,如果成績表score有該學生sid,將不能更改學生表student表的學生sid列,也不能刪除該學生。除非你先刪除該學生的成績,再刪除該學生。

刪除score表的外來鍵約束

alter table score drop foreign key score_fk;

增加score表的sid列外來鍵約束

ALTER TABLE `score` ADD CONSTRAINT `score_fk` FOREIGN KEY (`sid`) REFERENCES `student` (`sid`) ON DELETE NO ACTION ON UPDATE NO ACTION;

更新學號是10的學生的學號,失敗

update student set sid = 11 where sid = 10

刪除學號是10的學生,失敗

delete from student where sid = 10

需要先刪除學生成績表中的記錄,再刪除該學生。

delete from student where sid=10delete from score where sid=10;

7、驗證級聯動作Set NULL

在父表上update/delete記錄時,將子表上匹配記錄的列設為null,要注意子表的外來鍵不能為not null。

刪除成績表的外來鍵約束

alter table score drop foreign key score_fk;

增加成績表的sid列外來鍵約束,參照動作為set null

alter table score add constraint score_fk foreign key (sid) references student (sid) on delete set null on update set null;

修改成績表的sid列預設值為NULL

ALTER TABLE `score` MODIFY COLUMN `sid` INTEGER(11) DEFAULT NULL;insert into student values (1,'孫悟空')insert into student values (2,'豬八戒')insert into score values (1,98)insert into score values (2,88)

刪除學生表中學號1的學生

delete from student where sid = 1

檢視成績表,成績表中的學號為1的列為NULL

select * from score

 

喜歡的小夥伴們可以搜尋我們個人的微信公眾號“程式設計師的成長之路”點選關注或掃描下方二維碼