外來鍵約束
-
在新表中新增外來鍵約束語法: 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, s_c_id int, -- constraint 外來鍵約束名稱 foreign key(外來鍵的欄位名稱) references 主表表名(主鍵欄位名) CONSTRAINT stu_cour_id FOREIGN key(s_c_id) REFERENCES course(c_id) -- 給s_c_id 新增外來鍵約束 ON UPDATE CASCADE ON DELETE CASCADE ) insert into student VALUE(1,'小孫',1),(2,'小王',2),(3,'小劉',4); insert into student VALUE(4,'小司馬',1),(5,'小趙',1),(6,'小錢',1); -- 查詢學生表中的記錄 select * from student; -- 級聯操作。 -- 更新級聯 on update cascade 級聯更新 只能是建立表的時候建立級聯關係。當更新主表中的主鍵,從表中的外來鍵欄位會同步更新。 update course set c_id = 10 where c_id = 1; -- 刪除級聯 on delete cascade 級聯刪除 當刪除主表中的主鍵時,從表中的含有該欄位的記錄值會同步刪除。 delete from course where c_id = 10;
-
約束總結
約束名 | 關鍵字 | 描述 |
---|---|---|
主鍵 | 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;
- 總結
- 查詢哪些表
- 確定表關聯的條件
- 使用連線的方式
- 確定查詢的欄位資訊 ,儘量少用*
- 隱式內連線:省略掉內連線關鍵字 inner join
-
外連線
- 左外連線: 使用 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
- 左外連線: 使用 left [outer] join ..... on 條件語句 outer關鍵字可以省略
-
子查詢
-
什麼是子查詢?
-
概念:一個查詢的結果是另一個查詢的條件,形成查詢巢狀,裡面的查詢稱之為子查詢,一定要出現小括號。
-
子查詢有三種情況:
-
子查詢結果可以是單行單列,只有一個欄位,這一個只有一個值
-
也可以是多行單利,只有一個欄位,這個欄位有多個值
-
還可以是多行多列,有多個欄位,多個欄位分別有多個值。
-
操作:
-
第一種情況: 單行單列
- 語法: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 鎖表 安全性最高 效能最低
-
由事務隔離級別引發併發訪問操作的問題:髒讀、不可重複讀、幻讀。
-
-