Mysql

1. MySQL的索引

1.1 索引的數(shù)據(jù)結(jié)構(gòu)

B+樹

多路平衡查找樹询筏,路數(shù)(degree) = 數(shù)據(jù)頁一頁大小 / 索引數(shù)據(jù)大小

MySql 默認一頁大小是16k = 4 * 操作系統(tǒng)頁(4KB)

1.2 MySQL常見的存儲引擎

MyISAM

tableName.frm(建表文件)

tableName.myd(my-data 存放數(shù)據(jù))

tableName.myi (my-index 存放索引)

InnoDB

tableName.frm

tableName.idb

可以看出 InnoDB數(shù)據(jù)和索引是放在同一個文件里渠鸽,按照主鍵來組織數(shù)據(jù)的存儲涝涤。所以主鍵索引才又叫聚集索引训柴。

如果創(chuàng)建表沒有指定哪一列做索引龙助,InnoDB將自動生成一個6byte int型的隱藏主鍵捉邢。

主鍵索引的葉子節(jié)點數(shù)據(jù)區(qū)保存數(shù)據(jù),其他索引的葉子節(jié)點數(shù)據(jù)區(qū)保存主鍵

CSV

tableName.frm

tableName.CSV (保存元數(shù)據(jù))

tableName.CSM (數(shù)據(jù)行吮螺,可以用vi直接編輯)

1.3 索引選擇原則

經(jīng)常用的列優(yōu)先(最左匹配原則)

離散度高的列優(yōu)先

寬度小的列優(yōu)先(一個數(shù)據(jù)頁的degree越多饶囚,提高樹的查找效率)

覆蓋索引:要查詢的值正好包含在索引中,從而不需要找到葉子節(jié)點鸠补。所以如果查詢能通過命中聯(lián)合索引直接返回的萝风,一定不要用select *;

2. MySQL查詢執(zhí)行路徑

  1. 客戶端發(fā)送查詢請求

  2. 查詢緩存(可配可無)

  3. 查詢優(yōu)化處理

  4. 查詢執(zhí)行引擎

  5. 返回客戶端

MySQL查詢執(zhí)行路徑

2.1 客戶端與服務(wù)端的通信

半雙工: 在任意一個時刻,要么是客戶端接收服務(wù)端返回的數(shù)據(jù)紫岩,要么是客戶端向服務(wù)端發(fā)送數(shù)據(jù)规惰,這兩個動作不能同時發(fā)生。也無法將一個消息切成小塊進行傳輸被因。

客戶端一旦開始接收數(shù)據(jù)就沒有辦法停下來發(fā)送指令卿拴。

對于一個MySQL連接衫仑,時刻都有一個狀態(tài)來標識這個連接正在做什么

show full processlist / show processlist

常見狀態(tài)有:

  • Sleep : 線程正在等待客戶端發(fā)送數(shù)據(jù)
  • Query:連接線程正在執(zhí)行查詢
  • Locked: 線程正在等待表鎖的釋放
  • Sorting result: 線程正在對結(jié)果進行排序
  • Sending data : 向請求端返回數(shù)據(jù)

2.2 緩存

MySQL能緩存select操作的結(jié)果集和SQL語句梨与。對于新的SELECT語句,先去查緩存文狱,判斷是否有可用的記錄集粥鞋。

判斷標準為:與緩存的SQL語句完全一樣,區(qū)分大小寫瞄崇。即必須一毛一樣呻粹,可以簡單認為存儲了一個key-value的結(jié)構(gòu),key為SQL語句苏研,value為SQL執(zhí)行結(jié)果集等浊。

可以通過如下命令查看緩存情況

show status like 'Qcache%'

緩存配置項:

  • query_cache_type

    0 - 不啟用 (默認值)

    1- 啟用查詢緩存。但可以通過加上SQL_NO_CACHE不緩存

    2- 啟用摹蘑。但需要在SQL上加SQL_CACHE才緩存

  • query_cache_size

    緩存區(qū)的大小筹燕,默認1M。推薦64/128M

  • query_cache_limit

    單個結(jié)果集可使用的緩存大小衅鹿,結(jié)果大于該值則不緩存撒踪。默認1M

