欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

MySQL數(shù)據(jù)庫(kù)設(shè)計(jì)概念及多表查詢和事物操作

 更新時(shí)間:2022年05月23日 17:26:58   作者:Tangable1024  
數(shù)據(jù)庫(kù)設(shè)計(jì)就是根據(jù)業(yè)務(wù)系統(tǒng)具體需求,結(jié)合我們所選用的DBMS,為這個(gè)業(yè)務(wù)系統(tǒng)構(gòu)造出最優(yōu)的數(shù)據(jù)存儲(chǔ)模型,本文給大家介紹MySQL數(shù)據(jù)庫(kù)設(shè)計(jì)概念及多表查詢和事物操作,感興趣的朋友一起看看吧

數(shù)據(jù)庫(kù)設(shè)計(jì)概念

數(shù)據(jù)庫(kù)設(shè)計(jì)簡(jiǎn)介

1.數(shù)據(jù)庫(kù)設(shè)計(jì)概念

  • 數(shù)據(jù)庫(kù)設(shè)計(jì)就是根據(jù)業(yè)務(wù)系統(tǒng)具體需求,結(jié)合我們所選用的DBMS,為這個(gè)業(yè)務(wù)系統(tǒng)構(gòu)造出最優(yōu)的數(shù)據(jù)存儲(chǔ)模型。
  • 建立數(shù)據(jù)庫(kù)中的表結(jié)構(gòu)以及表與表之間的關(guān)聯(lián)關(guān)系的過(guò)程。
  • 有哪些表?表里有哪些字段?表和表之間有什么關(guān)系?

2.數(shù)據(jù)庫(kù)設(shè)計(jì)步驟

  • 需求分析:數(shù)據(jù)庫(kù)是什么?數(shù)據(jù)具體有哪些屬性?數(shù)據(jù)與屬性的特點(diǎn)是什么?
  • 邏輯分析:通過(guò)ER圖對(duì)數(shù)據(jù)庫(kù)進(jìn)行邏輯建模,不需要考慮我們所選用的數(shù)據(jù)庫(kù)管理系統(tǒng)。
  • 物理設(shè)計(jì):根據(jù)數(shù)據(jù)庫(kù)自身的特點(diǎn)把邏輯設(shè)計(jì)轉(zhuǎn)換為物理設(shè)計(jì)。
  • 維護(hù)設(shè)計(jì):對(duì)新的需求進(jìn)行建表和對(duì)表的優(yōu)化。

3.表關(guān)系簡(jiǎn)介

  • 在真實(shí)的開(kāi)發(fā)中,一個(gè)項(xiàng)目中的數(shù)據(jù),一般都會(huì)保存在同一個(gè)數(shù)據(jù)庫(kù)中,但是不同的數(shù)據(jù)需要保存在不同的數(shù)據(jù)表中。這時(shí)不能把所有的數(shù)據(jù)都保存在同一張表中。
  • 那么在設(shè)計(jì)保存數(shù)據(jù)的數(shù)據(jù)表時(shí),我們就要根據(jù)具體的數(shù)據(jù)進(jìn)行分析,然后把同一類數(shù)據(jù)保存在同一張表中,不同的數(shù)據(jù)進(jìn)行分表處理。
  • 數(shù)據(jù)之間必然會(huì)有一定的聯(lián)系,我們把不同的數(shù)據(jù)保存在不同的數(shù)據(jù)表中之后,同時(shí)還要在數(shù)據(jù)表中維護(hù)這些數(shù)據(jù)之間的關(guān)系。這時(shí)就會(huì)導(dǎo)致表和表之間必然會(huì)有一定的聯(lián)系。這時(shí)要求設(shè)計(jì)表的人員,就需要考慮不同表之間的具體關(guān)系。

在數(shù)據(jù)庫(kù)中,表總共存在三種關(guān)系,真實(shí)的數(shù)據(jù)表之間的關(guān)系:多對(duì)多關(guān)系、一對(duì)多(多對(duì)一)、一對(duì)一(極少),(一對(duì)一關(guān)系就是我們之前學(xué)習(xí)的Map集合的key-value關(guān)系)

表關(guān)系(多對(duì)多)

1.多對(duì)多

  • 如:訂單 和 商品
  • 一個(gè)商品對(duì)應(yīng)多個(gè)訂單,一個(gè)訂單對(duì)應(yīng)多個(gè)商品
  • 實(shí)現(xiàn)方式:建立第三張中間表,中間表至少包含兩個(gè)外鍵,分別關(guān)聯(lián)兩方主鍵

