<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
1.資料庫設計概念
表結構
以及表與表之間的關聯關係
的過程。2.資料庫設計步驟
ER圖
對資料庫進行邏輯建模,不需要考慮我們所選用的資料庫管理系統。3.表關係簡介
在資料庫中,表總共存在三種關係,真實的資料表之間的關係:多對多關係、一對多(多對一)、一對一(極少),(一對一關係就是我們之前學習的Map集合的key-value關係)
1.多對多
中間表
,中間表至少包含兩個外來鍵
,分別關聯兩方主鍵
說明:如果兩張表是多對多的關係,需要建立第三張表,並在第三張表中增加兩列,引入其他兩張表的主鍵作為自己的外來鍵。
2.外來鍵約束
3.外來鍵約束語法
-- 關鍵字解釋: constraint: 新增約束,可以不寫 foreign key(當前表中的列名): 將某個欄位作為外來鍵 references 被參照表名(被參照表的列名) : 外來鍵參照主表的主鍵 -- 建立表時新增外來鍵約束 CREATE TABLE 表名( 列名 資料型別, … [CONSTRAINT] [外來鍵名稱] FOREIGN KEY(外來鍵列名) REFERENCES 主表(主表列名) ); -- 建完表後新增外來鍵約束 ALTER TABLE 表名 ADD CONSTRAINT 外來鍵名稱 FOREIGN KEY (外來鍵欄位名稱) REFERENCES 主表名稱(主表列名稱); -- 刪除約束 ALTER TABLE 表名 DROP FOREIGN KEY 外來鍵名稱;
4.建立外來鍵約束
-- 訂單表 CREATE TABLE tb_orders ( id int primary key auto_increment, payment double(10, 2), payment_type TINYINT, -- 0 微信支付 1 支付寶支付 status TINYINT -- 0 未付款 1 已經支付 ); -- 商品表 CREATE TABLE tb_goods ( id int primary key auto_increment, title varchar(100), price double(10, 2) ); -- 訂單商品中間表 CREATE TABLE tb_order_goods ( id int primary key auto_increment, order_id int, -- 外來鍵,來自於訂單表的主鍵 goods_id int, -- 外來鍵,來自於商品表的主鍵 count int, -- 購買商品數量 foreign key(order_id) references tb_orders(id), foreign key(goods_id) references tb_goods(id) );
5.外來鍵級聯
在修改和刪除主表的主鍵時,同時更新或刪除從表的外來鍵值,稱為級聯操作
ON UPDATE CASCADE
– 級聯更新,主鍵發生更新時,外來鍵也會更新ON DELETE CASCADE
– 級聯刪除,主鍵發生刪除時,外來鍵也會刪除6.總結
1.為何要參照外來鍵約束?
讓表的資料有效性,正確性。提高查詢效率。2.新增外來鍵約束語法?
constraint 外來鍵約束名 foreign key(當前表的欄位名) references 主表(主鍵)3.有了外來鍵約束運算元據注意事項?
要求新增資料需要先新增主表,然後新增從表。要求刪除資料需要先刪除從表,然後再刪除主表。
一對多(多對一)
一對一
(UNIQUE)
準備資料
-- 價格 create table price ( id int primary key auto_increment, price double ); -- 水果 create table fruit ( id int primary key auto_increment, name varchar(20) not null, price_id int, foreign key (price_id) references price (id) ); -- 資料 insert into price values (1, 2.30); insert into price values (2, 3.50); insert into price values (4, null); insert into fruit values (1, '蘋果', 1); insert into fruit values (2, '橘子', 2); insert into fruit values (3, '香蕉', null);
1.什麼是笛卡爾積現象
select * from 表名1,表名2;
需求:查詢兩張表中關於水果的資訊,要顯示水果名稱和水果價格
表設計原則:將價格的主鍵作為水果的外來鍵
-- 多表查詢語法(同時查詢多個表獲取到需要的資料) select * from 表名1,表名2; -- 查詢價格(我們向查詢水果對應的價格,需要將水果表和價格表同時進行查詢;) select * from fruit,price;
查詢結果:
2.笛卡爾積產生原因
fruit
表中的每一條記錄,都和price
表中的每一條進行匹配連線。所得到的最終結果是:fruit表中的條目數乘以price
表中的資料的條目數。
將fruit
表的每行記錄和price
表的每行記錄組合的結果就是笛卡爾積
3.如何避免笛卡爾積
解決上述查詢的方案:在查詢兩張表的同時新增條件進行過濾,比如fruit表的id和必須和price表的id相同
-- 條件過濾笛卡爾積 select * from fruit,price where fruit.price_id=price.id;
1.什麼是內連線
內連線查詢又稱為交集查詢,也就是查詢只顯示滿足條件的資料
2.顯示內連線
顯示內連線:使用INNER JOIN...ON
語句,可以省略INNER
關鍵字
-- 語法核心 select * from 表名1 inner join 表名2 on 條件; -- 或者 select * from 表名1 join 表名2 on 條件;
3.隱式內連線
看不到JOIN
關鍵字,條件使用WHERE
指定
select 列名,列名,... from 表名1,表名2 where 表名1.列名=表名2.列名;
4.範例
查詢水果的價格
-- 隱式內連線 select * from fruit,price where fruit.price_id=price.id; -- 顯式內連線 select * from fruit inner join price on fruit.price_id=price.id;
查詢蘋果的資訊,顯示蘋果的id,名字,價格
-- 方式1 select fruit.id, fruit.name, price.price from fruit, price where fruit.price_id = price.id and fruit.name = '蘋果'; -- 方式2 select fruit.id, fruit.name, price.price from fruit inner join price on fruit.price_id = price.id and fruit.name = '蘋果';
5.總結
1.內連線作用?
2.什麼是隱式內連線和顯示內連線?
select 列名,列名....from 表名1,表名2 where 表名1.列名=表名2.列名;
select * from 表名1 inner join 表名2 on 條件;
3.內連線查詢步驟?
1.左外連線
語法格式:
select * from 表1 left [outer] join 表2 on 條件;
說明:
left
關鍵字左邊的表定義為左表,left
關鍵字右邊的表定義為右表,查詢的內容以左表為主outer
關鍵字可以省略練習:
不管能否查到水果對應價格,都要把水果顯示出來
-- 左外連線查詢 select * from fruit left outer join price on fruit.price_id=price.id;
2.右外連線
語法格式:
select * from 表名1 right [outer] join 表名2 on 條件;
說明:
right
關鍵字左邊的表定義為左表,right
關鍵字右邊的表定義為右表,查詢的內容以右表為主outer
關鍵字可以省略練習:
不管能否查到價格對應的水果,都要把價格顯示出來
select * from fruit right outer join price on fruit.price_id=price.id;
總結:
1.掌握左外連線查詢格式?
select * from 表1 left outer join 表2 on 條件;
2.左外連線查詢特點?
3.掌握右外連線查詢格式?
select * from 表1 right outer join 表2 on 條件;
4.右外連線查詢特點?
在滿足要求的基礎上,保證右表的資料全部顯示
1.什麼是子查詢
一條查詢語句結果作為另一條查詢語法一部分。
SELECT 查詢欄位 FROM 表 WHERE 條件; 舉例: SELECT * FROM employee WHERE salary=(SELECT MAX(salary) FROM employee);
說明:子查詢需要放在()中
三種子查詢情況:單行單列
、多行單列
、多行多列
。
2.單行單列
子查詢結果是單列
,在WHERE
後面作為條件
SELECT 查詢欄位 FROM 表 WHERE 欄位=(子查詢);
通常使用比較運運算元: >
、>=
、<
、<=
、=
等
3.多行單列
子查詢結果是多行單列,結果集類似於一個陣列,在WHERE
後面作為條件
,父查詢使用IN
運運算元
-- IN表示在數值中 SELECT 查詢欄位 FROM 表 WHERE 欄位 IN (子查詢);
4.多行多列
子查詢結果是多列
,在FROM
後面作為表
SELECT 查詢欄位 FROM (子查詢) 表別名 WHERE 條件;
注意:子查詢作為表需要取別名,使用as,可以省略,否則這張表沒用名稱無法存取表中的欄位
什麼是事務
在實際的業務開發中,有些業務操作要多次存取資料庫。一個業務要傳送多條SQL語句給資料庫執行。需要將多次存取資料庫的操作視為一個整體來執行,要麼所有的SQL語句全部執行成功。如果其中有一條SQL語句失敗,就進行事務的回滾,所有的SQL語句全部執行失敗。
簡而言之,事務指的是邏輯上的一組操作,組成這組操作的各個單元要麼全都成功,要麼全都失敗。
事務作用:保證在一個事務中多次運算元據庫表中資料時,要麼全都成功,要麼全都失敗。
事務的應用場景宣告
關於事務在實際中的應用場景:
假設我在淘寶買了一部手機,然後當我付完款,錢已經從我的賬戶中扣除。正當此時,淘寶轉賬系統宕機了,那麼此時淘寶還沒有收到錢,而我的賬戶的錢已經減少了,這樣就會導致我作為買家錢已經付過,而賣家還沒有收到錢,他們不會發貨物給我。這樣做顯然是不合理。實際生活中是如果淘寶出問題,作為使用者的賬戶中錢是不應該減少的。這樣使用者就不會損失錢。
還有種情況,就是當我付完款之後,賣家看到我付款成功,然後直接發貨了,我如果有許可權操作,我可以復原,這樣就會導致我的錢沒有減少,但是賣家已經發貨,同樣這種問題在實際生活中也是不允許出現的。
MySQL中可以有兩種方式進行事務的操作:
sql
語句提交一次事物資料準備
# 建立賬號表 create table account( id int primary key auto_increment, name varchar(20), money double ); # 初始化資料 insert into account values (null,'a',1000); insert into account values (null,'b',1000);
手動提交事務有關的sql語句
SQL語句 | 描述 |
---|---|
start transaction | 開啟手動控制事物 |
commit | 提交事物 |
rollback | 回滾事物 |
手動提交事務使用步驟
演示案例:演示提交事務,a給b轉賬100元
-- 1.開啟事務 start transaction; -- 2.執行sql語句 update account set money=money-100 where name='a'; update account set money=money+100 where name='b'; -- 3.提交事務 commit;
案例演示:演示回滾事務,a給b轉賬100元
-- 1.開啟事務 start transaction; -- 2.執行sql語句 update account set money=money-100 where name='a'; update account set money=money+100 where name='b'; -- 3.回滾事務 rollback;
注意:
commit
) :事務提交之後,sql
語句對資料庫產生的操作才會被永久的儲存rollback
):復原已經成功執行的sql
語句,回到開啟事務之前的狀態MySQL的每一條DML(增刪改)語句都是一個單獨的事務,每條語句都會自動開啟一個事務,執行完畢自動提交事務,MySQL預設開始自動提交事務。自動提交,通過修改mysql全域性變數autocommit
進行控制。
通過以下命令可以檢視當前autocommit模式
show variables like '%commit%';
設定自動提交的引數為OFF
set autocommit = 0; -- 0:OFF 1:ON
案例演示
-- 自動提交事務:每條sql語句就是一個事務,那麼執行一條sql語句就會提交一次事務 -- mysql資料庫就是自動提交事務 -- a給b轉賬100元 update account set money=money-100 where name='a'; update account set money=money+100 where name='b'; -- 檢視mysql是否自動提交事務 -- autocommit的值是on表示自動提交事務,值是off表示關閉自動提交事務 show variables like '%commit%'; -- 我們可以使用命令臨時設定mysql變為手動提交事務,即將自動提交事務關閉 -- 下次重新連線mysql依然是自動提交事務 set autocommit = 0; -- 0 表示關閉自動提交事務 1表示開啟自動事務 update account set money=money-100 where name='a'
注意:
1)MySql預設自動提交。即執行一條sql語句提交一次事務。
2)設定autocommit為off
狀態,只是臨時性的,下次重新連線mysql,autocommit依然變為on
狀態。
3)如果設定autocommit為off
狀態,那麼當我們執行一條sql語句,就不會自動提交事務,重新啟動視覺化工具,資料並沒有改變。
4)如果設定autocommit為on
狀態,如果我們先執行start transaction
然後在執行修改資料庫的語句:
update account set money = money-100 where name='a'; update account set money = money+100 where name='b';
那麼此時就表示上述修改資料庫的sql語句都在同一個事務中,此時必須手動提交事務,即commit
;
換句話說,如果我們手動開啟事務start transaction
那麼此時mysql就不會自動提交事務,必須手動提交事務。
5)如果設定autocommit為on狀態,如果我們不執行start transaction
直接執行修改資料庫的語句:
update account set money = money-100 where name='a'; update account set money = money+100 where name='b';
那麼此時mysql就會自動提交事務,即上述每條sql語句就是一個事務
原理說明
事務的四大特徵(ACID)
資料庫的事務必須具備ACID特徵,ACID是指Atomicity
(原子性)、Consistensy
(一致性)、Isolation
(隔離性)和Durabiliyt
(永續性)
隔離性(Isolation)
多個使用者並行的存取資料庫時,一個使用者的事務不能被其他使用者的事物干擾,多個並行的事務之間相互隔離
永續性(Durability)
指一個事務一旦被提交,它對資料庫的改變是永久性的,哪怕資料庫發生異常,重啟之後資料依然會存在
原子性(Atomicity)
指事務包裝的一組sql語句(一組業務邏輯)是一個不可分割的工作單位,事務中的操作要麼都發生,要麼都不發生
一致性(Consistency)
一致性是指資料處於一種語意上有意義且正確的狀態;
事務一致性是指事務執行的結果必須是使資料從一個一致性狀態變到另一個一致性狀態。
事務的成功與失敗,最終資料庫的資料都是符合實際生活的業務邏輯。一致性絕大多數依賴業務邏輯和原子性
事務在操作時的理想狀態:多個事務之間互不影響,如果隔離級別設定不當就可能引發並行存取問題
並行存取的問題 | 含義 |
---|---|
髒讀 | 一個事務讀取到了另一個事務中尚未提交的資料。最嚴重,杜絕發生。 |
不可重複讀 | 一個事務中兩次讀取的資料內容不一致,要求的是一個事務中多次讀取時資料是不一致的,這是事務update時引發的問題 |
幻讀(虛讀) | 一個事務內讀取到了別的事務插入或者刪除的資料,導致前後讀取記錄行數不同。這是insert或delete時引發的問題 |
1.髒讀:指一個事務讀取了另外一個事務未提交的資料。(非常危險)
2.不可重複讀:在一個事務內多次讀取表中的資料,多次讀取的結果不同。
3.幻讀(虛讀):一個事務內讀取到了別的事務插入或者刪除的資料,導致前後讀取記錄行數不同
4.總結
通過以上問題演示,我們發現如果不考慮事務的隔離性,會遇到髒讀、不可重複讀和虛讀等問題。所以在資料庫中我們要對上述三種問題進行解決。MySQL資料庫規範規定了4種隔離級別,分別用於描述兩個事務並行的所有情況。
事物隔離級別
上面的級別最低,下面的級別最高。是
表示會出現這種問題,否
表示不會出現這種問題。
級別 | 名字 | 隔離級別 | 髒讀 | 不可重複讀 | 幻讀 | 資料庫預設隔離級別 |
---|---|---|---|---|---|---|
1 | 讀未提交 | read uncommitted | 是 | 是 | 是 | |
2 | 讀已提交 | read committed | 否 | 是 | 是 | Oracle和SQL Server |
3 | 可重複讀 | repeatable read | 否 | 否 | 是 | MySQL |
4 | 序列化 | serializable | 否 | 否 | 否 |
安全和效能對比
其實三個問題中,最嚴重的就是髒讀(讀取了錯誤資料),這個問題一定要避免;
關於不可重複讀和虛讀其實並不是邏輯上的錯誤,而是資料的時效性問題,所以這種問題並不屬於很嚴重的錯誤;
如果對於資料的時效性要求不是很高的情況下,我們是可以接受不可重複讀和虛讀的情況發生的
到此這篇關於MySQL資料庫設計概念及多表查詢;事物操作的文章就介紹到這了,更多相關mysql資料庫設計內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45