1.什麼是存儲過程?有哪些優缺點?
存儲過程Procedure是一組為了完成特定功能的SQL語句集合,經編譯後存儲在資料庫中,使用者通過指定存儲過程的名稱并給出參數來執行。
存儲過程中可以包含邏輯控制語句和資料操縱語句,它可以接受參數、輸出參數、傳回單個或多個結果集以及傳回值。
由于存儲過程在建立時即在資料庫伺服器上進行了編譯并存儲在資料庫中,是以存儲過程運作要比單個的SQL語句塊要快。同時由于在調用時隻需用提供存儲過程名和必要的參數資訊,是以在一定程度上也可以減少網絡流量、簡單網絡負擔。
2.介紹一下mysql的索引(優缺點?存儲結構等,索引類型?)
MyISAM使用的B+樹,樹的葉子節點存放執行指向資料的位址;
InnoDB也是使用的B+樹,但是葉子節點存放的是資料,資料檔案本身就是索引檔案;
InnoDB是聚類索引,輔助索引data域存儲相應記錄主鍵的值而不是位址;聚集索引這種實作方式使得按主鍵的搜尋十分高效,但是輔助索引搜尋需要檢索兩遍索引:首先檢索輔助索引獲得主鍵,然後用主鍵到主索引中檢索獲得記錄。
索引有唯一索引,主鍵索引,全文索引,普通索引。
3.事務介紹
主要四個事務隔離級别
4.資料庫的樂觀鎖和悲觀鎖是什麼?
悲觀鎖,往往依靠資料庫提供的鎖機制 (也隻有資料庫層提供的鎖機制才能真正保證資料通路的排他性,否則,即使在本系統中實作了加鎖機制,也無法保證外部系統不會修改資料) ,需要關閉資料庫的自動送出功能,autocommit=0;通過select。。。 for update拿到鎖。
樂觀鎖,樂觀鎖并不會使用資料庫提供的鎖機制。一般的實作樂觀鎖的方式就是記錄資料版本,有版本号或者時間戳方式,需要通過代碼來實作(類似CAS的功能)
處理如下,加上版本号的處理
1.查詢出商品資訊
select (status,status,version) from t_goods where id=#{id}
2.根據商品資訊生成訂單
3.修改商品status為2
update t_goods
set status=2,version=version+1
where id=#{id} and version=#{version};
5.使用索引查詢一定能提高查詢的性能嗎?為什麼
不一定,在以下情況中不一定會有性能的提升
當查詢結果傳回的資料集較大時,使用索引并不會提升性能;
對于值比較少的字段,比如性别,使用索引性能也不會有多少提升;
6.簡單說一說drop、delete與truncate的差別
相同點:drop、delete(不帶where子句)、truncate都會删除表中的資料
不同點:
1.truncate與delete隻删除表的資料,不删除表的結構;而drop會删除表的結構被依賴的限制、索引、觸發器,但是存儲過程/函數會保留,但是會變為invalid狀态(是以delete table後,再插入時的自增ID不是從1開始,而是從之前最大的值+1開始);
2.delete是DML,删除的資料會存儲在系統的復原段中,需要的時候,資料可以復原恢複;而truncate、delete是DDL,删除的資料的操作立即生效,且原資料不放回segment rollback中,無法復原恢複。是以慎用。
delete不會自動送出事務,操作會觸發trigger,而truncate、drop自動送出事務,且不觸發trigger。
速度來說,一般是drop>truncate>delete
因為delete語句不影響表所占用的extent,高水位(high watermark)保持原位置不動;而drop語句将表所占用的空間全部釋放,truncate語句預設情況下将空間釋放到minextents個extent,除非使用reuse storage;否則truncate會将高水位複位,因為預設情況下truncate table = truncate table drop storage;
PS:使用select語句查詢資料時,資料庫會掃描高水位線以下的資料塊,因為高水位線沒有變化,是以掃描的時間不會減少,是以才會出現使用delete删除資料以後,查詢的速度還是和delete以前一樣。
7.drop、delete與truncate分别在什麼場景之下使用?
6中已經把特點介紹的比較清楚了:
想删除部分資料行用delete,注意帶上where子句,復原段要足夠大;
想删除表,當然用drop;
想保留表而将所有資料删除,如果和事務無關,用truncate即可;
如果和事務有關,或者想觸發trigger,還是用delete;
如果是整理表内部的碎片,可以用truncate跟上reuse stroage,再重新導入/插入資料。
8.mysql裡面的行鎖和表鎖介紹?
表鎖:開銷小,加鎖快;不會出現死鎖;鎖定力度大,發生鎖沖突機率高,并發度最低
行鎖:開銷大,加鎖慢;會出現死鎖;鎖定粒度小,發生鎖沖突的機率低,并發度高
MyISAM引擎使用的表鎖,InnoDB有行鎖和表鎖。表鎖隻有在條件為有索引的情況下才會使用,行鎖實際是針對索引的。
9.超鍵、候選鍵、主鍵、外鍵分别是什麼?
粘貼過來的
超鍵:在關系模式中,能唯一辨別元組的屬性集稱為超鍵。
候選鍵 :如果一個屬性集能唯一辨別元組,且有不包含多餘屬性,那麼這個屬性集稱為候選鍵(候選鍵是沒有多餘屬性的超鍵)
主鍵:關系模式中使用者正在使用的候選鍵稱主鍵(primary key)。一般,如不加說明,鍵是指主鍵。
外鍵:在關系模式R中,如果某屬性集是其他模式的候選鍵,那麼該屬性集對模式R來說就是外鍵
10.什麼是視圖?以及視圖的使用場景有哪些?
視圖就是将你需要的幾張表中的資料整合到一張表上面。友善操作,特别是查詢操作,減少複雜的SQL語句,增強可讀性;
使用場景:
權限控制的時候,不希望使用者通路表中某些含敏感資訊的列,比如salary...
關鍵資訊來源于多個複雜關聯表,可以建立視圖提取我們需要的資訊,簡化操作。
11.說三個範式。
1.第一範式(確定每列保持原子性)
第一範式是最基本的範式。如果資料庫表中的所有字段值都是不可分解的原子值,就說明該資料庫表滿足了第一範式。
2.第二範式(確定表中的每列都和主鍵相關)
第二範式在第一範式的基礎之上更進一層。第二範式需要確定資料庫表中的每一列都和主鍵相關,而不能隻與主鍵的某一部分相關(主要針對聯合主鍵而言)。也就是說在一個資料庫表中,一個表中隻能儲存一種資料,不可以把多種資料儲存在同一張資料庫表中。
3.第三範式(確定每列都和主鍵列直接相關,而不是間接相關)
第三範式需要確定資料表中的每一列資料都和主鍵直接相關,而不能間接相關。
12.mysql查詢優化有哪些手段?
1.資料庫設計方面;包括索引的添加,字段類型,是否允許非空等等。
2.資料庫查詢方面;優化查詢條件,盡量使用到索引,避免全表掃描
3.連接配接方面,資料庫連接配接池的,使用orm的架構等
13.例舉mysql可能出現死鎖的場景
MyISAM基于的是表鎖,是以不會出現死鎖的情況。InnoDB大部分情況下使用的行鎖,比如兩個存在用戶端執行事務:
session1 session2
擷取表1的排它鎖 擷取表2的排它鎖
擷取表2的排它鎖(進入等待) 擷取表1的排它鎖(這時就會進入死鎖)
這樣就進入了互相等待的過程,是以會造成死鎖
14.mysql死鎖怎麼解決的?
發生死鎖後,InnoDB一般都會自動檢測到,并使一個事務釋放鎖并回退事務,另一個事務擷取鎖,繼續執行。在設計外部鎖,外部表鎖的情況下,InnoDB并不能完全檢測到死鎖,這時候通過設定鎖等待的逾時時間來解決。innodb_lock_wait_timeout
15.InnoDB什麼時候會用到行鎖,什麼情況下會用到表鎖?
對于InnoDB表,在絕大部分情況下都應該使用行級鎖,因為事務和行鎖往往是我們之是以選擇InnoDB表的理由。但在個别特殊事務中,也可以考慮使用表級鎖。
第一種情況是:事務需要更新大部分或全部資料,表又比較大,如果使用預設的行鎖,不僅這個事務執行效率低,而且可能造成其他事務長時間鎖等待和鎖沖突,這種情況下可以考慮使用表鎖來提高該事務的執行速度。
第二種情況是:事務涉及多個表,比較複雜,很可能引起死鎖,造成大量事務復原。這種情況也可以考慮一次性鎖定事務涉及的表,進而避免死鎖、減少資料庫因事務復原帶來的開銷。
當然,應用中這兩種事務不能太多,否則,就應該考慮使用MyISAM表了。
16.索引字段為什麼越小越好?
從索引的資料結構來講,因為索引使用的B+樹,而B+樹的高度決定了查詢的時間,每高度增加1,即一次磁盤分頁讀取。因為磁盤的分頁大小是固定的,是以需要盡可能的讓每一頁存更多的資料,是以如果索引字段比較大的話,每一頁存的數量就會少了,這樣就會增加B+樹的高度。
還有在InnoDB中,輔助索引都引用主索引的值,這樣如果主索引值太大的話,所有輔助索引都會變大。
17.為什麼建議使用一個也業務ID不相幹的字段來作為主鍵?
1.如果使用身份證号或學号,首先主鍵索引值會比較大,而輔助索引都會引用主鍵索引的值,輔助索引也會變大;
2.如果使用學号或身份證号,每次插入時,會根據主鍵将其插入到合适的節點和位置,如果達到裝載因子,會開辟一個新的頁(記憶體頁或磁盤頁),
如果使用自增主鍵,每次都是順序插入,達到裝載因子時,開辟一個新的頁,這樣就會形成一個非常緊湊的索引結構,由于每次插入也不需要移動已有資料,是以效率很高。如果使用非自增主鍵(如果身份證号或學号等),由于每次插入主鍵的值近似于随機,是以每次新紀錄都要被插到現有索引頁得中間某個位置,此時MySQL不得不為了将新記錄插到合适位置而移動資料,甚至目标頁面可能已經被回寫到磁盤上而從緩存中清掉,此時又要從磁盤上讀回來,這增加了很多開銷,同時頻繁的移動、分頁操作造成了大量的碎片,得到了不夠緊湊的索引結構,後續不得不通過OPTIMIZE TABLE來重建表并優化填充頁面。