為什么mysql默認關(guān)閉了緩存呢?

  1. 在查詢之前要先檢查是否命中緩存大渤,浪費計算資源
  2. 如果這個查詢可以被緩存制妄,那么執(zhí)行完成后,MySQL發(fā)現(xiàn)緩存中沒有這個查詢泵三,將會把結(jié)果集放入緩存中耕捞,帶來額外的系統(tǒng)消耗
  3. 最重要的一點衔掸,當對表進行寫入和更新操作時,該表對應(yīng)的所有緩存都將失效

所以俺抽,MySQL的緩存只適合以讀為主的業(yè)務(wù)場景具篇,數(shù)據(jù)生成之后就不常變的業(yè)務(wù)。比如 新聞凌埂、報表類驱显、門戶類等

2.3 查詢優(yōu)化處理

2.3.1 查詢優(yōu)化處理的三個階段
  • 解析SQL

    將sql語句解析成解析樹

  • 預(yù)處理階段

    根據(jù)MySQL的語法規(guī)則進一步檢查解析樹的合法性。比如檢查表和數(shù)據(jù)列是否存在瞳抓,解析列名和別名等

  • 查詢優(yōu)化器

    找到最優(yōu)的執(zhí)行計劃

那么埃疫,查詢優(yōu)化器是怎么找到最優(yōu)的執(zhí)行計劃呢?

MySQL的查詢優(yōu)化器是基于成本計算的原則孩哑。它會嘗試各種執(zhí)行計劃數(shù)據(jù)抽樣的方式進行試驗栓霜,隨機讀取一個4K的數(shù)據(jù)塊進行分析。

一些優(yōu)化手段

  • 等價變化規(guī)則: 基于聯(lián)合索引横蜒,調(diào)整位置等
  • 優(yōu)化count胳蛮、min、max等函數(shù):
  • 覆蓋索引掃描
  • 子查詢優(yōu)化
  • 提前終止查詢 : limit
  • IN的優(yōu)化 : 先進行排序丛晌,再采用二分查找
2.3.2 怎么看執(zhí)行計劃

可以通過explain查看執(zhí)行計劃仅炊,執(zhí)行計劃的幾個關(guān)鍵參數(shù):

  1. id

    id代表select查詢的序號,標識執(zhí)行的順序

    • id相同澎蛛,執(zhí)行順序由上往下抚垄。id相同的可以認為是一組
    • id不同,如果是子查詢谋逻,id的序號會遞增呆馁,id值越大優(yōu)先級越高,越先執(zhí)行
  2. select_type

    select_type標識查詢的類型毁兆,可以區(qū)分普通查詢浙滤、聯(lián)合查詢、子查詢等

    • SIMPLE :簡單的select查詢气堕,查詢中不包含子查詢或者union查詢
    • PRIMARY: 對于包含子查詢的sql纺腊,外層查詢將被標記為PRIMARY
    • SUBQUERY:表示在select或where列表中包含子查詢
    • MATERIALIZED: 表示在where后面 in條件的子查詢
    • UNION:若第二個select出現(xiàn)在union之后,則被標記為union
    • UNION RESULT: 從union表獲取結(jié)果的select
  3. table

    查詢設(shè)計到的表送巡,一般直接顯示表名或別名

    • <unionM,N>由id為M,N查詢聯(lián)合產(chǎn)生的結(jié)果
    • <subqueryN> 由id為N的查詢產(chǎn)生的結(jié)果
  4. type

    訪問類型摹菠,它在查詢優(yōu)化中是一個很重要的指標,結(jié)果從好到壞依次是:

    • system:表只有一行記錄骗爆,或系統(tǒng)表次氨,
    • const: 表示通過一次索引就找到了,用于比較primary key或者unique key
    • eq_ref:唯一索引掃描摘投,對于每個索引健煮寡,表中只有一條記錄與之匹配
    • ref:非唯一索引掃描虹蓄,返回匹配某個單獨值的所有行
    • range : 只檢索給定范圍的行
    • index:full index scan。索引全表掃描
    • ALL :full table scan幸撕。
  5. possible_keys, key, rows, filtered

    • possible_keys :查詢過程中有可能用到的索引
    • key: 實際使用的索引
    • rows:大致估算找到所需記錄要讀取的行數(shù)
    • filtered:結(jié)果行數(shù)占所需要讀取rows行數(shù)的百分比薇组。filtered越大越好
