MySQL基礎篇


數據庫基礎知識

以MySQL為基礎


  1. 數據庫事務 :數據庫中一組原子性的SQL操作,彼此狀態一致。具有ACID特性。

  2. 事務 ACID 特性:

    • 原子性:數據庫事務是一個整體,其中的SQL操作要么全部提交成功commit要么全部失敗回滾rollback,不可分割;
    • 一致性:與原子性有聯系。事務總是從一個一致狀態轉換到另一個一致狀態;
    • 隔離性:事務之間彼此互不影響,一個事務在提交之前,對其他事務是不可見的。
    • 持久性:一個事務一旦提交成功,他所做的修改就會永久性的存儲在數據庫中。
  3. MySQL 4 種隔離級別

    • 未提交讀READ UNCOMMITTED:一個事務在提交之前,對其他事務是可見的,即事務可以讀取未提交的數據。存在“臟讀”(讀到了臟數據)問題;
    • 提交讀READ COMMITTED:事務在提交之前,對其它事務是不可見的。存在“不可重復讀”(兩次查詢的得到的結果可能不同,即可能在查詢的間隙,有事務提交了修改)問題。解決了“臟讀”問題。
    • 可重復讀REPEATABLE READ:在同一事務中多次讀取的數據是一致的。解決了臟讀和不可重復讀問題,存在“幻讀”(在事務兩次查詢間隙,有其他事務又插入或刪除了新的記錄)。--- MySQL默認隔離級別。
    • 可串行化SERIALIZABLE:強制事務串行化執行。即一個事物一個事物挨個來執行,可以解決上述所有問題。
  4. 鎖及粒度:

    • 共享鎖/讀鎖:互不阻塞,優先級低
    • 排他鎖/寫鎖:阻塞其他鎖,優先級高,即確保在一個事務寫入時不受其他事務的影響。
    • 鎖粒度:鎖定的數據量越少(粒度越小),並發程度越高,但相應的加鎖、檢測鎖、釋放鎖用的系統開銷也隨之增大。
    • 鎖策略:鎖開銷與數據安全性之間的平衡
      • 表鎖:鎖住整張表,讀鎖互不阻塞,寫鎖阻塞其他所有讀寫鎖(同一張表)。開銷最小。
      • 行級鎖:對每一行數據(記錄)加鎖,開銷大,並發程度高。
  5. InnoDB對死鎖的處理:此處死鎖與OS死鎖類似,多個事務互相持有對方所有要申請資源的鎖不釋放,造成環路死鎖。MySQL InnoDB引擎檢測到死鎖循環依賴后,回滾持有最少行級鎖的事務。

  6. 索引及其作用和實現方法:

    • 概念:對數據庫表列進行增加恰當索引,可以快速的找到匹配的記錄行數,相比於默認的全表掃描,可以大大加快查找的速度。
    • 作用:加快查找速度;
    • 實現方法:一般分為B+樹索引和哈希索引。
      • B+樹索引:在B-tree上改進得到,其非葉子節點均為key值,葉子節點是key-data鍵值對。葉子節點前后相連且有序。
      • 哈希索引:通過對key進行hash(crc/MD5/sha1/sha256...)而將記錄存儲在不同的bucket種,可以做到常數時間的查找,但要注意哈希沖突的避免(鏈表法、線性探測、二次探測、公共溢出區的方法)。其中MD5 128位,和sha1/256碼都較長不太適合作為hash函數。默認無序。
      • 為什么有了B+樹索引還要hash索引?
        1. B+樹默認有序,hash默認無序,所以哈希索引無法用於排序;
        2. 哈希索引O(1)在速度上毋庸置疑要快於B+樹近似O(logn);
        3. 哈希索引只能進行等值查詢(因為他要計算hash(key)再去匹配)而B+樹索引可以進行等值、部分前綴、范圍查詢;
        4. 底層實現結構不同:B+樹是非線性結構,hash桶是線性結構。
        5. 對於某些場景如熱點頁/活躍查詢頁,需要借助哈希索引來實現快速查詢。
    • 索引越多越快?
      此言差矣,索引並非是虛無縹緲的,是實實在在的一種數據結構(B+樹/hash桶)要占內存、維護它要系統開銷,一般的插入刪除都要進行結構的調整,這要消耗時間,所以索引太多反而拖慢查找時間。有時候,見數據量不多時,建立索引還不如全表查詢。索引加快了檢索的速度,但是插入刪除修改都需要DBMS動態更新內部索引結構,要耗費開銷。
  7. InnoDB MVCC
    多版本並發控制,是為了避免加鎖而實現的。一般的實現方法是存儲快照來實現的。InnoDB實現方式是在記錄后添加兩個隱藏列(表項),分別是事務創建時間、過期時間,存儲的實際上是系統版本號(系統版本號隨着事務的創建而遞增)。
    這樣一來,INSERT 時加上開始版本號,UPDATE/DELETE時加上過期版本號,這樣一來在SELETE時,就只訪問開始系統版本號小於當前的事務的版本號、過期時間要么未定義要么在當前版本號之后的記錄,這樣就可以保證:訪問的記錄是在本事務開始前就存在而且在本事務期間沒有過期(被刪除或被修改過的)。可以避免臟讀、不可重復讀、幻讀的問題。(個人覺得)

  8. MySQL存儲引擎簡介

    • InnoDB,最為通用/推薦的一種引擎,支持事務、行級鎖、甚至間隙鎖(避免幻讀)、支持熱備份,MVCC,在並發上占優勢,系統資源占用多。
    • MyISAM,默認的存儲引擎,不支持事務和行級鎖,只支持表鎖,某些場景性能很好:占用存儲上優,查詢速度上完勝(大概是InnoDB的3倍)系統資源占用少。
    • InnoDB支持事務, MyISAM不支持;
    • InnoDB支持行級鎖、表鎖;MyISAM只支持表鎖;
    • InnoDB支持MVCC,MyISAM不支持;
    • InnoDB不支持全文索引,MyISAM支持;
    • InnoDB支持外鍵,MyISAM不支持外鍵;
    • InnoDB和MyISAM都支持B+樹索引,InnoDB還支持自適應哈希索引
    • MyISAM實現了前綴壓縮技術,占用存儲空間更小(但會影響查找),InnoDB是原始數據存儲,占用存儲更大。

    PS:大部分情況下,InnoDB都是正確的選擇。---《高性能MySQL》

  9. SQL優化

    • 在經常性的檢索列上,建立必要索引,以加快搜索速率,避免全表掃描(索引覆蓋掃描);
    • 多次查詢同樣的數據,可以考慮緩存該組數據;
    • 審視select * form tables, 你需要所有列數據嗎?
    • 切分查詢(大查詢切分成為小查詢,避免一次性鎖住大量數據)
    • 分解關聯查詢(單表查詢,結果在應用程序中進行關聯,可以減少處理過程中的鎖爭用)
    • 盡量先做單表查詢;
    • ...
  10. profile 的作用和用法
    用於保存SQL語句執行狀態,需要手動開啟,才可以查看。

set profiling = 1; 開啟
show profiles; 顯示SQL查詢的profiles概況
show profile all for query X; 查看第X條語句的所有執行情況。
show profile cpu, block io, memory for query X; 查看部分profile信息。

  1. MySQL查詢的步驟
    • 客戶端發送查詢到服務器;
    • 服務器檢查查詢緩存query cache(大小寫敏感的哈希查找,常數時間)。如果命中,返回緩存中的結果,否則下一步;
    • 解析語句,生成執行計划;(SQL解析,預處理,優化器生成執行計划);
    • 根據執行計划,根據存儲引擎的不同調用API,執行查詢(一棵指令樹);
    • 結果返回客戶端。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM