MySQL常見面試題

事務四大特性sql

1.原子性:不可分割的操做單元,事務中全部操做,要麼所有成功;要麼撤回到事務執行以前的狀態數據庫

2.一致性:若是在執行事務以前數據庫是一致性的,那麼在執行事務後數據庫也仍是一致的編程

3.隔離性:事務操做之間彼此獨立和透明互不影響。事務獨立運行。這一般使用鎖來實現。一個事務處理後的結果,影響了其餘事務,那麼其餘事物會撤回。事務的100%隔離,須要犧牲速度安全

4.持久性:事務一旦提交,其結果就是永久的。即使發生系統故障,也能恢復。網絡


事務隔離級別數據結構

未提交讀(Read Uncommitted):容許髒讀,其餘事務只要修改了數據,即便未提交,本事務也能看到修改後的數據值。也就是可能讀取到其餘會話中未提交事務修改的數據併發

提交讀(Read Committed):只能讀取到已經提交的數據。Oracle等多數數據庫默認的都是該級別(不重複讀)函數

可重複讀(Repeated Read):可重複讀。不管其餘事務是否修改並提交了數據,在這個數據中看到的數據值始終不受其餘事務影響。性能

串行讀(Serializable):徹底串行話的讀。每次讀都須要得到表級共享鎖,讀寫相互都會阻塞優化

 

MySQL數據庫(InnoDB引擎)默認使用可重複讀(Repeated Read)

 

髒讀、幻讀、不可重複讀

髒讀:是指事務T1將某一值修改,而後事務T2讀取該值,此後T1由於某種緣由撤銷對該值的修改,這就致使了T2所讀取到的數據是無效的。

不可重複度:是指在數據庫訪問時,一個事務範圍內的倆次相同查詢卻返回了不一樣數據。在一個事務內屢次讀同一數據。在這個事務尚未結束時,另外一個事物也該訪問同一數據。那麼在第一個事務中的倆次讀數據之間,因爲第二個事務的修改,第一個事務倆次讀到的數據多是不同的。這樣在一個事務內倆次讀到的數據是不同的,所以稱爲是不可重複讀。

幻讀:是指事務不是獨立執行時發生的一種現象,好比第一個事務對第一個表中的數據進行了修改,這種修改涉及到表中的所有數據行,同時,第二個事務也修改這個表中的數據,這種修改是像表中插入一行新數據。那麼就會發生,操做第一個事務的用戶發現表中尚未修改的數據,就好像發生了幻覺同樣。

不可重複度和幻讀的區別:

若是使用鎖機制來實現這倆種隔離級別,可在重複度中,該sql第一次讀取到數據後,就將這些數據加鎖,其餘事務沒法修改這些數據,就能夠實現可重複讀了。但這種方法卻沒法鎖住insert的數據。因此當事務A先前讀取了數據,或者修改了所有數據,事務B仍是能夠insert提交數據,這是事務A就會大仙莫名其妙的多了一條數據,這就是幻讀,不能經過行鎖來避免。因此須要串行讀(Serializable)隔離級別,讀用讀鎖,寫用寫鎖,讀鎖和寫鎖互斥,這麼作就能夠有效的避免幻讀、不可重複讀、髒讀等問題,但會極大的下降數據庫的併發能力。

不可重複讀重點在於update和delete,而幻讀重點在於insert。如何經過鎖機制來解決他們產生的問題。


 索引相關

數據庫索引,是數據庫管理系統中一個排序的數據結構,以協助快速查詢、更新數據庫表中數據。索引的實現一般使用B_TREE。B_TREE索引加速了數據訪問,由於存儲引擎不會再去掃描整張表。

MyISAM引擎使用B+TREE做爲索引結構。葉節點的data域存放的是數據記錄地址,即:MyISAM索引文件和數據文件是分離的。MyISAM的索引文件僅僅、保存數據記錄的地址。

InnoDB引擎也使用B+TREE做爲索引結構,可是InnoDB的數據文件自己就是索引文件,葉節點data域保存了完整的數據記錄。這個索引的key是數據表的主鍵,所以InnoDB表數據文件自己就是索引。

MySQL數據庫的四類索引:

index:普通索引,數據能夠重複,沒有任何限制。

unque:惟一索引。要求索引列的值必須惟一,但容許有空值;若是是組合索引,那麼列值的組合必須惟一。

primary key:主鍵索引,是一種特殊的惟一索引,一個表只能有一個主鍵,不容許有空值,通常是在建立表的同時建立主鍵索引。

組合索引:在多個字段上建立的索引,只有在查詢條件中使用了建立索引時的第一個字段,索引纔會被使用。

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

  全文索引目前只有MyISAM存儲引擎支持全文索引,InnoDB引擎5.6如下版本還不支持全文索引

  全部存儲引擎對每一個表至少支持16個索引,總索引長度至少爲256字節,索引有倆種存儲類型,包括B型書索引和哈希索引。

  索引能夠提升查詢的速度,可是建立和維護索引須要耗費時間,同時也會影響插入的速度,若是須要插入大量的數據時,最好是先刪除索引,插入數據後再創建索引。

索引生效條件

  假設index(a,b,c)

  1.最左前綴匹配:模糊查詢時,使用%匹配是:"a%"會使用索引,"%a"不會使用索引

  2.條件中有or,索引不會生效

  3.a and c,a生效,c不生效

  4.b and c,都不生效

  5.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,這就是傳遞依賴。解決:將一個實體信息的數據放在一個表內實現。


存儲引擎 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語句刪除後並不會like清理磁盤空間,須要定時清理,命令: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的區別

1. truncate和delete只刪除數據,不刪除表結構,drop刪除表結構,而且釋放所佔的空間。

2. 刪除數據的速度,drop>truncate>delete

3. delete屬於DML語言,須要事務管理,commit以後才能生效。drop和truncate屬於DDL語言,操做即刻生效,不可回滾。

4. 使用場合:

  -:當你不在須要該表時,用drop;

  -:當你仍要保留該表,但要刪除全部記錄時,用truncate;

  -:當你要刪除部分記錄時(always  with  a  where  clause),用delete

注意:對於有主外鍵關係的表,不能使用truncate而應該使用不帶where句子的delete語句,因爲truncate不記錄在日誌中,不可以激活觸發器

相關文章
相關標籤/搜索