2.3.3 Extra

執(zhí)行計劃中的額外信息

  1. using filesort

    MySQL對數(shù)據(jù)使用一個外部的文件內(nèi)容進行排序,而不是按照表內(nèi)的索引進行排序讀取

  2. Using temporary

    使用臨時表保存中間結(jié)果坐儿,常見于order by 或 group by

  3. Using index:

    表示select操作中使用了覆蓋索引律胀,避免了訪問表的數(shù)據(jù)行

  4. Using where

    使用了where過濾條件

  5. select tables optimized away

    基于索引優(yōu)化MIN/MAX操作或者MyISAM存儲引擎優(yōu)化COUNT(*)操作, 不必等到執(zhí)行階段在進行計算貌矿, 查詢執(zhí)行計劃生成的階段即可完成優(yōu)化

2.4 查詢執(zhí)行引擎

調(diào)用插件式的存儲引擎API執(zhí)行 執(zhí)行計劃

2.5 返回客戶端

  1. 需要做緩存的炭菌,執(zhí)行緩存操作

  2. 增量的返回結(jié)果給客戶端:

    開始生成第一條結(jié)果時,MySQL就開始往請求方逐步返回數(shù)據(jù)逛漫。

    這么做的好處是:MySQL服務(wù)器無需保存過多的數(shù)據(jù)黑低,從而浪費內(nèi)存;用戶體驗好酌毡,拿到數(shù)據(jù)快

3. 如何定位慢SQL

3.1.1 慢查詢?nèi)罩九渲?/h5>
#查看是否開啟慢查詢?nèi)罩?show variables like 'slow_query_log'
#開啟慢查詢?nèi)罩?set global slow_query_log=on
#設(shè)置慢查詢?nèi)罩疚募窂?set global slow_query_log_file='/var/lib/mysql/slow.log'
#將沒有使用索引的查詢記錄到日志
set global log_queries_not_using_indexes=on
#設(shè)置慢查詢閾值克握,單位:秒
set global long_query_time=10 
3.2.2 慢查詢?nèi)罩痉治龉ぞ?/h5>
mysqldumpslow --help

4. 事務(wù)

事務(wù)是數(shù)據(jù)庫操作的最小工作單元,是一組不可再分的邏輯工作單元枷踏。

#開啟事務(wù)
begin/start transaction --手工開啟一個事務(wù)
#事務(wù)提交或回滾
commit/rollback
#設(shè)置事務(wù)自動開啟
set session autocommit = on/off;

4.1 事務(wù)的ACID特性

  • Automicity 原子性

    最小的工作單元菩暗,整個工作單元要么一起提交成功,要么全部失敗回滾

  • Consistency 一致性

    事務(wù)中操作的數(shù)據(jù)及狀態(tài)改變是一致的呕寝,即寫入資料的結(jié)果必須完全符合預(yù)設(shè)的規(guī)則婴梧。不會因為出現(xiàn)系統(tǒng)意外等原因?qū)е聽顟B(tài)的不一致

  • Isolation 隔離性

    一個事務(wù)所操作的數(shù)據(jù)在提交之前孽江,對其他事務(wù)的可見性設(shè)定(一般設(shè)定為不可見)

  • Durability 持久性

    事務(wù)所作的修改就會永久保存,不會因為系統(tǒng)意外導(dǎo)致數(shù)據(jù)的丟失

