爲了規範數據格式, 在用戶進行插入、修改、刪除等操做時,DBMS(數據庫管理系統(Data Base Management System))自動按照約束條件對數據進行監測, 使不符合規範的數據不能進入數據庫, 以確保數據的完整性和惟一性python
表完整性約束條件與字段數據類型的寬度同樣, 都是可選參數,分爲如下幾種:mysql
完整性約束關鍵字 | 含義 |
---|---|
NULL | 標識字段值能夠爲空 |
NOT NULL | 約束字段值不爲空 |
DEAFAULT | 設置字段值爲默認值 |
UNIQUE KEY(UK) | 約束字段的值惟一 |
PRIMARY KEY(PK) | 設置字段爲表的主鍵 |
FOREIGN KEY(FK) | 設置字段爲表的外鍵 |
AUTO_INCREAMENT | 約束字段的值爲自動遞增 |
UNSIGNED | 無符號 |
AEROFILL | 使用 0 填充 |
create table t04(id int); insert t04 value(); # values() 也能夠 value() insert t04 value(null); # 而且 into 能夠省略 insert t04 value(1);
create table t05(name char(16) not null); insert t05 value(); insert t05 value(null); insert t05 value("shawn");
create table t06(name char not null default "shawn"); insert t06 value(); insert t06 value(null); create table t07(name char not null dafault null); # 直接報錯
create table t07(id int unique,name char(16)); insert t07 value(1,"shawn"),(2,"song"); insert t07 value(1,"xing"); # 報錯提示重複
create table t08(id int,ip varchar(16),port int,unique(ip,port)); # ip + port 聯合單個能夠重複, 聯合不能相同 insert t08 value(1,"127.0.0.1",8090); insert t08 value(2,"127.0.0.1",8091); insert t08 value(3,"127.0.0.1",8090); # 聯合與id爲1的相同, 報錯
主鍵約束(primary key)sql
ps : InnoDB引擎表是基於B+樹的索引組織表(IOT)(自行百度)數據庫
create table t09(id int primary key); # 設置主鍵 insert t09 value(1),(2); insert t09 value(null); # 插入 null 報錯 insert t09 value(1); # 插入id 1 報錯 insert t09 value(2); # 插入id 2 也報錯
create table t10( id int not null unique, # 設置 id 字段不爲空,且惟一 name char(16) not null, age int, sex char(3) not null ); desc t10; # 查看錶結構
create table t11( id int primary key, name varchar(16) ); desc t11;
create table t12( ip varchar(16), port int, primary key(ip,port) # 設置 IP + port 聯合主鍵 ); insert t12 value("127.0.0.1",8090); insert t12 value("127.0.0.1",8091); # 單個字段能夠相同 insert t12 value("127.0.0.1",8090); # 連個字段不能相同, 報錯
create table t13( id int primary key auto_increment, name varchar(16) ); insert t13(name) value("shawn"),("xing");
insert t13 value(7,"xing"),(9,"hai");
insert t13(name) value("hello"); # 再次不指定 id
🍓"delete"刪除表再插入記錄演示 delete from t13; insert t13(name) value("shawn");
🍓"truncate"清空表再插入記錄演示 insert t13(name) value("song"),("hai"),("xing"); # 先插入幾條記錄 truncate t13; insert t13(name) value("aaa"),("bbb"),("ccc"); # 再次插入記錄
alter table t13 auto_increment=18; insert t13(name) value("ddd"),("eee"),("fff"); select * from t13;
create table t14( id int primary key auto_increment, name varchar(16), sex enum("male","female") default "male" )auto_increment=5; # 初始值的設置爲表選項,應該放到括號外 insert t14(name) value("aaa"),("bbb"),("ccc");
ps : 得出表關係結論須要雙向進行觀察對比 (固然沒有關係也是一種關係數據結構
)測試
從上面的表中咱們不難發現缺點(以上只演示了7個員工, 假設有一萬個員工) :優化
- 部門名和職能說明重複, 浪費磁盤空間
- 組織結構不是很清晰
- 數據的擴展性差 (重點)
表已經抽離成功, 咱們使用 dep_id 將兩個表創建聯繫設計
正常來講, 一個員工只能對應一個部門, 一個部門能夠包含多個員工code
結論 : 員工表與部門表是 一對多(或多對一) 的關係索引
- 一對多關係表, 外鍵關鍵字設置在多的一方(emp)
- 在建表時, 需先創建被關聯的表(主表)(dep), 否則先建立附表會報錯
- 插入數據時, 必須先往被關聯的表(主表)插入(dep)
語法 :
foreign key([子表字段]) references [主表名]([主表字段])
🍓先建立被關聯的表(主表)(dep) create table dep( id int primary key auto_increment, dep_name varchar(16), dep_dec varchar(50) ); insert dep(dep_name,dep_dec) value ("銷售部","銷售公司產品"), ("採購部","採購公司所需原材料"), ("售後部","爲客戶提供售後服務"); # 插入部門數據 🍓再建立附表(子表)(emp) create table emp( id int primary key auto_increment, emp_name varchar(16), emp_age int, dep_id int, foreign key(dep_id) references dep(id) ); insert emp(emp_name,emp_age,dep_id) value ("派大星",22,2),("章魚哥",32,2), ("蟹老闆",34,1),("海綿寶寶",23,3), ("珍妮",18,1),("痞老闆",54,3), ("珍珍",25,2); # 插入員工數據
update dep set id=100 where id=1; # 報錯 update emp set dep_id=200 where dep_id=2; # 報錯
delete from dep where id=2; # 報錯 delete from emp where id=4; # 能夠刪除成功
on update cascade
), 同步刪除(on delete cascade
)🍓新建一個子表,並設置級聯(emp2) create table emp2( id int primary key auto_increment, emp2_name varchar(16), emp2_age int, dep_id int, foreign key(dep_id) references dep(id) on delete cascade on update cascade ); insert emp2(emp2_name,emp2_age,dep_id) value ("派大星",22,2),("章魚哥",32,2), ("蟹老闆",34,1),("海綿寶寶",23,3), ("珍妮",18,1),("痞老闆",54,3), ("珍珍",25,2); # 插入員工數據
drop table emp; # 測試以前先刪除 emp 表,以避免受影響 update dep set id=100 where id=1; # 將主表 id 爲 1 的改成 100 update emp2 set dep_id=300 where dep_id=3; # 子表沒法更新外鍵(報錯)
delete from dep where id=100; # 刪除 id 爲 100 的記錄(銷售部門) select * from emp2; # 查看 emp2 受到的影響
是否左表的多條記錄能夠對應右表的一條記錄,若是是,則證實左表的一個字段能夠 foreign key 右表一個字段(一般是id)
是否右表的多條記錄能夠對應左表的一條記錄,若是是,則證實右表的一個字段能夠 foreign key 左表一個字段(一般是id)
多對一 : 若是隻有步驟1成立,則是左表多對一右表, 若是隻有步驟2成立,則是右表多對一左表
多對多 : 若是步驟1和2同時成立,則證實這兩張表時一個雙向的多對一,即多對多,須要定義一個這兩張表的關係表(中間表)來專門存放兩者的關係
一對一 : 若是1和2都不成立,而是左表的一條記錄惟一對應右表的一條記錄,反之亦然, 這種狀況很簡單,就是在左表foreign key右表的基礎上,將左表的外鍵字段設置成unique便可
上面的"員工表(emp)"與"部門表(dep)"就是多對一的關係
場景演示 : 做者和書的對應關係
對應關係 : 一個做者能夠寫多本書, 一本書也能夠對應多個做者(合著) , 雙向的一對多,即多對多
關聯方式 : 設置外鍵(froeign key), 並使用一張中間表創建兩表的聯繫
設計思路 : 建立一張中間表(au_bo), au_bo的一個id對應多個圖書表(book)的id, 也對應做者表(author)的多個id, 反過來則是多對一, 因而咱們就能夠在au_bo表內設置兩個外鍵foreign key 來分別關聯book表的id和author表的id
🍓先建立"book"和"author"兩張表,並插入值 create table book( id int primary key auto_increment, title varchar(30) not null, price float(10,2) not null ); insert book(title,price) value ("《蟹堡祕籍》",1000.5),("《菠蘿房建成手冊》",5000.25), ("《章魚哥做息日記》",2000),("《派大星哲學》",15000); create table author( id int primary key auto_increment, name varchar(16) not null, age int not null ); insert author(name,age) value("海綿寶寶",35),("派大星",34); 🍓再建立中間表"au_bo", 並設置外鍵創建聯繫 create table au_bo( id int primary key auto_increment, book_id int not null, author_id int not null, foreign key(book_id) references book(id) # 設置外鍵 on update cascade on delete cascade, # 設置級聯更新和刪除 foreign key(author_id) references author(id) # 設置外鍵 on update cascade on delete cascade # 設置級聯更新和刪除 ); insert au_bo(book_id,author_id) value(1,1),(1,2),(2,1),(3,1),(3,2),(4,2); select * from book; select * from author; select * from au_bo;
場景演示 : 一我的要去公司入職一個部門, 入職後就是員工, 部門對應的這我的是惟一的, 不可能有兩個如出一轍的人, 而這名員工對應的就這一個部門, 還好比一張身份證對應一我的
注意 : 必定得保證設置外鍵的字段惟一, 外鍵健在哪一方均可以, 建議建在查詢頻率較高的表中
🍓建立"people"表,並插入內容 create table card( id int primary key auto_increment, phone int not null, ID_card varchar(19) not null ); insert card(phone,ID_card) value (458796,"3675454567855544555"), (784555,"3732458220113245979"), (458755,"2332214578621525545"); 🍓建立"card"表,並插入內容 create table people( id int primary key auto_increment, name varchar(16) not null, sex enum("male","female") default "male", card_id int not null unique, foreign key(card_id) references card(id) on update cascade on delete cascade ); insert people(name,sex,card_id) value ("shawn","male",1), ("song","female",2), ("xing","male",3); select * from people; select * from card;
---end---