約束概述
對數(shù)據(jù)表中數(shù)據(jù)的限制條件叫表的約束,目的是為了保證表中記錄的完整和有效。例如非空、唯一等。
查看約束
1 通過查看建表語句 查看表中的約束
show create table tb_name;
2 通過檢查約束表 查看約束
select * from information_schema.table_constraints where table_name='usr';
Tips:在MySQL數(shù)據(jù)庫中 所有的約束都存放在information_schema.table_constraints表中~~~~參看~~~~~information_schema數(shù)據(jù)庫介紹
主鍵約束
什么是主鍵約束
在MySQL中主鍵是一種約束,也是一種索引。被設(shè)為主鍵的字段 要求 不重復(fù) 不能為空 不能缺省。主鍵的作用為唯一的確定表中的一條記錄。需要注意的是 當(dāng)主鍵是復(fù)合主鍵時(shí),不重復(fù)的含義是 組合起來不重復(fù)即可,單列值允許重復(fù),但不允許同時(shí)重復(fù)
創(chuàng)建主鍵
1 在字段中定義主鍵
create table if not exists user(
id int(11) auto_increment primary key,
name char(64) not null default 'No Name'
);
2 字段定義結(jié)束后定義主鍵
create table if not exists user(
id int(11) auto_increment,
name char(64) not null default 'No Name',
primary key(id,name)
);
-- 注意 聲明主鍵的完整格式應(yīng)該是這樣的
-- constraint 約束名 primary key key_name
3 建表完成后添加主鍵
上邊的兩種方式都是在創(chuàng)建表時(shí)候指定主鍵約束,也可以在表建成后添加主鍵約束
alter table tb_name add primary key(key_name)
-- tb_name 表名
-- primary key() 括號里填寫字段名,可以是一個(gè) 也可以是多個(gè)(復(fù)合主鍵)
刪除主鍵
-- 如果主鍵字段中包含有自增 auto_increment,需要先刪除自增屬性 在刪除主鍵
-- 如果沒有自增直接刪除主鍵即可
-- 刪除自增類型。 ?。。∽⒁?自增是類型 所以 可以使用 修改字段的類型就ok
--1 修改字段的名 修改后需要重新指定類型
alter table tb_name change col_name col_name int;
--2 簡單的直接修改類型
alter table tb_name modify col_name int;
-- 刪除掉 auto_increment屬性后可以刪除主鍵
alter table tb_name drop primary key;
主鍵的分類
1 單一主鍵
創(chuàng)建 1 中 創(chuàng)建的 id 就是單一的主鍵,需要注意,定義字段時(shí)聲明主鍵是無法創(chuàng)建復(fù)合主鍵的。
2 復(fù)合主鍵
創(chuàng)建 2 中的創(chuàng)建主鍵的方式 允許創(chuàng)建單一主鍵也允許創(chuàng)建復(fù)合主鍵,推薦使用這種方法進(jìn)行主鍵的創(chuàng)建。
3 聯(lián)合主鍵
當(dāng)處理多對多的關(guān)系時(shí),需要?jiǎng)?chuàng)建中間表來進(jìn)行多對多的關(guān)聯(lián),此時(shí)中間表的主鍵成為聯(lián)合主鍵,他能唯一的確定多對多的若干實(shí)體間的對應(yīng)關(guān)系。聯(lián)合主鍵也可以是復(fù)合主鍵即聯(lián)合主鍵由第三表的多個(gè)列復(fù)合而成。保持唯一。
外鍵約束
什么是外鍵
外鍵依托于具有唯一約束的字段,一般來講主鍵會多一些,但是也可以不是主鍵。前提是它們具有唯一約束。外鍵依賴的字段可以來自本(自參照表)也可以是其他表,一般的是其他表的情況多一些。此時(shí)要求 主表必須已經(jīng)存在于數(shù)據(jù)庫中,或者是當(dāng)前正在創(chuàng)建的表。如果被依賴字段在本表中,那么這樣的約束結(jié)構(gòu)稱為 自參照完整性。
Tips: 雖然主鍵不允許為空不允許重復(fù),但是外鍵可以為空,也可以重復(fù)。外鍵約束要求每一個(gè)值都來自于主鍵,特別的插入空值時(shí),MySQL不支持缺省,必須顯式表達(dá)出來,例如
insert into user(name,leader_id) values('monkey',null);
-- 顯示的寫出 null 否則 會報(bào)錯(cuò)
insert into user(name,leader_id) values('monkey');
-- 是不合法的語句
- 在父表的表名后面指定列名或列名的組合。這個(gè)列或列的組合必須是父表的主鍵或候選鍵。
- 外鍵中列的數(shù)目必須和父表的主鍵中列的數(shù)目相同。
- 外鍵中列的數(shù)據(jù)類型必須和父表主鍵中對應(yīng)列的數(shù)據(jù)類型相同。
創(chuàng)建外鍵
1 建表時(shí)創(chuàng)建外鍵
[constraint <fk_name>] foreign key(fk_col_name [,col_name2,…])
references <tb_name> (pk_col_name1 [,pk_col_name2,…])
-- fk_name 外鍵名
-- fk_col_name 設(shè)置外鍵字段的字段名
-- tb_name 外鍵關(guān)聯(lián)的主表表名
-- pk_col_name 主表被依賴的字段名
2 建表完成后創(chuàng)建
alter table tb_name add [constriant <fk_name>] foreign key(fk_name) references tb_name(pk_col_name)
-- fk_name 外鍵名
-- fk_col_name 設(shè)置外鍵字段的字段名
-- tb_name 外鍵關(guān)聯(lián)的主表表名
-- pk_col_name 主表被依賴的字段名
例子
-- 創(chuàng)建主表 leader
create table leader(
id int(11) primary key auto_increment,
name char(64) not null
);
-- 創(chuàng)建外鍵所在表 employee
create table employee(
id int(11) primary key auto_increment,
name char(64) not null,
leader_id int(11),
constraint fk_leader_employee foreign key(leader_id) references leader(id)
);
create table employee(
id int(11) primary key auto_increment,
tid char(11),
name char(64) not null,
leader_id int(11),
constraint fk_leader_employee foreign key(name) references leader(name)
);
注意
- 外鍵 和 關(guān)聯(lián)的主表字段類型必須一致,但是允許size不一致,但是這樣可能會出現(xiàn)無法預(yù)期的問題,不推薦這樣做,曾經(jīng)在使用django的ORM時(shí),手寫了migrations文件,導(dǎo)致出現(xiàn)類似情況,很大的坑。
- 外鍵字段可以是主表的多個(gè)字段(復(fù)合主鍵或者其他的情況都是被允許的,但是此時(shí)要保證關(guān)聯(lián)字段和被關(guān)聯(lián)字段要能對應(yīng)起來)
- 特別要說明的是,作為其他表外鍵的主表字段必須是具有唯一約束(主鍵字段原生就自帶 unique 屬性,如果不是主鍵,那必須要手動(dòng)的設(shè)置unique 當(dāng)是外鍵是多個(gè)字段時(shí),需要設(shè)置復(fù)合唯一)
刪除外鍵
同刪除主鍵類似,不同的是,每張表只有一個(gè)主鍵,因此不需要指定主鍵名,但是外鍵 外鍵名是不虛指定的。
alter table tb_name drop foreign key fk_name;
-- fk_name 外鍵約束名 也就是 constrain 后面的名字
唯一約束
什么是唯一約束
唯一約束就是要求字段中的值是唯一,特別的它允許為空,但只能出現(xiàn)一個(gè)空值。唯一約束可以確保一列不出現(xiàn)重復(fù)值,或者若干列不出現(xiàn)重復(fù)的組合。
創(chuàng)建唯一約束
1 字段定義時(shí)添加
create table leader(
id int(11) primary key auto_increment,
name char(64) unique,
);
-- name 字段唯一 ,不允許有重名的出現(xiàn)
2 字段定義完成后添加
create table leader(
id int(11) primary key auto_increment,
name char(64),
constraint uq_name unique key(name) -- 在這里寫唯一約束 與主鍵類似
);
注意
- 唯一約束和主鍵約束的區(qū)別在于主鍵中不許出現(xiàn)null 但是唯一 要求只能出現(xiàn)一個(gè)空值
- 一張表中可以有若個(gè)個(gè)唯一約束,但是只能存在一個(gè)主鍵約束
3 建表完成后添加
alter table tb_name add [constaint uq_name] unique key(uq_col_name)
-- tb_name 要修改的表名
-- uq_name 約束名<索引名>
-- uq_col_name 聲明唯一的字段名
-- 約束名 可以不寫
刪除唯一約束
alter table tb_name drop index fk_name;
-- tb_name 表名
-- fk_name 約束名<索引名>
默認(rèn)值約束和非空約束
default 應(yīng)該被稱為默認(rèn)值約束,他也是一種約束,作用和簡單,指定某字段的默認(rèn)值
創(chuàng)建默認(rèn)值約束
1 字段中定義默認(rèn)值/非空
create table user(
id int(11) auto_increment primary key,
age int(4) default 18,
name char(64) not null
);
2 表建成后添加
alter table tb_name change col_name col_type[size] default <默認(rèn)值>
-- 就是簡單的修改表的結(jié)構(gòu)語句
alter table user change col_name col_type[size] {default 默認(rèn)值 | not null | null }
刪除默認(rèn)值/非空約束
-- 修改表結(jié)構(gòu) 將默認(rèn)值 設(shè)置為null
alter table tb_name change col_name col_type[size] default null;
-- 或者
-- 修改表結(jié)構(gòu) 修改字段的類型
alter table tb_name modify col_name col_type[size];
檢查約束
MySQL不支持檢查約束,官方文檔上說,即使設(shè)置了檢查約束,但是mysql不會強(qiáng)制的要求這樣做。創(chuàng)建之后在information_schema.table_constraints 找不到相關(guān)的記錄。甚至他可能本身就不存在。
什么是檢查約束
檢查約束一般來說是為了滿足用戶實(shí)際的實(shí)體完整性而存在的。例如 身高應(yīng)該 high > 10 and high < 280
創(chuàng)建檢查約束
1 創(chuàng)建表時(shí)添加
check <約束條件>
-- 例子
create table userinfo(
id int(11) auto_increment primary key,
high int(4) default 160,
weight int(4) default 50,
check(heigh > 10 and heigh < 280)
);
2 創(chuàng)建完成后添加
alter table userinfo add constraint check_name check(約束條件)
-- 例如
alter table userinfo add constraint check_weight check(weight > 10 and weight < 300);
刪除檢查約束
alter table tb_name drop constraint check_name;
-- 例如
alter table userinfo drop constraint check_weight;
-- 值得注意的是,mysql 雖然說創(chuàng)建成功了,但是在information_schema 數(shù)據(jù)庫的 table_constraints 表中并不能找到相關(guān)的信息。MySQL不支持檢查約束。
|