4.2 事務(wù)并發(fā)帶來的問題

  • 臟讀 :事務(wù)A讀到事務(wù)B 本該rollback的 內(nèi)容

    ![臟讀]
    臟讀.jpg
  • 不可重復(fù)讀:

    事務(wù)A先讀取某一條數(shù)據(jù),在執(zhí)行自己邏輯的過程中暇屋,事務(wù)B修改了這條數(shù)據(jù)并提交事務(wù)昙衅。然后事務(wù)A再次讀取該記錄,發(fā)現(xiàn)兩次數(shù)據(jù)不一致了啼县。

不可重復(fù)讀.jpg
  • 幻讀
幻讀.jpg

4.3 事務(wù)的隔離級別

根據(jù)SQL92 ANSI/ISO標準:

  • Read Uncommitted (未提交讀谭羔、讀未提交)

    事務(wù)未提交對其他事務(wù)也是可見的瘟裸,未解決任何并發(fā)問題

  • Read Committed 提交讀

    一個事務(wù)開始之后话告,只能看到已提交的事務(wù)所做的修改。解決了臟讀問題病线,存在不可重復(fù)讀

  • Repeatable Read 可重復(fù)度

    在同一個事務(wù)中暖眼,多次讀取同樣的數(shù)據(jù)結(jié)果是一樣的司澎,解決不可重復(fù)度問題挤安。但這種隔離級別未定義解決幻讀的問題

  • Serializable 串行化

    最高的隔離級別蛤铜,每個事務(wù)串行執(zhí)行 ,解決所有問題

總結(jié)

隔離級別 臟讀 不可重復(fù)讀 幻讀
未提交讀(Read Uncommitted) 可能 可能 可能
已提交讀(Read Committed) 不可能 可能 可能
可重復(fù)讀(Repeatable Read) 不可能 不可能 對InnoDB不可能
串行化(Serializable) 不可能 不可能 不可能

5. 鎖

鎖是用來管理不同事務(wù)對共享資源的并發(fā)訪問

5.1 表鎖昂羡、行鎖

表鎖與行鎖的區(qū)別:

鎖定粒度:表鎖 > 行鎖

加鎖效率:表鎖 > 行鎖

沖突概率:表鎖 > 行鎖

并發(fā)性能:表鎖 < 行鎖

InnoDB存儲引擎支持行鎖和表鎖(另類的行鎖)

5.2 InnoDB的鎖

  • 共享鎖(行鎖): Shared Locks
  • 排他鎖(行鎖):Exclusive Locks
  • 意向共享鎖(表鎖):Intention Shared Locks
  • 意向排他鎖(表鎖):Intention Exclusive Locks
  • 自增鎖: AUTO-INC Locks

其中,行鎖的算法

  • 記錄鎖 Record Locks
  • 間隙鎖 Gap Locks
  • 臨鍵鎖 Next-key Locks
5.2.1 共享鎖 VS 排他鎖
  • 共享鎖

共享鎖又稱讀鎖虐先,簡稱S(shared)鎖。顧名思義蛹批,共享鎖是多個事務(wù)對于同一數(shù)據(jù)可以共享一把鎖撰洗,都能訪問到數(shù)據(jù)差导,但是只能讀不能修改

加鎖方式:

select * from users where id = 1 Lock IN SHARE MODE;
  • 排他鎖

排他鎖又稱寫鎖,簡稱X鎖椅您,排他鎖不能與其他鎖并存雪隧,如一個事務(wù)獲取了一個數(shù)據(jù)行的排他鎖,其他事務(wù)就不能再獲取該行的鎖(不管是共享鎖還是排他鎖)员舵。只有該獲取了排他鎖的事務(wù)可以對這行數(shù)據(jù)進行讀取和修改脑沿。其他事務(wù)要讀取數(shù)據(jù)可來自于快照。

