1. 程式人生 > 實用技巧 >mysql面試題大全,mysql面試題詳解

mysql面試題大全,mysql面試題詳解

MySQL常見面試題

MySQL事務四大特性

  • 原子性:不可分割的操作單元,事務中所有操作,要麼全部成功;要麼撤回到執行事務之前的狀態
  • 一致性:如果在執行事務之前資料庫是一致的,那麼在執行事務之後資料庫也還是一致的;
  • 隔離性:事務操作之間彼此獨立和透明互不影響。事務獨立執行。這通常使用鎖來實現。一個事務處理後的結果,影響了其他事務,那麼其他事務會撤回。事務的100%隔離,需要犧牲速度。
  • 永續性:事務一旦提交,其結果就是永久的。即便發生系統故障,也能恢復。

MySQL事務隔離級別

未提交讀(Read Uncommitted):允許髒讀,其他事務只要修改了資料,即使未提交,本事務也能看到修改後的資料值。也就是可能讀取到其他會話中未提交事務修改的資料
提交讀(Read Committed):只能讀取到已經提交的資料。Oracle等多數資料庫預設都是該級別 (不重複讀)。
可重複讀(Repeated Read):可重複讀。無論其他事務是否修改並提交了資料,在這個事務中看到的資料值始終不受其他事務影響。
序列讀(Serializable):完全序列化的讀,每次讀都需要獲得表級共享鎖,讀寫相互都會阻塞

MySQL資料庫(InnoDB引擎)預設使用可重複讀( Repeatable read)


MySQL索引相關

資料庫索引,是資料庫管理系統中一個排序的資料結構,以協助快速查詢、更新資料庫表中資料。索引的實現通常使用 B_TREE。B_TREE 索引加速了資料訪問,因為儲存引擎不會再去掃描整張表得到需要的資料;相反,它從根節點開始,根節點儲存了子節點的指標,儲存引擎會根據指標快速尋找資料。

MyISAM引擎使用B+Tree作為索引結構,葉節點的data域存放的是資料記錄的地址,即:MyISAM索引檔案和資料檔案是分離的,MyISAM的索引檔案僅僅儲存資料記錄的地址。MyISAM中索引檢索的演算法為首先按照B+Tree搜尋演算法搜尋索引,如果指定的Key存在,則取出其data域的值,然後以data域的值為地址,讀取相應資料記錄。MyISAM的索引方式也叫做“非聚集”的。

InnoDB引擎也使用B+Tree作為索引結構,但是InnoDB的資料檔案本身就是索引檔案,葉節點data域儲存了完整的資料記錄。這個索引的key是資料表的主鍵,因此InnoDB表資料檔案本身就是主索引。這種索引叫做“聚焦索引”。InnoDB的輔助索引的data域儲存相應記錄主鍵的值而不是地址。換句話說,InnoDB的所有輔助索引都引用主鍵作為data域。聚集索引這種實現方式使得按主鍵的搜尋十分高效,但是輔助索引搜尋需要檢索兩遍索引:首先檢索輔助索引獲得主鍵,然後用主鍵到主索引中檢索獲得記錄。InnoDB的索引實現後,不建議使用過長的欄位作為主鍵,因為所有輔助索引都引用主索引,過長的主索引會令輔助索引變得過大。在Innodb中也不建議使用非單調的欄位作為主鍵,因為InnoDB資料檔案本身是一顆B+Tree,非單調的主鍵會造成在插入新記錄時資料檔案為了維持B+Tree的特性而頻繁的分裂調整,十分低效,建議使用自增欄位作為主鍵。

MySQL資料庫的四類索引:

  index ----普通索引,資料可以重複,沒有任何限制。
  unique----唯一索引,要求索引列的值必須唯一,但允許有空值;如果是組合索引,那麼列值的組合必須唯一。

  primary key----主鍵索引,是一種特殊的唯一索引,一個表只能有一個主鍵,不允許有空值,一般是在建立表的同時建立主鍵索引。

  組合索引----在多個欄位上建立的索引,只有在查詢條件中使用了建立索引時的第一個欄位,索引才會被使用。

  fulltext----全文索引,是對於大表的文字域:char,varchar,text列才能建立全文索引,主要用於查詢文字中的關鍵字,並不是直接與索引中的值進行比較。fulltext更像是一個搜尋引擎,配合match against操作使用,而不是一般的where語句加like。

  注:全文索引目前只有MyISAM儲存引擎支援全文索引,InnoDB引擎5.6以下版本還不支援全文索引

  所有儲存引擎對每個表至少支援16個索引,總索引長度至少為256位元組,索引有兩種儲存型別,包括B型樹索引和雜湊索引。

  索引可以提高查詢的速度,但是建立和維護索引需要耗費時間,同時也會影響插入的速度,如果需要插入大量的資料時,最好是先刪除索引,插入資料後再建立索引。

