MySQL資料庫——從入門到刪庫跑路(三)
-
在新表中新增外來鍵約束語法: constraint 外來鍵約束名稱 foreign key(外來鍵的欄位名稱) references 主表表名(主鍵欄位名)
-
在已有表中新增外來鍵約束:alter table 從表表名 add constraints 外來鍵約束名稱 foreign key(外來鍵的欄位名稱) references 主表表名(主鍵欄位名)
-
刪除外來鍵語法: alter table 從表表名 drop foreign key 外來鍵名稱;
-
級聯操作:
-
注意:
在從表中,修改關聯主表中不存在的資料,是不合法的
在主表中,刪除從表中已經存在的主表資訊,是不合法的。直接刪除主表(從表中有記錄資料關聯) 會包刪除失敗。
-
概念: 在修改或者刪除主表的主鍵時,同時它會更新或者刪除從表中的外來鍵值,這種 動作我們稱之為級聯操作。
-
語法:
-
更新級聯 on update cascade 級聯更新 只能是建立表的時候建立級聯關係。當更新主表中的主鍵,從表中的外來鍵欄位會同步更新。
-
刪除級聯 on delete cascade 級聯刪除 當刪除主表中的主鍵時,從表中的含有該欄位的記錄值會同步刪除。
-
-
操作:
-- 給從表student新增級聯操作 create table student( s_id int PRIMARY key , s_name VARCHAR(10) not null
-
約束總結
約束名 | 關鍵字 | 描述 |
---|---|---|
主鍵 | primary key | 唯一不為空 |
預設 | default | 插入資料,該欄位沒有賦值,系統會自動賦指定的預設值 |
非空 | not null | 該欄位不能為null(空) |
唯一 | unique | 該欄位的值在整個表中只能出現1次 |
外來鍵 | foreign key | 從表中新增外來鍵欄位,關聯主表中的主鍵欄位 |
表與表之間的關係
可以分成三類:
-
一對一的關係:一般情況下,一對一的關係基本不用,當發現兩張表是一對一的關係,合成一張表,例如:人和身份證號,學生和學生證號
-
一對多的關係:在表關係中是最多的情況,也是最常見的,比如:部門和員工
-
多對多:從兩個方向觀察發現都是1-n關係,比如:學生表和課程表, 企業和應聘者 雙選會
-
操作:
學生表、課程表 多對多關係 使用者表 、角色表 一對多關係
-- 建立學生表 drop table student; create table student( s_id int PRIMARY key auto_increment, -- 主鍵約束 s_name VARCHAR(10) not null, -- 非空約束 s_num int unique not null -- 唯一約束,非空約束 ); -- 建立課程表 drop table course; create table course ( c_id int PRIMARY key auto_increment COMMENT '課程id', -- 主鍵約束 c_name VARCHAR(10) not null unique COMMENT '課程名稱' -- 唯一 非空約束 ); -- 中間表 create table t_stu_cour ( s_id int, c_id int, CONSTRAINT stu_id foreign key(s_id) REFERENCES student(s_id), CONSTRAINT cour_id foreign key(c_id) REFERENCES course(c_id) ); -- 建立使用者表 drop table user; create table user ( u_id int PRIMARY key auto_increment COMMENT '使用者表主鍵id', -- 主鍵約束 u_name VARCHAR(10) not null, -- 非空約束 u_phone VARCHAR(11) unique, -- 唯一約束 u_rid int, -- 需要新增的外來鍵資訊 CONSTRAINT user_rid FOREIGN key(u_rid) REFERENCES role(r_id) ); -- 建立角色表 drop table role; create table role ( r_id int PRIMARY key auto_increment COMMENT '角色表主鍵id', -- 主鍵約束 r_name VARCHAR(10) not null UNIQUE, -- 唯一約束 非空約束 r_desc VARCHAR(255) ) -- 如果兩張表是一對多關係 設計建立時,先建立主表,再建立從表
-
表與表之間關係總結
表之間關係 關係維護、建立 一對一 合表,互為外來鍵約束,表之間關係很少 一對多 在從表(多的那一方)的那一方建立外來鍵,關聯主表的主鍵欄位,先建立主表,再建立從表 多對多 建立中間表,中間表分別新增外來鍵約束關聯各自對應的的主鍵 資料庫設計的正規化
-
什麼是正規化?
在設計資料庫的時候,需要遵從的規範要求,根據這些規範要求設計出合理的資料庫。這些規範被稱為正規化。
這些正規化針對的是關係型資料庫。
目前關係型資料庫的正規化有六種:第一正規化(1NF)、第二正規化(2NF)、第三正規化(3NF)、第四正規化(4NF)、第五正規化(完美正規化)(5NF)、巴斯-科德正規化。(BCNF)
各種正規化呈遞次規範,越高的正規化資料庫的冗餘性就越低。
-
前三種正規化介紹:
-
第一正規化(1NF):資料庫中的每一列是不可分割的原子資料項。
-
第二正規化(2NF): 在第一正規化的基礎上,非碼屬性必須完全依賴於碼(在第一正規化的基礎上消除非主屬性對碼的部分函式依賴)
-
概念:
-
函式依賴:A---->B 如果通過A屬性(屬性組)的值,可以確定唯一的B屬性值,可以稱B依賴於A
-
完全函式依賴 A---->B 如果A是一個屬性組,則B屬性值的確定需要依賴於A屬性組中的所有屬性值
-
部分函式依賴 A---->B 如果A是一個屬性組,則B屬性值的確定只需要依賴於A屬性組中某一個或某一些屬性值即可。
-
傳遞函式依賴 A---->B B---->C 如果通過A屬性(屬性組)的值,可以唯一確定B屬性的值,在通過B屬性的值可以唯一確定C屬性的值,可以稱 C 傳遞依賴於A
-
碼:如果在一張表中,一個屬性或者屬性組,被其他所有屬性所完全依賴,則稱這個屬性(屬性組)為該表的碼。
-
主屬性: 碼屬性組中的所有屬性
-
非主屬性:除主屬性外的其他屬性
-
-
-
-
第三正規化(3NF):在第二正規化的基礎上,任何非主屬性不依賴與其他的非主屬性(在2NF基礎上,消除傳遞函式依賴)
-
-
三大正規化總結
正規化 | 特徵 |
---|---|
1NF | 表中的每一列具有原子性,表中的每一列不可分割 |
2NF | 消除部分函式依賴,一張表只做一件事 |
3NF | 消除傳遞函式依賴,表中的每一列都直接依賴於碼(主鍵)。不需要通過其他的欄位(列)間接依賴於主鍵 |
多表連線查詢
-
分類:內連線(顯式內連線、隱式內連式)、外連線(左外連線、右外連線)
-
笛卡爾積現象:
-
左表中的每條記錄和右表中的每條記錄全關聯組合,這種效果就稱之為笛卡爾積現象。
-
-
消除笛卡爾積現象
新增條件過濾,使用where條件語句,達到過濾掉無效的資料。
-
內連線 inner join
-
隱式內連線:省略掉內連線關鍵字 inner join
-
語法: select 欄位列表 from 表名1,表名2,.... where 條件語句
-
操作: select * from department ,employee where d_id = e_did;
-
-
顯式內連線:使用內連線關鍵字 inner join .... on語句 inner 可以省略
-
語法: select 欄位列表 from 表名1 [inner] join 表名2 on 條件語句
-
操作:select * from department inner join employ on d_id = e_did;
-
-
總結
-
查詢哪些表
-
確定表關聯的條件
-
使用連線的方式
-
確定查詢的欄位資訊 ,儘量少用*
-
-
-
外連線
-
左外連線: 使用 left [outer] join ..... on 條件語句 outer關鍵字可以省略
-
語法: select 欄位列表 from 左表(主表) left [outer] join 右表(從表/輔表) on 條件語句。
-
注意事項:用左表中的記錄資料去匹配右表中的記錄資料,如果符合條件的則顯示,不顯示的資料一律顯示為null。保證左表中的資料全部顯示。
-
操作:select d.*, e. e_username from department as d left outer join employee as e on e.e_did = d.d_id;
-
-
右外連線 使用 right [outer] join ..... on 條件語句 outer關鍵字可以省略
-
語法: select 欄位列表 from 右表(主表) right [outer] join 左表(從表/輔表) on 條件語句。
-
注意事項:用右表中的記錄資料去匹配左表中的記錄資料,如果符合條件的則顯示,不顯示的資料一律顯示為null。保證右表中的資料全部顯示。
-
select * from employ right outer join department on e_did = d_id right outer join salary on e_id = s_eid
-
-
-
子查詢
-
什麼是子查詢?
-
概念:一個查詢的結果是另一個查詢的條件,形成查詢巢狀,裡面的查詢稱之為子查詢,一定要出現小括號。
-
子查詢有三種情況:
-
子查詢結果可以是單行單列,只有一個欄位,這一個只有一個值
-
也可以是多行單利,只有一個欄位,這個欄位有多個值
-
還可以是多行多列,有多個欄位,多個欄位分別有多個值。
-
操作:
-
第一種情況: 單行單列
-
語法:select 查詢欄位列表 from 表名 where 欄位 比較運算子 (子查詢);
-
特徵:我們可以在where的後面 使用比較運算子 > < >= <= != <>
-
-
第二種情況:多行單列
-
語法:select 查詢欄位列表 from 表名 where 欄位 in (子查詢);
-
特徵:結果值是一個集合或者一個數組,父查詢使用in運算子
-
操作:
select d_name from department WHERE d_id in ( SELECT DISTINCT e_did FROM employee WHERE age > ( SELECT avg(age) FROM employee ) )
-
-
第三種情況:多行多列,一般情況下我們可以作為一張虛擬表,進行關聯二次查詢,一般需要給這個虛擬表起一個別名來實現。
-
語法:select 查詢欄位列表 from 表名 ,(子查詢) as 新表名 where 條件語句 ;
-
特徵:多行多列不能再使用in運算子或者比較運算子,而是需要進行多表關聯,給查詢出來的多行多列起別名。
-
-
-
-
子查詢總結:
-
單行單列:只有一個值,在where後面可以使用比較運算子,作為條件
-
多行單列:是一個集合值或者陣列值,在where後面使用的是in運算子,作為條件
-
多行多列:大多數多列結果值是放在from後面的,作為多表關聯的。可以進行二次條件過濾。
-
-
事務
-
什麼是事務:一個業務操作中,這個操作要麼被完全執行成功,要麼被撤銷掉。這個業務操作是一個整體,在這個整體中所有的sql語句要麼全部執行成功,要麼被回滾。(業務執行失敗)。
-
操作: 張三給李四轉賬10000,張三的賬戶減掉1萬塊 李四的賬戶增加1萬塊
-- 建立賬戶表
create table account (
id int PRIMARY key auto_increment, -- 主鍵id
username VARCHAR(10) not null, -- 賬戶
balance double -- 賬戶餘額
)
-- 插入兩條資料
insert into account values(null,'張三',20000),(null,'李四',20000);
-- 張三給李四轉賬1000塊錢
-- 先讓張三的錢減掉10000
update account set balance = balance - 10000 where username = '張三';
-- 新增一條語句
update account set balance = balance - 10000 username = '張三';
-- 再讓李四的錢增加10000
update account set balance = balance + 10000 where username = '李四';
-- 還原資料
update account set balance = 20000;
-- 查詢賬戶表
SELECT * from account;
手動操作事務:
-
-
三個動作:
-
開啟事務: start transaction;
-
提交事務: commit;
-
回滾事務: rollback;
-
事務的四大特性:
-
-
原子性:這個事務是一個整體,在這個整體中,是不可分割的,在事務中所有的sql語句要麼完全執行成功,要麼都失敗。
-
一致性:事務在執行前和執行後資料庫中的資料狀態是一致的。轉賬:張三和李四轉賬前餘額都是20000,轉賬後,如果成功結果:張三是10000,李四是30000,如果失敗結果:張三是20000,李四也是20000。
-
隔離性:事務與事務之間是互不影響的,在多個事務併發執行的時候應該處於隔離的狀態。
-
永續性:一旦事務執行成功,對資料庫的影響是持久的。
-
事務的隔離級別:讀未提交-->read uncommitted 讀已提交--->read committed 可重複讀 ----> repeatable read
序列化-----> serializable 鎖表 安全性最高 效能最低
由事務隔離級別引發併發訪問操作的問題:髒讀、不可重複讀、幻讀。
備註:如果表的引擎是MyISAM,則該表無法不支援事務,最好將其改為InnoDB引擎。