加鎖方式:

# for update 加X鎖固灵。 delete/update/insert默認加X鎖
select * from users where id = 1 for update;

InnoDB的行鎖到底鎖了什么捅伤?

InnoDB的行鎖是通過給索引上的索引項加鎖來實現(xiàn)的。只有通過索引條件進行數(shù)據(jù)檢索巫玻,InnoDB才使用行級鎖,否則祠汇,InnoDB將使用表鎖(鎖住索引的所有記錄)

5.2.2 意向共享鎖 和意向排他鎖
  • 意向共享鎖 IS:

    表示事務(wù)準備給數(shù)據(jù)行加入共享鎖仍秤。即,一個數(shù)據(jù)行要想加共享鎖之前可很,必須先取得該表的意向共享鎖诗力,意向共享鎖之間是可以互相兼容的。

  • 意向排他鎖 IX:

    表示事務(wù)準備給數(shù)據(jù)行加入排他鎖。即苇本,一個數(shù)據(jù)行加排他鎖之前必須先取得該表的IX鎖袜茧,意向排他鎖之間是可以相互兼容的。

    意向鎖是InnoDB操作數(shù)據(jù)之前自動加的瓣窄,不需要用戶干預(yù)笛厦。當一個事務(wù)想去進行表鎖時,可以先判斷意向鎖是否存在俺夕,如果存在則可以快速返回該表不能啟用表鎖裳凸。

5.2.3 自增鎖 AUTO-INC Locks

自增鎖是針對自增列自增長的一個特殊的表級別鎖

show variables like 'innodb_autoinc_lock_mode'

默認取值為1,代表連續(xù)劝贸,若事務(wù)未提交則ID永久丟失

5.3 鎖的算法

前面我們說InnoDB的行鎖是采用記錄鎖姨谷、間隙鎖臨鍵鎖來實現(xiàn)的映九,那么這三者又是什么呢梦湘?

5.3.1 記錄鎖 Record Locks

記錄鎖的功能是鎖住具體的索引項。當sql執(zhí)行按照唯一性索引(Primary Key 件甥、Unique Key)進行數(shù)據(jù)的檢索時践叠,查詢條件等值匹配且要查詢的數(shù)據(jù)存在,這時SQL語句加上的鎖即為記錄鎖Record Locks嚼蚀,鎖住這行索引項禁灼。

例如:數(shù)據(jù)庫中存在2條記錄

id name age
1 Alice 20
2 Bob 22

事務(wù)A鎖住id為1的記錄即給主鍵索引為1的記錄加了一個記錄鎖。

5.3.2 間隙鎖 Gap Locks

當sql執(zhí)行按照索引進行數(shù)據(jù)的檢索時轿曙,若查詢條件的數(shù)據(jù)不存在弄捕,這時SQL語句加上的鎖即為Gap Locks , 鎖住索引不存在的這段區(qū)間,且左開右開导帝。

如:數(shù)據(jù)庫user表存在3條記錄:

id name age
1 Alice 20
2 Bob 22
5 Charlie 22

事務(wù)A嘗試獲取id=4 的鎖守谓,sql語句為:

# 事務(wù)A
begin;
select * from users where id = 4 for update;
#先獲取鎖 rollback先不執(zhí)行
rollback;

然后事務(wù)B嘗試插入 id = 3的記錄:

# 事務(wù)B
set session autocommit = off; --設(shè)置會話不自動提交
insert into users values(3,"Eve",20);
rollback;

結(jié)果發(fā)現(xiàn)插表不成功,輸出為:

1205 - Lock wait timeout exceeded; try restarting transaction

時間: 51.035s

再嘗試把id=3 改為 id=4 同樣插不進表您单。更新id=2 或 id=5 均可成功斋荞。由此可以驗證結(jié)論為:間隙是指不存在的那段區(qū)間。鎖住的范圍是左開右開虐秦。 無窮大同理平酿。

5.3.3 臨鍵鎖 Next-Key Locks