索引生效條件

  假設index(a,b,c)

  • 最左字首匹配:模糊查詢時,使用%匹配時:’a%‘會使用索引,’%a‘不會使用索引
  • 條件中有or,索引不會生效
  • a and c,a生效,c不生效
  • b and c,都不生效
  • a and b > 5 and c,a和b生效,c不生效。

檢測索引的效果:

show status like '%handler_read%'越大越好

sql語句分類:

  • DDL:資料定義語言(create drop)
  • DML:資料操作語句(insert update delete)
  • DQL:資料查詢語句(select)
  • DCL:資料控制語句,進行授權和許可權回收(grant revoke)
  • TPL:資料事務語句(commit collback savapoint)

資料庫三正規化:

  • 第一正規化:1NF是對屬性的原子性約束,要求欄位具有原子性,不可再分解;(只要是關係型資料庫都滿足1NF)

  • 第二正規化:2NF是在滿足第一正規化的前提下,非主鍵欄位不能出現部分依賴主鍵;解決:消除複合主鍵就可避免出現部分以來,可增加單列關鍵字。

  • 第三正規化:3NF是在滿足第二正規化的前提下,非主鍵欄位不能出現傳遞依賴,比如某個欄位a依賴於主鍵,而一些欄位依賴欄位a,這就是傳遞依賴。解決:將一個實體資訊的資料放在一個表內實現。

髒讀、幻讀、不可重複讀

髒讀:是指事務T1將某一值修改,然後事務T2讀取該值,此後T1因為某種原因撤銷對該值的修改,這就導致了T2所讀取到的資料是無效的。

不可重複讀:是指在資料庫訪問時,一個事務範圍內的兩次相同查詢卻返回了不同資料。在一個事務內多次讀同一資料。在這個事務還沒有結束時,另外一個事務也訪問該同一資料。那麼在第一個事務中的兩次讀資料之間,由於第二個事務的修改,第一個事務兩次讀到的的資料可能是不一樣的。這樣在一個事務內兩次讀到的資料是不一樣的,因此稱為是不可重複讀。

幻讀:是指當事務不是獨立執行時發生的一種現象,比如第一個事務對一個表中的資料進行了修改,這種修改涉及到表中的全部資料行。同時,第二個事務也修改這個表中的資料,這種修改是向表中插入一行新資料。那麼就會發生,操作第一個事務的使用者發現表中還有沒有修改的資料行,就好象發生了幻覺一樣。

不可重複讀&幻讀區別:

如果使用鎖機制來實現這兩種隔離級別,在可重複讀中,該sql第一次讀取到資料後,就將這些資料加鎖,其它事務無法修改這些資料,就可以實現可重複讀了。但這種方法卻無法鎖住insert的資料,所以當事務A先前讀取了資料,或者修改了全部資料,事務B還是可以insert資料提交,這時事務A就會發現莫名其妙多了一條之前沒有的資料,這就是幻讀,不能通過行鎖來避免。需要Serializable隔離級別 ,讀用讀鎖,寫用寫鎖,讀鎖和寫鎖互斥,這麼做可以有效的避免幻讀、不可重複讀、髒讀等問題,但會極大的降低資料庫的併發能力。 不可重複讀重點在於update和delete,而幻讀的重點在於insert。如何通過鎖機制來解決他們產生的問題

儲存引擎MyISAM和InnoDB區別:

  1. InnoDB支援事務,MyISAM不支援。
  2. MyISAM適合查詢以及插入為主的應用,InnoDB適合頻繁修改以及涉及到安全性較高的應用。
  3. InnoDB支援外來鍵,MyISAM不支援。
  4. 從MySQL5.5.5以後,InnoDB是預設引擎。
  5. MyISAM支援全文型別索引,而InnoDB不支援全文索引。
  6. InnoDB中不儲存表的總行數,select count(*) from table時,InnoDB需要掃描整個表計算有多少行,但MyISAM只需簡單讀出儲存好的總行數即可。注:當count(*)語句包含where條件時MyISAM也需掃描整個表。
  7. 對於自增長的欄位,InnoDB中必須包含只有該欄位的索引,但是在MyISAM表中可以和其他欄位一起建立聯合索引。
  8. 清空整個表時,InnoDB是一行一行的刪除,效率非常慢。MyISAM則會重建表。MyisAM使用delete語句刪除後並不會立刻清理磁碟空間,需要定時清理,命令:OPTIMIZE table dept;
  9. InnoDB支援行鎖(某些情況下還是鎖整表,如update table set a=1 where user like ‘%lee%’)
  10. Myisam建立表生成三個檔案:.frm資料表結構、.myd資料檔案、.myi索引檔案,Innodb只生成一個.frm檔案,資料存放在ibdata1.log
  11. 現在一般都選用InnoDB,主要是MyISAM的全表鎖,讀寫序列問題,併發效率鎖表,效率低,MyISAM對於讀寫密集型應用一般是不會去選用的。
  12. 應用場景:

    • MyISAM不支援事務處理等高階功能,但它提供高速儲存和檢索,以及全文搜尋能力。如果應用中需要執行大量的SELECT查詢,那麼MyISAM是更好的選擇。
    • InnoDB用於需要事務處理的應用程式,包括ACID事務支援。如果應用中需要執行大量的INSERT或UPDATE操作,則應該使用InnoDB,這樣可以提高多使用者併發操作的效能。