說(shuō)明:如果兩張表是多對(duì)多的關(guān)系,需要?jiǎng)?chuàng)建第三張表,并在第三張表中增加兩列,引入其他兩張表的主鍵作為自己的外鍵。

2.外鍵約束

  • 外鍵用來(lái)讓兩個(gè)表的數(shù)據(jù)之間建立鏈接,保證數(shù)據(jù)的一致性和完整性(例如上述多對(duì)多中的訂單商品表來(lái)維護(hù)訂單表和商品表之間的關(guān)系)
  • 使用之間表的目的是維護(hù)兩表之間多對(duì)多的關(guān)系:中間表插入的數(shù)據(jù),必須在多對(duì)多的主表中存在,如果主表的記錄在中間表中維護(hù)了關(guān)系,就不能隨意的刪除。如果要?jiǎng)h除,必須先要?jiǎng)h除中間表關(guān)聯(lián)的數(shù)據(jù)

3.外鍵約束語(yǔ)法

-- 關(guān)鍵字解釋:
constraint: 添加約束,可以不寫(xiě)
foreign key(當(dāng)前表中的列名): 將某個(gè)字段作為外鍵
references 被引用表名(被引用表的列名) : 外鍵引用主表的主鍵

-- 創(chuàng)建表時(shí)添加外鍵約束
CREATE TABLE 表名(
   列名 數(shù)據(jù)類型,
   …
   [CONSTRAINT] [外鍵名稱] FOREIGN KEY(外鍵列名) REFERENCES 主表(主表列名) 
); 
-- 建完表后添加外鍵約束
ALTER TABLE 表名 ADD CONSTRAINT 外鍵名稱 FOREIGN KEY (外鍵字段名稱) REFERENCES 主表名稱(主表列名稱);
-- 刪除約束
ALTER TABLE 表名 DROP FOREIGN KEY 外鍵名稱;

4.創(chuàng)建外鍵約束

-- 訂單表
CREATE TABLE tb_orders
(
    id           int primary key auto_increment,
    payment      double(10, 2),
    payment_type TINYINT, -- 0 微信支付  1 支付寶支付
    status       TINYINT  -- 0 未付款  1 已經(jīng)支付

);
-- 商品表
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, -- 外鍵,來(lái)自于訂單表的主鍵
    goods_id int, -- 外鍵,來(lái)自于商品表的主鍵
    count    int,  -- 購(gòu)買商品數(shù)量
    foreign key(order_id) references tb_orders(id),
    foreign key(goods_id) references tb_goods(id)
);

5.外鍵級(jí)聯(lián)

在修改和刪除主表的主鍵時(shí),同時(shí)更新或刪除從表的外鍵值,稱為級(jí)聯(lián)操作

  • ON UPDATE CASCADE – 級(jí)聯(lián)更新,主鍵發(fā)生更新時(shí),外鍵也會(huì)更新
  • ON DELETE CASCADE – 級(jí)聯(lián)刪除,主鍵發(fā)生刪除時(shí),外鍵也會(huì)刪除

6.總結(jié)

1.為何要引用外鍵約束?

讓表的數(shù)據(jù)有效性,正確性。提高查詢效率。

2.添加外鍵約束語(yǔ)法?

constraint 外鍵約束名 foreign key(當(dāng)前表的字段名) references 主表(主鍵)

3.有了外鍵約束操作數(shù)據(jù)注意事項(xiàng)?

要求添加數(shù)據(jù)需要先添加主表,然后添加從表。要求刪除數(shù)據(jù)需要先刪除從表,然后再刪除主表。

表關(guān)系(一對(duì)多)

一對(duì)多(多對(duì)一)

  • 如:部門(mén)表 和 員工表
  • 一個(gè)部門(mén)對(duì)應(yīng)多個(gè)員工,一個(gè)員工對(duì)應(yīng)一個(gè)部門(mén)
  • 實(shí)現(xiàn)方式:在多的一方建立外鍵,指向一的一方的主鍵

表關(guān)系之一對(duì)一

一對(duì)一

  • 如:用戶和 用戶信息
  • 一對(duì)一關(guān)系多用于表拆分,將一個(gè)實(shí)體中經(jīng)常使用的字段放一張表,不經(jīng)常使用的字段放另一張表,用于提升查詢性能
  • 實(shí)現(xiàn)方式:在任意一方加入外鍵,關(guān)聯(lián)另一方主鍵,并且設(shè)置外鍵為唯一(UNIQUE)

多表查詢

準(zhǔn)備數(shù)據(jù)

-- 價(jià)格
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)
);
-- 數(shù)據(jù)
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, '蘋(píng)果', 1);
insert into fruit
values (2, '橘子', 2);
insert into fruit
values (3, '香蕉', null);

笛卡爾積現(xiàn)象

1.什么是笛卡爾積現(xiàn)象

  • 笛卡爾積問(wèn)題:把多張表放在一起,同時(shí)去查詢,會(huì)得到一個(gè)結(jié)果,而這結(jié)果并不是我們想要的數(shù)據(jù),這個(gè)結(jié)果稱為笛卡爾積。
  • 笛卡爾積缺點(diǎn):查詢到的結(jié)果冗余了,里面有很多錯(cuò)誤的數(shù)據(jù),需要過(guò)濾。
  • 多表查詢語(yǔ)法:select * from 表名1,表名2;

需求:查詢兩張表中關(guān)于水果的信息,要顯示水果名稱和水果價(jià)格

表設(shè)計(jì)原則:將價(jià)格的主鍵作為水果的外鍵

-- 多表查詢語(yǔ)法(同時(shí)查詢多個(gè)表獲取到需要的數(shù)據(jù))
select * from 表名1,表名2;
-- 查詢價(jià)格(我們向查詢水果對(duì)應(yīng)的價(jià)格,需要將水果表和價(jià)格表同時(shí)進(jìn)行查詢;)
select * from fruit,price;

查詢結(jié)果:

2.笛卡爾積產(chǎn)生原因

fruit表中的每一條記錄,都和price表中的每一條進(jìn)行匹配連接。所得到的最終結(jié)果是:fruit表中的條目數(shù)乘以price表中的數(shù)據(jù)的條目數(shù)。

fruit表的每行記錄和price表的每行記錄組合的結(jié)果就是笛卡爾積

3.如何避免笛卡爾積

解決上述查詢的方案:在查詢兩張表的同時(shí)添加條件進(jìn)行過(guò)濾,比如fruit表的id和必須和price表的id相同

-- 條件過(guò)濾笛卡爾積
select * from fruit,price where fruit.price_id=price.id;

內(nèi)連接查詢

1.什么是內(nèi)連接

內(nèi)連接查詢又稱為交集查詢,也就是查詢只顯示滿足條件的數(shù)據(jù)

2.顯示內(nèi)連接

顯示內(nèi)連接:使用INNER JOIN...ON語(yǔ)句,可以省略INNER關(guān)鍵字

-- 語(yǔ)法核心
select * from 表名1 inner join 表名2 on 條件;
-- 或者
select * from 表名1 join 表名2 on 條件;

3.隱式內(nèi)連接

看不到JOIN關(guān)鍵字,條件使用WHERE指定

select 列名,列名,... from 表名1,表名2 where 表名1.列名=表名2.列名; 

4.示例

查詢水果的價(jià)格

-- 隱式內(nèi)連接
select * from fruit,price where fruit.price_id=price.id;
-- 顯式內(nèi)連接
select * from fruit inner join price on fruit.price_id=price.id;

查詢蘋(píng)果的信息,顯示蘋(píng)果的id,名字,價(jià)格

-- 方式1
select fruit.id, fruit.name, price.price
from fruit,
     price
where fruit.price_id = price.id
  and fruit.name = '蘋(píng)果';
-- 方式2
select fruit.id, fruit.name, price.price
from fruit
         inner join
     price
     on fruit.price_id = price.id
         and fruit.name = '蘋(píng)果';

5.總結(jié)

1.內(nèi)連接作用?

  • 過(guò)濾笛卡爾積
  • 獲取兩表的交集部分(都滿足條件的部分)

2.什么是隱式內(nèi)連接和顯示內(nèi)連接?

  • 隱式內(nèi)連接:看不到JOIN:select 列名,列名....from 表名1,表名2 where 表名1.列名=表名2.列名;
  • 顯示內(nèi)連接:看得到JOIN:select * from 表名1 inner join 表名2 on 條件;

3.內(nèi)連接查詢步驟?

  • 1)確定查詢幾張表
  • 2)確定表連接條件
  • 3)根據(jù)需要在操作 外連接查詢

1.左外連接

  • 左表的記錄全部顯示出來(lái)
  • 外表只會(huì)顯示符合搜索條件的記錄

語(yǔ)法格式:

select * from 表1 left [outer] join 表2 on 條件;

說(shuō)明:

  • left關(guān)鍵字左邊的表定義為左表,left關(guān)鍵字右邊的表定義為右表,查詢的內(nèi)容以左表為主
  • 如果左表有數(shù)據(jù),而右表沒(méi)有數(shù)據(jù)對(duì)應(yīng)的數(shù)據(jù),仍然會(huì)把左表數(shù)據(jù)進(jìn)行顯示
  • outer關(guān)鍵字可以省略

練習(xí):

不管能否查到水果對(duì)應(yīng)價(jià)格,都要把水果顯示出來(lái)

-- 左外連接查詢
select * from fruit left outer join price on fruit.price_id=price.id;

2.右外連接

  • 右表的記錄全部表示出來(lái)
  • 左表只會(huì)顯示符合搜索條件的記錄

語(yǔ)法格式:

select * from 表名1 right [outer] join 表名2 on 條件;

說(shuō)明:

  • right關(guān)鍵字左邊的表定義為左表,right關(guān)鍵字右邊的表定義為右表,查詢的內(nèi)容以右表為主
  • 如果右表沒(méi)有數(shù)據(jù),而左表沒(méi)有對(duì)應(yīng)的數(shù)據(jù),仍然會(huì)把右表數(shù)據(jù)進(jìn)行顯示
  • outer關(guān)鍵字可以省略

練習(xí):

不管能否查到價(jià)格對(duì)應(yīng)的水果,都要把價(jià)格顯示出來(lái)

select * from fruit right outer join price on fruit.price_id=price.id;

總結(jié):

1.掌握左外連接查詢格式?

select * from 表1 left outer join 表2 on 條件;
  • 表1看作為左表,表2看做為右表

2.左外連接查詢特點(diǎn)?

  • 在滿足要求的基礎(chǔ)上保證左表的數(shù)據(jù)全部顯示

3.掌握右外連接查詢格式?

select * from 表1 right outer join 表2 on 條件;

4.右外連接查詢特點(diǎn)?

在滿足要求的基礎(chǔ)上,保證右表的數(shù)據(jù)全部顯示

嵌套查詢(子查詢)

1.什么是子查詢

一條查詢語(yǔ)句結(jié)果作為另一條查詢語(yǔ)法一部分。

SELECT 查詢字段 FROM 表 WHERE 條件;
舉例:
SELECT * FROM employee WHERE salary=(SELECT MAX(salary) FROM employee);

說(shuō)明:子查詢需要放在()中

三種子查詢情況:單行單列、多行單列、多行多列。

2.單行單列

子查詢結(jié)果是單列,在WHERE后面作為條件

SELECT 查詢字段 FROM 表 WHERE 字段=(子查詢);

通常使用比較運(yùn)算符: >>= 、<、<==

3.多行單列

子查詢結(jié)果是多行單列,結(jié)果集類似于一個(gè)數(shù)組,在WHERE后面作為條件,父查詢使用IN運(yùn)算符

-- IN表示在數(shù)值中
SELECT 查詢字段 FROM 表 WHERE 字段 IN (子查詢);

4.多行多列

子查詢結(jié)果是多列,在FROM后面作為

SELECT 查詢字段 FROM (子查詢) 表別名 WHERE 條件;

注意:子查詢作為表需要取別名,使用as,可以省略,否則這張表沒(méi)用名稱無(wú)法訪問(wèn)表中的字段

事務(wù)操作

事務(wù)的概念

什么是事務(wù)

在實(shí)際的業(yè)務(wù)開(kāi)發(fā)中,有些業(yè)務(wù)操作要多次訪問(wèn)數(shù)據(jù)庫(kù)。一個(gè)業(yè)務(wù)要發(fā)送多條SQL語(yǔ)句給數(shù)據(jù)庫(kù)執(zhí)行。需要將多次訪問(wèn)數(shù)據(jù)庫(kù)的操作視為一個(gè)整體來(lái)執(zhí)行,要么所有的SQL語(yǔ)句全部執(zhí)行成功。如果其中有一條SQL語(yǔ)句失敗,就進(jìn)行事務(wù)的回滾,所有的SQL語(yǔ)句全部執(zhí)行失敗。

簡(jiǎn)而言之,事務(wù)指的是邏輯上的一組操作,組成這組操作的各個(gè)單元要么全都成功,要么全都失敗。

事務(wù)作用:保證在一個(gè)事務(wù)中多次操作數(shù)據(jù)庫(kù)表中數(shù)據(jù)時(shí),要么全都成功,要么全都失敗。

事務(wù)的應(yīng)用場(chǎng)景聲明

關(guān)于事務(wù)在實(shí)際中的應(yīng)用場(chǎng)景:

假設(shè)我在淘寶買了一部手機(jī),然后當(dāng)我付完款,錢已經(jīng)從我的賬戶中扣除。正當(dāng)此時(shí),淘寶轉(zhuǎn)賬系統(tǒng)宕機(jī)了,那么此時(shí)淘寶還沒(méi)有收到錢,而我的賬戶的錢已經(jīng)減少了,這樣就會(huì)導(dǎo)致我作為買家錢已經(jīng)付過(guò),而賣家還沒(méi)有收到錢,他們不會(huì)發(fā)貨物給我。這樣做顯然是不合理。實(shí)際生活中是如果淘寶出問(wèn)題,作為用戶的賬戶中錢是不應(yīng)該減少的。這樣用戶就不會(huì)損失錢。

還有種情況,就是當(dāng)我付完款之后,賣家看到我付款成功,然后直接發(fā)貨了,我如果有權(quán)限操作,我可以撤銷,這樣就會(huì)導(dǎo)致我的錢沒(méi)有減少,但是賣家已經(jīng)發(fā)貨,同樣這種問(wèn)題在實(shí)際生活中也是不允許出現(xiàn)的。

MySQL中可以有兩種方式進(jìn)行事務(wù)的操作:

  • 手動(dòng)提交事物:先開(kāi)啟,在提交
  • 自動(dòng)提交事物(默認(rèn)的):即執(zhí)行一條sql語(yǔ)句提交一次事物

數(shù)據(jù)準(zhǔn)備

# 創(chuàng)建賬號(hào)表
create table account(
	id int primary key auto_increment,
	name varchar(20),
	money double
);
# 初始化數(shù)據(jù)
insert into account values (null,'a',1000);
insert into account values (null,'b',1000);

手動(dòng)提交事務(wù)

手動(dòng)提交事務(wù)有關(guān)的sql語(yǔ)句

SQL語(yǔ)句描述
start transaction開(kāi)啟手動(dòng)控制事物
commit提交事物
rollback回滾事物

手動(dòng)提交事務(wù)使用步驟

  • 開(kāi)啟事務(wù)–>執(zhí)行SQL語(yǔ)句–>成功–>提交事務(wù)
  • 開(kāi)啟事務(wù)–>執(zhí)行SQL語(yǔ)句–>失敗–>回滾事務(wù)

演示案例:演示提交事務(wù),a給b轉(zhuǎn)賬100元

-- 1.開(kāi)啟事務(wù)
start transaction;
-- 2.執(zhí)行sql語(yǔ)句
update account set money=money-100 where name='a';
update account set money=money+100 where name='b';
-- 3.提交事務(wù)
commit;

案例演示:演示回滾事務(wù),a給b轉(zhuǎn)賬100元

-- 1.開(kāi)啟事務(wù)
start transaction;
-- 2.執(zhí)行sql語(yǔ)句
update account set money=money-100 where name='a';
update account set money=money+100 where name='b';
-- 3.回滾事務(wù)
rollback;

注意:

  • 提交事務(wù)(commit) :事務(wù)提交之后,sql語(yǔ)句對(duì)數(shù)據(jù)庫(kù)產(chǎn)生的操作才會(huì)被永久的保存
  • 事務(wù)的回滾(rollback):撤銷已經(jīng)成功執(zhí)行的sql語(yǔ)句,回到開(kāi)啟事務(wù)之前的狀態(tài)
  • 只要提交事務(wù),那么數(shù)據(jù)就會(huì)長(zhǎng)久保存了,就不能回滾事務(wù)了。即提交或者回滾事務(wù)都是代表結(jié)束當(dāng)前事務(wù)的操作

自動(dòng)提交事務(wù)

MySQL的每一條DML(增刪改)語(yǔ)句都是一個(gè)單獨(dú)的事務(wù),每條語(yǔ)句都會(huì)自動(dòng)開(kāi)啟一個(gè)事務(wù),執(zhí)行完畢自動(dòng)提交事務(wù),MySQL默認(rèn)開(kāi)始自動(dòng)提交事務(wù)。自動(dòng)提交,通過(guò)修改mysql全局變量autocommit進(jìn)行控制。

通過(guò)以下命令可以查看當(dāng)前autocommit模式

show variables like '%commit%';

設(shè)置自動(dòng)提交的參數(shù)為OFF

set autocommit = 0;  -- 0:OFF  1:ON

案例演示

-- 自動(dòng)提交事務(wù):每條sql語(yǔ)句就是一個(gè)事務(wù),那么執(zhí)行一條sql語(yǔ)句就會(huì)提交一次事務(wù)
-- mysql數(shù)據(jù)庫(kù)就是自動(dòng)提交事務(wù)
-- a給b轉(zhuǎn)賬100元
update account set money=money-100 where name='a';
update account set money=money+100 where name='b';

-- 查看mysql是否自動(dòng)提交事務(wù)
-- autocommit的值是on表示自動(dòng)提交事務(wù),值是off表示關(guān)閉自動(dòng)提交事務(wù)
show variables like '%commit%';
-- 我們可以使用命令臨時(shí)設(shè)置mysql變?yōu)槭謩?dòng)提交事務(wù),即將自動(dòng)提交事務(wù)關(guān)閉
-- 下次重新連接mysql依然是自動(dòng)提交事務(wù)
set autocommit = 0; -- 0 表示關(guān)閉自動(dòng)提交事務(wù) 1表示開(kāi)啟自動(dòng)事務(wù)
update account set money=money-100 where name='a'

注意:

1)MySql默認(rèn)自動(dòng)提交。即執(zhí)行一條sql語(yǔ)句提交一次事務(wù)。

2)設(shè)置autocommit為off狀態(tài),只是臨時(shí)性的,下次重新連接mysql,autocommit依然變?yōu)?code>on狀態(tài)。

3)如果設(shè)置autocommit為off狀態(tài),那么當(dāng)我們執(zhí)行一條sql語(yǔ)句,就不會(huì)自動(dòng)提交事務(wù),重新啟動(dòng)可視化工具,數(shù)據(jù)并沒(méi)有改變。

4)如果設(shè)置autocommit為on狀態(tài),如果我們先執(zhí)行start transaction 然后在執(zhí)行修改數(shù)據(jù)庫(kù)的語(yǔ)句:

update account set money = money-100 where name='a';
update account set money = money+100 where name='b';

那么此時(shí)就表示上述修改數(shù)據(jù)庫(kù)的sql語(yǔ)句都在同一個(gè)事務(wù)中,此時(shí)必須手動(dòng)提交事務(wù),即commit;

換句話說(shuō),如果我們手動(dòng)開(kāi)啟事務(wù)start transaction那么此時(shí)mysql就不會(huì)自動(dòng)提交事務(wù),必須手動(dòng)提交事務(wù)。

5)如果設(shè)置autocommit為on狀態(tài),如果我們不執(zhí)行start transaction 直接執(zhí)行修改數(shù)據(jù)庫(kù)的語(yǔ)句:

update account set money = money-100 where name='a';
update account set money = money+100 where name='b';

那么此時(shí)mysql就會(huì)自動(dòng)提交事務(wù),即上述每條sql語(yǔ)句就是一個(gè)事務(wù)

事務(wù)原理和四大特征

事務(wù)原理

原理說(shuō)明

  • 一個(gè)用戶登錄成功以后,服務(wù)器會(huì)創(chuàng)建一個(gè)臨時(shí)日志文件。日志文件用來(lái)保存用戶事務(wù)狀態(tài)。
  • 如果沒(méi)有使用事務(wù),則所有的操作直接寫(xiě)到數(shù)據(jù)庫(kù)中,不會(huì)使用日志文件。
  • 如果開(kāi)啟事務(wù),將所有的寫(xiě)操作寫(xiě)到日志文件中。
  • 如果這時(shí)用戶提交了事務(wù),則將日志文件中所有的操作寫(xiě)到數(shù)據(jù)庫(kù)中。
  • 如果用戶回滾事務(wù),則日志文件會(huì)被清空,不會(huì)影響到數(shù)據(jù)庫(kù)的操作。

事務(wù)的四大特征

事務(wù)的四大特征(ACID)

數(shù)據(jù)庫(kù)的事務(wù)必須具備ACID特征,ACID是指Atomicity(原子性)、Consistensy(一致性)、Isolation(隔離性)和Durabiliyt(持久性)

隔離性(Isolation)

多個(gè)用戶并發(fā)的訪問(wèn)數(shù)據(jù)庫(kù)時(shí),一個(gè)用戶的事務(wù)不能被其他用戶的事物干擾,多個(gè)并發(fā)的事務(wù)之間相互隔離


持久性(Durability)

指一個(gè)事務(wù)一旦被提交,它對(duì)數(shù)據(jù)庫(kù)的改變是永久性的,哪怕數(shù)據(jù)庫(kù)發(fā)生異常,重啟之后數(shù)據(jù)依然會(huì)存在


原子性(Atomicity)

指事務(wù)包裝的一組sql語(yǔ)句(一組業(yè)務(wù)邏輯)是一個(gè)不可分割的工作單位,事務(wù)中的操作要么都發(fā)生,要么都不發(fā)生

一致性(Consistency)

一致性是指數(shù)據(jù)處于一種語(yǔ)義上有意義且正確的狀態(tài);

事務(wù)一致性是指事務(wù)執(zhí)行的結(jié)果必須是使數(shù)據(jù)從一個(gè)一致性狀態(tài)變到另一個(gè)一致性狀態(tài)。

事務(wù)的成功與失敗,最終數(shù)據(jù)庫(kù)的數(shù)據(jù)都是符合實(shí)際生活的業(yè)務(wù)邏輯。一致性絕大多數(shù)依賴業(yè)務(wù)邏輯和原子性

事務(wù)的并發(fā)訪問(wèn)引發(fā)的三個(gè)問(wèn)題(面試)

事務(wù)在操作時(shí)的理想狀態(tài):多個(gè)事務(wù)之間互不影響,如果隔離級(jí)別設(shè)置不當(dāng)就可能引發(fā)并發(fā)訪問(wèn)問(wèn)題

并發(fā)訪問(wèn)的問(wèn)題含義
臟讀一個(gè)事務(wù)讀取到了另一個(gè)事務(wù)中尚未提交的數(shù)據(jù)。最嚴(yán)重,杜絕發(fā)生。
不可重復(fù)讀一個(gè)事務(wù)中兩次讀取的數(shù)據(jù)內(nèi)容不一致,要求的是一個(gè)事務(wù)中多次讀取時(shí)數(shù)據(jù)是不一致的,這是事務(wù)update時(shí)引發(fā)的問(wèn)題
幻讀(虛讀)一個(gè)事務(wù)內(nèi)讀取到了別的事務(wù)插入或者刪除的數(shù)據(jù),導(dǎo)致前后讀取記錄行數(shù)不同。這是insert或delete時(shí)引發(fā)的問(wèn)題

 

1.臟讀:指一個(gè)事務(wù)讀取了另外一個(gè)事務(wù)未提交的數(shù)據(jù)。(非常危險(xiǎn))


2.不可重復(fù)讀:在一個(gè)事務(wù)內(nèi)多次讀取表中的數(shù)據(jù),多次讀取的結(jié)果不同。


3.幻讀(虛讀):一個(gè)事務(wù)內(nèi)讀取到了別的事務(wù)插入或者刪除的數(shù)據(jù),導(dǎo)致前后讀取記錄行數(shù)不同

4.總結(jié)

  • 贓讀:一個(gè)事務(wù)讀取另一個(gè)事務(wù)還沒(méi)有提交的數(shù)據(jù),一定避免。
  • 不可重復(fù)讀:一個(gè)事務(wù)讀取多次數(shù)據(jù)內(nèi)容不一樣,主要是update語(yǔ)句。事務(wù)已經(jīng)提交了。 可以發(fā)生的。
  • 幻讀(虛讀):一個(gè)事務(wù)讀取多次數(shù)量不一樣,主要是delete或者insert語(yǔ)句。事務(wù)已經(jīng)提交了。可以發(fā)生的。

事務(wù)的隔離級(jí)別

通過(guò)以上問(wèn)題演示,我們發(fā)現(xiàn)如果不考慮事務(wù)的隔離性,會(huì)遇到臟讀、不可重復(fù)讀和虛讀等問(wèn)題。所以在數(shù)據(jù)庫(kù)中我們要對(duì)上述三種問(wèn)題進(jìn)行解決。MySQL數(shù)據(jù)庫(kù)規(guī)范規(guī)定了4種隔離級(jí)別,分別用于描述兩個(gè)事務(wù)并發(fā)的所有情況。

事物隔離級(jí)別

上面的級(jí)別最低,下面的級(jí)別最高。表示會(huì)出現(xiàn)這種問(wèn)題,表示不會(huì)出現(xiàn)這種問(wèn)題。

級(jí)別名字隔離級(jí)別臟讀不可重復(fù)讀幻讀數(shù)據(jù)庫(kù)默認(rèn)隔離級(jí)別
1讀未提交read uncommitted 
2讀已提交read committedOracle和SQL Server
3可重復(fù)讀repeatable readMySQL
4串行化serializable

安全和性能對(duì)比

  • 安全: 串行化>可重復(fù)讀>讀已提交>讀未提交
  • 性能: 串行化<可重復(fù)讀<讀已提交<讀未提交

其實(shí)三個(gè)問(wèn)題中,最嚴(yán)重的就是臟讀(讀取了錯(cuò)誤數(shù)據(jù)),這個(gè)問(wèn)題一定要避免;

關(guān)于不可重復(fù)讀和虛讀其實(shí)并不是邏輯上的錯(cuò)誤,而是數(shù)據(jù)的時(shí)效性問(wèn)題,所以這種問(wèn)題并不屬于很嚴(yán)重的錯(cuò)誤;

如果對(duì)于數(shù)據(jù)的時(shí)效性要求不是很高的情況下,我們是可以接受不可重復(fù)讀和虛讀的情況發(fā)生的

到此這篇關(guān)于MySQL數(shù)據(jù)庫(kù)設(shè)計(jì)概念及多表查詢;事物操作的文章就介紹到這了,更多相關(guān)mysql數(shù)據(jù)庫(kù)設(shè)計(jì)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Linux下MySQL卸載和安裝圖文教程

    Linux下MySQL卸載和安裝圖文教程

    這篇文章主要為大家詳細(xì)介紹了Linux下MySQL卸載和安裝圖文教程,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-11-11
  • MYSQL 沒(méi)有完全卸載將導(dǎo)致其安裝不成功

    MYSQL 沒(méi)有完全卸載將導(dǎo)致其安裝不成功

    安裝MYSQL不成功,一般是因?yàn)榉?wù)器可能安裝過(guò)MYSQL而沒(méi)有完全卸載。
    2009-06-06
  • MySQL?Innodb索引機(jī)制詳細(xì)介紹

    MySQL?Innodb索引機(jī)制詳細(xì)介紹

    這篇文章介紹了MySQL?Innodb索引數(shù)據(jù)結(jié)構(gòu)工作原理。對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2021-11-11
  • SQL?CREATE?INDEX提高數(shù)據(jù)庫(kù)檢索效率的關(guān)鍵步驟詳解

    SQL?CREATE?INDEX提高數(shù)據(jù)庫(kù)檢索效率的關(guān)鍵步驟詳解

    這篇文章主要為大家介紹了SQL?CREATE?INDEX提高數(shù)據(jù)庫(kù)檢索效率的關(guān)鍵步驟詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-12-12
  • mysql使用instr達(dá)到in(字符串)的效果

    mysql使用instr達(dá)到in(字符串)的效果

    本文主要介紹了mysql使用instr達(dá)到in(字符串)的效果,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2022-04-04
  • mysql中字段類型轉(zhuǎn)義方式

    mysql中字段類型轉(zhuǎn)義方式

    這篇文章主要介紹了mysql中字段類型轉(zhuǎn)義方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-12-12
  • MySql如何使用not in實(shí)現(xiàn)優(yōu)化

    MySql如何使用not in實(shí)現(xiàn)優(yōu)化

    這篇文章主要介紹了MySql如何使用not in實(shí)現(xiàn)優(yōu)化,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-03-03
  • MySQL多表關(guān)聯(lián)查詢相關(guān)練習(xí)題

    MySQL多表關(guān)聯(lián)查詢相關(guān)練習(xí)題

    這篇文章主要給大家介紹了關(guān)于MySQL多表關(guān)聯(lián)查詢的相關(guān)資料,在MySQL中JOIN語(yǔ)句是實(shí)現(xiàn)多表關(guān)聯(lián)查詢的關(guān)鍵,它可以將多個(gè)表格中符合條件的數(shù)據(jù)連接在一起,從而提供一個(gè)完整的查詢結(jié)果,需要的朋友可以參考下
    2023-10-10
  • MySql Error 1698(28000)問(wèn)題的解決方法

    MySql Error 1698(28000)問(wèn)題的解決方法

    這篇文章主要介紹了MySql Error 1698(28000)問(wèn)題的解決方法,需要的朋友可以參考下
    2017-06-06
  • MySQL exists 和in 詳解及區(qū)別

    MySQL exists 和in 詳解及區(qū)別

    本文章向大家介紹MySQL exists 和in 使用方法以及他們之間的區(qū)別,需要的朋友可以參考下
    2017-01-01

最新評(píng)論