臨鍵鎖鎖住的是 記錄+區(qū)間(左開右閉)。當sql執(zhí)行按照索引進行數(shù)據(jù)的檢索時悦陋,若查詢的條件為范圍查找(between a and b蜈彼、< 、>)并有數(shù)據(jù)命中俺驶,則此時的SQL語句加上鎖為臨鍵鎖幸逆。鎖住索引存在的那條記錄 + 不存在的區(qū)間。左開右閉。

所以还绘,InnoDB可以解決幻讀楚昭,當根據(jù)條件范圍檢索時,檢索范圍內(nèi)不存在的數(shù)據(jù)將被鎖住拍顷,所以不可能插入新記錄進去抚太。

InnoDB采用臨鍵鎖作為行鎖的默認算法

當記錄不存在菇怀,臨鍵鎖可退化成Gap鎖凭舶;當條件精準匹配到記錄,則退化成Record鎖爱沟。

5.4 數(shù)據(jù)庫的死鎖

死鎖發(fā)生的條件:

  • 多個并發(fā)事務(wù)(2個及以上)
  • 每個事務(wù)都持有鎖或在等待鎖
  • 每個事務(wù)都需要繼續(xù)再持有鎖
  • 事務(wù)之間產(chǎn)生加鎖的循環(huán)等待帅霜,形成死鎖

避免死鎖:

  • 類似的業(yè)務(wù)邏輯以固定的順序訪問表和數(shù)據(jù)行

  • 大事務(wù)拆成小事務(wù)。一般大事務(wù)更容易產(chǎn)生死鎖呼伸,業(yè)務(wù)允許的話把大事務(wù)拆成小事務(wù)

  • 在同一個事務(wù)中身冀,盡可能做到一次性鎖定所有需要的資源,減少死鎖概率

  • 如果業(yè)務(wù)允許可以降低隔離級別

  • 為表添加合理的索引括享÷Ц可以看到如果不走索引將會為表添加表鎖。

了解完鎖的特性后铃辖,再看下面這個例子:

begin;--事務(wù)A
update users set age = 0 where id = 1; -- 上X鎖
select * from users where id =1; -- 結(jié)果: 1剩愧,Alice,0
-- age = 0的數(shù)據(jù)存到哪兒去了?
rollback;

事務(wù)B在事務(wù)A 提交或rollBack之前娇斩,查到的永遠是正確的1仁卷,Alice,20犬第。

是不是有這樣的疑問:為什么給id=1 的記錄加上X鎖后锦积,別的事務(wù)還是能對它進行查詢呢?快照是什么歉嗓?它怎么實現(xiàn)的丰介?

6. MVCC

MVCC ,Multi version concurrency control 鉴分,多版本并發(fā)控制哮幢。

并發(fā)訪問數(shù)據(jù)庫時,對正在事務(wù)內(nèi)處理的數(shù)據(jù)做多版本的管理冠场,以避免寫操作的堵塞造成無法讀的并發(fā)問題家浇。

6.1 增刪改查對應(yīng)的MVCC

MVCC: 一張表設(shè)計完以后,MySQL默認給每一行自動生成DB_TRX_ID(數(shù)據(jù)入庫時事務(wù)版本號)碴裙,DB_ROLL_PT(數(shù)據(jù)刪除時的版本號)。

6.1.1 插入

假設(shè)當前的全局事務(wù)ID為1,

begin; -- 拿到當前系統(tǒng)的事務(wù)ID
insert users(id,name,age) values(1,"Alice",20);
insert users(id,name,age) values(2,"Bob",21);
commit;

此時舔株,表中記錄的包括版本相關(guān)的信息為:

id name age DB_TRX_ID DB_ROLL_PT
1 Alice 20 1 NULL
2 Bob 21 1 NULL
6.1.2 刪除

假設(shè)當前的系統(tǒng)全局事務(wù)ID已經(jīng)到了10. 再此之前沒有其他事務(wù)操作過id=1 的記錄

