深入浅出MySQL
1.?數據庫事務ACID四大特性
MySQL主要通過日志及鎖實現事務的ACID特性。
A-atomicity?原子性,也稱不可分割性
數據庫依賴 redo / undo 日志實現事務的原子性。
簡單來說,redo 日志記錄事務后的修改數據, undo 日志記錄事務前的原始數據。在恢復時,數據庫先檢查事務中斷在什么階段:如果事務中斷在 commit 階段,則重放 redo 日志;如果中斷在 prepare 階段,則利用 undo 日志進行回滾。
數據庫用 檢查點(check-point)確定事務的恢復位點。檢查點代表:在這一點之前提交的事務所修改的數據已經全部寫回磁盤。因此,數據庫故障后只要找到最近一次檢查點,就可以從這個位置開始處理 redo / undo 日志。
C-consistency?一致性
用類型檢查、唯一索引、外鍵約束和級聯更新保護數據的完整性
I-isolation?隔離性,又稱獨立性
實現事務隔離的主要手段是鎖。另外一個關鍵技術是 MVCC (Multi-version Concurrency Control), 它可以在一些場景避免加鎖, 實現同時讀寫(詳見下文【數據庫事務的隔離級別】)
D-durability?持久性
數據庫的持久化依賴磁盤和數據復制機制
2.?數據庫事務的隔離級別
Read uncommitted?- 讀未提交。讀不需要加鎖,寫僅僅需要加行鎖。
會出現臟讀問題:在一個事務處理過程中讀取了另一個未提交的事務中的數據
Read committed?- 讀已提交。需要加寫鎖,讀必須等待寫事務結束。
會存在不可重復讀問題:對于數據庫中的某個數據,一個事務范圍內多次查詢卻返回了不同的數據值,這是由于在查詢間隔,被另一個事務修改并提交了。
不可重復讀和臟讀的區別是,臟讀是某一事務讀取了另一個事務未提交的臟數據,而不可重復讀則是讀取了前一事務提交的數據。
在某些情況下,不可重復讀并不是問題,比如我們多次查詢某個數據當然以最后查詢得到的結果為主。
Repeatable reads?- 可重復讀。需要加讀鎖,當有事務在讀一行記錄,其他寫同一行的事務都會阻塞,就是在開始讀數據(事務開啟)時,不再允許修復操作。
不可重復讀對應的是修改,即UPDATE操作。但是可能還會有幻讀問題。因為幻讀問題對應的是插入INSERT操作,而不是UPDATE操作。
Serializable?- 串行化。需要加范圍鎖,當有事務 SELECT 某個范圍的數據時,其他訪問同一范圍的事務都會阻塞。
序列化是最高的事務隔離級別,在該級別下,事務串行化順序執行,可以避免臟讀、不可重復讀與幻讀。但是這種事務隔離級別效率低下,比較耗數據庫性能,一般不使用
大多數數據庫默認的事務隔離級別是Read committed,比如Sql Server ,?Oracle。
Oracle數據庫中,只支持Serializable (串行化)級別和Read committed (讀已提交)這兩種級別,其中默認的為Read committed級別
MySQL的默認隔離級別是Repeatable read。
四種隔離級別對應可以避免的問題(不過級別越高,執行效率就越低):
① Serializable (串行化):可避免臟讀、不可重復讀、幻讀的發生。
② Repeatable read (可重復讀):可避免臟讀、不可重復讀的發生。
③ Read committed (讀已提交):可避免臟讀的發生。
④ Read uncommitted (讀未提交):最低級別,任何情況都無法保證。
3.?數據庫表結構設計三范式(Normal Form)
◆ 第一范式(1NF):強調的是列的原子性,即列不能夠再分成其他幾列。
◆ 第二范式(2NF):首先是 1NF,另外包含兩部分內容,一是表必須有一個主鍵;二是沒有包含在主鍵中的列必須完全依賴于主鍵,而不能只依賴于主鍵的一部分。不符合 2NF 的設計容易產生冗余數據。
◆ 第三范式(3NF):首先是 2NF,另外非主鍵列必須直接依賴于主鍵,不能存在傳遞依賴。即不能存在:非主鍵列 A 依賴于非主鍵列 B,非主鍵列 B 依賴于主鍵的情況。
第二范式(2NF)和第三范式(3NF)的概念很容易混淆,區分它們的關鍵點在于,
2NF:非主鍵列是否完全依賴于主鍵,還是依賴于主鍵的一部分;
3NF:非主鍵列是直接依賴于主鍵,還是直接依賴于非主鍵列。
?
4.?數據庫系統檢查
##查詢數據庫隔離級別SELECT @@tx_isolation; ##查詢數據庫是否自動提交事務:1-是SELECT @@autocommit;?##查詢數據庫進程SHOW PROCESSLIST;?##查殺死鎖進程SELECT * FROM information_schema.innodb_trx;KILL 123; ## trx_id?##EXPLAIN 檢查SQL執行計劃##使用explain可以查看該SQL語句有沒有使用索引,有沒有做全表掃描EXPLAIN select * from user;總結
- 上一篇: Java文件读写操作指定编码方式防乱码
- 下一篇: hrbust/哈理工oj 1475国王的