CHAR和VARCHAR的區別:

  • CHAR和VARCHAR型別在儲存和檢索方面有所不同
  • CHAR列長度固定為建立表時宣告的長度,長度值範圍是1到255
  • 當CHAR值被儲存時,它們被用空格填充到特定長度,檢索CHAR值時需刪除尾隨空格。

Mysql中的鎖型別

  • MyISAM支援表鎖,InnoDB支援表鎖和行鎖,預設為行鎖
  • 表級鎖:開銷小,加鎖快,不會出現死鎖。鎖定粒度大,發生鎖衝突的概率最高,併發量最低
  • 行級鎖:開銷大,加鎖慢,會出現死鎖。鎖力度小,發生鎖衝突的概率小,併發度最高

儲存過程

我們常用的操作資料庫語言SQL語句在執行的時候需要要先編譯,然後執行,而儲存過程(Stored Procedure)是一組為了完成特定功能的SQL語句集,經編譯後儲存在資料庫中,使用者通過指定儲存過程的名字並給定引數(如果該儲存過程帶有引數)來呼叫執行它。

一個儲存過程是一個可程式設計的函式,它在資料庫中建立並儲存。它可以有SQL語句和一些特殊的控制結構組成。當希望在不同的應用程式或平臺上執行相同的函式,或者封裝特定功能時,儲存過程是非常有用的。資料庫中的儲存過程可以看做是對程式設計中面向物件方法的模擬。它允許控制資料的訪問方式。

優點:

(1).儲存過程增強了SQL語言的功能和靈活性。儲存過程可以用流控制語句編寫,有很強的靈活性,可以完成複雜的判斷和較複雜的運算。

(2).儲存過程允許標準組件是程式設計。儲存過程被建立後,可以在程式中被多次呼叫,而不必重新編寫該儲存過程的SQL語句。而且資料庫專業人員可以隨時對儲存過程進行修改,對應用程式原始碼毫無影響。

(3).儲存過程能實現較快的執行速度。如果某一操作包含大量的Transaction-SQL程式碼或分別被多次執行,那麼儲存過程要比批處理的執行速度快很多。因為儲存過程是預編譯的。在首次執行一個儲存過程時查詢,優化器對其進行分析優化,並且給出最終被儲存在系統表中的執行計劃。而批處理的Transaction-SQL語句在每次執行時都要進行編譯和優化,速度相對要慢一些。

(4).儲存過程能過減少網路流量。針對同一個資料庫物件的操作(如查詢、修改),如果這一操作所涉及的Transaction-SQL語句被組織程儲存過程,那麼當在客戶計算機上呼叫該儲存過程時,網路中傳送的只是該呼叫語句,從而大大增加了網路流量並降低了網路負載。

(5).儲存過程可被作為一種安全機制來充分利用。系統管理員通過執行某一儲存過程的許可權進行限制,能夠實現對相應的資料的訪問許可權的限制,避免了非授權使用者對資料的訪問,保證了資料的安全。

delete、drop、truncate區別

  • truncate和delete只刪除資料,不刪除表結構,drop刪除表結構,並且釋放所佔的空間。
  • 刪除資料的速度,drop> truncate > delete
  • delete屬於DML語言,需要事務管理,commit之後才能生效。drop和truncate屬於DDL語言,操作立刻生效,不可回滾。
  • 使用場合:
    • 當你不再需要該表時, 用drop;
    • 當你仍要保留該表,但要刪除所有記錄時, 用truncate;
    • 當你要刪除部分記錄時(always with a where clause),用delete.

注意:對於有主外來鍵關係的表,不能使用truncate而應該使用不帶where子句的delete語句,由於truncate不記錄在日誌中,不能夠啟用觸發器