begin;  -- 拿到事務(wù)ID=10
delete users where id = 1;
commit;

事務(wù)提交后莺琳,id = 1的記錄 DB_ROLL_PT = 10. MVCC相關(guān)信息變成:

id name age DB_TRX_ID DB_ROLL_PT
1 Alice 20 1 10
2 Bob 21 1 NULL
6.1.3 修改

修改操作是先做命中數(shù)據(jù)行的復(fù)制,然后將原來那行數(shù)據(jù)的刪除版本號設(shè)置為當前的事務(wù)ID载慈。假設(shè)當前全局ID到了20惭等,事務(wù)執(zhí)行:

begin; -- 拿到事務(wù)ID=20
update users set age = 20 where id = 2;
commit;

事務(wù)提交后,

id name age DB_TRX_ID DB_ROLL_PT
1 Alice 20 1 10
2 Bob 21 1 20
2 Bob 20 20 NULL
6.1.4 查詢

查詢數(shù)據(jù)行版本小于當前查詢的事務(wù)版本办铡,這樣就確保了只能讀取到在本次事務(wù)開始之前就已經(jīng)存在的數(shù)據(jù)辞做;另外,數(shù)據(jù)行的刪除版本要么為NULL寡具,要么大于本次查詢版本號秤茅,確保取出的記錄在本次查詢開始之前沒有被刪除。

但是如果事務(wù)A(tx_id=2)查詢id=1的數(shù)據(jù)童叠,然后處理自己邏輯的同時框喳,事務(wù)B(tx_id = 1)對id=1的數(shù)據(jù)修改并提交了,接著事務(wù)A再次查詢了id=1的數(shù)據(jù)厦坛,MVCC是怎么解決不可重復(fù)讀的五垮?

6.2 Redu / Undo 日志

6.2.1 Undo Log

Undo意思是撤銷,以撤銷操作為目的杜秸,返回某個指定狀態(tài)的操作放仗。

Undo Log是指在事務(wù)開始以前,在任何操作開始之前撬碟,首先將需要操作的數(shù)據(jù)備份到一個地方(Undo Log)诞挨。

Undo Log是為了實現(xiàn)事務(wù)的原子性而出現(xiàn)的產(chǎn)物。事務(wù)處理過程中如果出現(xiàn)了錯誤或用戶執(zhí)行ROLLBACK語句小作,MySQL可以利用Undo Log中的備份將數(shù)據(jù)恢復(fù)到事務(wù)開始之前的狀態(tài)亭姥。即,Undo Log中的數(shù)據(jù)可以作為數(shù)據(jù)舊版本的快照 供其他并發(fā)事務(wù)進行快照讀顾稀。

Undo Log 1.jpg
6.2.2 Redo Log

Redo 的意思是重做达罗。Redo Log 是事務(wù)操作的任何數(shù)據(jù),將最新的數(shù)據(jù)備份到一個地方(Redo Log)静秆。

Redo Log不是隨著事務(wù)的提交才寫的粮揉,而是在事務(wù)的執(zhí)行過程中就開始寫入Redo Buffer中,具體什么時候?qū)懙酱疟P的Redo Log可以通過配置來配抚笔。Innodb_flush_log_at_trx_commit:

  • 0:每秒提交redo buffer->redo log -> flush cache to disk
  • 1:每次事務(wù)提交執(zhí)行全流程redo buffer->redo log -> flush cache to disk
  • 2:每次事務(wù)提交執(zhí)行redo buffer->redo log扶认。 然后每隔一秒執(zhí)行 flush cache to disk

Redo Log是為了確保事務(wù)的持久性而設(shè)計的。為了防止在故障發(fā)生的時候殊橙,尚有臟頁未寫入磁盤辐宾,在重啟MySQL服務(wù)時狱从,根據(jù)Redo Log進行重做,從而使未入磁盤的數(shù)據(jù)再次進行持久化叠纹。

Redo Log.jpg

7. 數(shù)據(jù)庫表設(shè)計 三范式

  • 第一范式(1NF):字段具有原子性季研,不可再分。

  • 第二范式(2NF):屬性完全依賴主鍵誉察,不能出現(xiàn)僅依賴主鍵一部分的屬性与涡,如果出現(xiàn)了,那么這個屬性和主關(guān)鍵字的這部分關(guān)系應(yīng)該分離出來形成一個新的實體持偏。

  • 第三范式(3NF):一個數(shù)據(jù)庫表中不包含已在其他表中已包含的非主鍵信息驼卖。

    簡單點說:

    1NF:每一列只有一個單一的值,不能再拆分

    2NF:每一行都有主鍵進行區(qū)分

    3NF:每一個表都不包含其他表已經(jīng)存在的非主鍵信息

三范式的要求僅為庫表設(shè)計提供一種理論依據(jù)鸿秆,

  • 過分滿足第一范式將為表建立太多的列

  • 過分滿足第三范式將造成太多的表關(guān)聯(lián)

  • 使用外鍵將帶來額外的開銷

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末酌畜,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子谬莹,更是在濱河造成了極大的恐慌檩奠,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,270評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件附帽,死亡現(xiàn)場離奇詭異埠戳,居然都是意外死亡,警方通過查閱死者的電腦和手機蕉扮,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,489評論 3 395
  • 文/潘曉璐 我一進店門整胃,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人喳钟,你說我怎么就攤上這事屁使。” “怎么了奔则?”我有些...
    開封第一講書人閱讀 165,630評論 0 356
  • 文/不壞的土叔 我叫張陵蛮寂,是天一觀的道長。 經(jīng)常有香客問我易茬,道長酬蹋,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,906評論 1 295
  • 正文 為了忘掉前任抽莱,我火速辦了婚禮范抓,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘食铐。我一直安慰自己匕垫,他們只是感情好,可當我...
    茶點故事閱讀 67,928評論 6 392
  • 文/花漫 我一把揭開白布虐呻。 她就那樣靜靜地躺著象泵,像睡著了一般寞秃。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上单芜,一...
    開封第一講書人閱讀 51,718評論 1 305
  • 那天蜕该,我揣著相機與錄音犁柜,去河邊找鬼洲鸠。 笑死,一個胖子當著我的面吹牛馋缅,可吹牛的內(nèi)容都是我干的扒腕。 我是一名探鬼主播,決...
    沈念sama閱讀 40,442評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼萤悴,長吁一口氣:“原來是場噩夢啊……” “哼瘾腰!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起覆履,我...
    開封第一講書人閱讀 39,345評論 0 276
  • 序言:老撾萬榮一對情侶失蹤蹋盆,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后硝全,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體栖雾,經(jīng)...
    沈念sama閱讀 45,802評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,984評論 3 337
  • 正文 我和宋清朗相戀三年伟众,在試婚紗的時候發(fā)現(xiàn)自己被綠了析藕。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,117評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡凳厢,死狀恐怖账胧,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情先紫,我是刑警寧澤治泥,帶...
    沈念sama閱讀 35,810評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站遮精,受9級特大地震影響居夹,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜仑鸥,卻給世界環(huán)境...
    茶點故事閱讀 41,462評論 3 331
  • 文/蒙蒙 一吮播、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧眼俊,春花似錦意狠、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,011評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽闷板。三九已至,卻和暖如春院塞,著一層夾襖步出監(jiān)牢的瞬間遮晚,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,139評論 1 272
  • 我被黑心中介騙來泰國打工拦止, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留县遣,地道東北人。 一個月前我還...
    沈念sama閱讀 48,377評論 3 373
  • 正文 我出身青樓汹族,卻偏偏與公主長得像萧求,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子顶瞒,可洞房花燭夜當晚...
    茶點故事閱讀 45,060評論 2 355

推薦閱讀更多精彩內(nèi)容