十七、MySql面試題

 

  1. 數據庫的三範式是什麼?
    (1)第一範式:當關系R不能再分解成更基本的數據單位時。
    
    (2)第二範式:在滿足第一範式下,並且R得所有非主屬性都完全依賴於R的每一個候選關鍵屬性。
    
    (3)第三範式:在滿足第一、第二範式下,屬性不依賴於其它非主屬性,也就是在滿足2NF的基礎上,
    任何非主屬性不得傳遞依賴於主屬性。

     

  2. 一張自增表裏面總共有 7 條數據,刪除了最後 2 條數據,重啓 mysql 數據庫,又插入了一條數據,此時 id 是幾?
        (1)數據庫引擎如果是 MyISAM ,那 id 就是 8。
        (2)數據庫引擎如果是 InnoDB,那 id 就是 6。
       (3)InnoDB 表只會把自增主鍵的最大 id 記錄在內存中,所以重啓之後會導致最大 id 丟失。

     

  3. 如何獲取當前數據庫版本?
    select version()

     

  4. 說一下 ACID 是什麼?
    (1)原子性Atomicity:指的是整個事務是一個獨立的單元,是不可分割的工作單位,要麼操
    作成功,要麼操作不成功,事務必須要保持和系統處於一致的狀態,只有使據庫中所有的操作
    執行成功,纔算整個事務成功。
    
    (2)一致性Consistency:指數據庫事務不能破壞關係數據的完整性以及業務邏輯上的一致性。
    
    (3)隔離性Isolaction:指的是在併發環境中,當不同的事務同時操縱相同的數據時,每個事
    務都有各自的完整數據空間。
    
    (4)持久性Durility:指的是隻要事務成功結束,它對數據庫所做的更新就必須永久保存下來。
    即使發生系統崩潰,重新啓動數據庫系統後,數據庫還能恢復到事務成功結束時的狀態。

     

  5. char 和 varchar 的區別是什麼?
    (1)char:定長,效率高,一般用於固定長度的表單提交數據存儲 ;例如:身份證號,
    手機號,電話,密碼等。
    
    (2)varchar:不定長,效率偏低。
    
    (3)char定義的是固定長度,長度範圍爲0-255,存儲時,如果字符數沒有達到定義的位數,
    在後面用空格補全存入數據庫中。
    
    (4)varchar是變長長度,長度範圍爲0-65535,存儲時,如果字符沒有達到定義的位數,也
    不會在後面補空格。
    
    

     

  6. float 和 double 的區別是什麼?
    (1)double精度高,有效數字16位,float精度7位。但double消耗內存是float的兩倍,
    double的運算速度比float慢得多;
    
    (2)float數值類型用於表示單精度浮點數值,而double數值類型用於表示雙精度浮點數
    值,float和double都是浮點型,而decimal是定點型;
    
    (3)FLOAT和DOUBLE在不指定精度時,默認會按照實際的精度來顯示,而DECIMAL在不指
    定精度時,默認整數爲10,小數爲0。

     

  7. mysql 的內連接、左連接、右連接有什麼區別?
    (1)內連接,顯示兩個表中有聯繫的所有數據;
    
    (2)左鏈接,以左表爲參照,顯示所有數據;
    
    (3)右鏈接,以右表爲參照顯示數據;

     

  8. mysql 索引是怎麼實現的?
    (1)索引是一個排序的列表,在這個列表中存儲着索引的值和包含這個值的數據
    所在行的物理地址,在數據十分龐大的時候,索引可以大大加快查詢的速度,這是
    因爲使用索引後可以不用掃描全表來定位某行的數據,而是先通過索引表找到該行
    數據對應的物理地址然後訪問相應的數據。
    
    (2)優勢:可以快速檢索,減少I/O次數,加快檢索速度;根據索引分組和排序,
    可以加快分組和排序;
    
    (3)缺點:索引本身也是表,因此會佔用存儲空間,一般來說,索引表佔用的空間
    的數據表的1.5倍;索引表的維護和創建需要時間成本,這個成本隨着數據量增大而
    增大;構建索引會降低數據表的修改操作(刪除,添加,修改)的效率,因爲在修改
    數據表的同時還需要修改索引表;
    
    (4)索引的分類
    常見的索引類型有:主鍵索引、唯一索引、普通索引、全文索引、組合索引。
    1、主鍵索引:即主索引,根據主鍵pk_clolum(length)建立索引,不允許重複,不允許空值;
    2、唯一索引:用來建立索引的列的值必須是唯一的,允許空值。
    3、普通索引:用表中的普通列構建的索引,沒有任何限制。
    4、全文索引:用大文本對象的列構建的索引(下一部分會講解)。
    5、組合索引:用多個列組合構建的索引,這多個列中的值不允許有空值。
    

     

  9. 怎麼驗證 mysql 的索引是否滿足需求?
    (1)在select語句前加上explain就可以用來查看sql的執行計劃,explain顯示了MySQL
        如何使用索引來處理select語句以及連接表。
    
    (2)possible_keys:顯示可能應用在這張表中的索引。如果爲空,沒有可能的索引。可
        以爲相關的域從WHERE語句中選擇一個合適的語句。
    
    (3)key: 實際使用的索引。如果爲NULL,則沒有使用索引。很少的情況下,MYSQL會選
        擇優化不足的索引。這種情況下,可以在SELECT語句中使用USE INDEX(indexname)來強
        制使用一個索引或者用IGNORE INDEX(indexname)來強制MYSQL忽略索引

     

  10. 說一下數據庫的事務隔離?
    (1)未提交讀(Read Uncommitted):允許髒讀,也就是可能讀取到其他會話中未提交事
        務修改的數據.
    (2)提交讀(Read Committed):只能讀取到已經提交的數據。Oracle等多數數據庫默認
        都是該級別 (不重複讀)。
    (3)可重複讀(Repeated Read):可重複讀。在同一個事務內的查詢都是事務開始時刻一
        致的,InnoDB默認級別。在SQL標準中,該隔離級別消除了不可重複讀,但是還存在幻象讀。
    (4)串行讀(Serializable):完全串行化的讀,每次讀都需要獲得表級共享鎖,讀寫相互
        都會阻塞。
    
    ① 髒讀: 髒讀就是指當一個事務正在訪問數據,並且對數據進行了修改,而這種修改還沒有提交
        到數據庫中,這時,另外一個事務也訪問這個數據,然後使用了這個數據。
    ② 不可重複讀:是指在一個事務內,多次讀同一數據。在這個事務還沒有結束時,另外一個事務
      也訪問該同一數據。那麼,在第一個事務中的兩次讀數據之間,由於第二個事務的修改,那麼第
      一個事務兩次讀到的的數據可能是不一樣的。這樣就發生了在一個事務內兩次讀到的數據是不一
      樣的,因此稱爲是不可重複讀。
    ④ 幻讀:第一個事務對一個表中的數據進行了修改,這種修改涉及到表中的全部數據行。同時,第
      二個事務也修改這個表中的數據,這種修改是向表中插入一行新數據。那麼,以後就會發生操作
      第一個事務的用戶發現表中還有沒有修改的數據行,就好象發生了幻覺一樣。
    

     

  11. 說一下 mysql 常用的引擎?
    (1)a.Innodb引擎:
        1.Innodb引擎提供了對數據庫ACID事務的支持。並且還提供了行級鎖和外鍵的約束。
        2.它的設計的目標就是處理大數據容量的數據庫系統。它本身實際上是基於Mysql後臺的完整的系統。
        3.Mysql運行的時候,Innodb會在內存中建立緩衝池,用於緩衝數據和索引。
        4.但是,該引擎是不支持全文搜索的。同時,啓動也比較的慢,它是不會保存表的行數的。當進
        行Select count(*) from table指令的時候,需要進行掃描全表。
        5.當需要使用數據庫的事務時,該引擎就是首選。由於鎖的粒度小,寫操作是不會鎖定全表的。所
        以在併發度較高的場景下使用會提升效率的。
    
    (2)b.MyIASM引擎
        1.是MySql的默認引擎,但不提供事務的支持,也不支持行級鎖和外鍵。
        2.當執行Insert插入和Update更新語句時,即執行寫操作的時候需要鎖定這個表。所以會導致
        效率會降低。
        3.如果表的讀操作遠遠多於寫操作時,並且不需要事務的支持的。可以將MyIASM作爲數據庫引擎
        的首先。

     

  12. 說一下 mysql 的行鎖和表鎖?
    (1)表級鎖:每次操作鎖住整張表。開銷小,加鎖快;不會出現死鎖;鎖定粒度大,發生鎖
        衝突的概率最高,併發度最低;
    (2)行級鎖:每次操作鎖住一行數據。開銷大,加鎖慢;會出現死鎖;鎖定粒度最小,發生
        鎖衝突的概率最低,併發度也最高;

     

  13. 說一下樂觀鎖和悲觀鎖?
    (1)樂觀鎖:每次去拿數據的時候都認爲別人不會修改,所以不會上鎖,但是在提交更新的
        時候會判斷一下在此期間別人有沒有去更新這個數據。
    (2)悲觀鎖:每次去拿數據的時候都認爲別人會修改,所以每次在拿數據的時候都會上鎖,
        這樣別人想拿這個數據就會阻止,直到這個鎖被釋放。

     

  14. mysql 問題排查都有哪些手段?
    (1)使用 show processlist 命令查看當前所有連接信息。
    (2)使用 explain 命令查詢 SQL 語句執行計劃。
    (3)開啓慢查詢日誌,查看慢查詢的 SQL。

     

  15. 如何做 mysql 的性能優化?
    (1)爲搜索字段創建索引。
    (2)避免使用 select *,列出需要查詢的字段。
    (3)垂直分割分表。
    (4)選擇正確的存儲引擎。

     

  16. 索引的使用策略?
    (1)什麼時候要使用索引?
       1.主鍵自動建立唯一索引;
       2.經常作爲查詢條件在WHERE或者ORDER BY語句中出現的列要建立索引;
       3.作爲排序的列要建立索引;
       4.查詢中與其他表關聯的字段,外鍵關係建立索引;
       5.高併發條件下傾向組合索引;
       6.用於聚合函數的列可以建立索引,例如使用了max(column_1)或者
       count(column_1)時的column_1就需要建立索引。
    
    (2)什麼時候不要使用索引?
        1.經常增刪改的列不要建立索引;
        2.有大量重複的列不建立索引;
        3.表記錄太少不要建立索引。
    
    (3)索引失效的情況:
        1.在組合索引中不能有列的值爲NULL,如果有,那麼這一列對組合索引就是無效的。
        2.在一個SELECT語句中,索引只能使用一次,如果在WHERE中使用了,那麼在ORDER BY
        中就不要用了。
        3.LIKE操作中,'%aaa%'不會使用索引,也就是索引會失效,但是‘aaa%’可以使用索引。
        4.在索引的列上使用表達式或者函數會使索引失效,例如:select * from users where
        YEAR(adddate)<2007,將在每個行上進行運算,這將導致索引失效而進行全表掃描,因此我們
        可以改成:select * from users where adddate<’2007-01-01′。
        5.其它通配符同樣,也就是說,在查詢條件中使用正則表達式時,只有在搜索模板的第一個字符
        不是通配符的情況下才能使用索引。
        6.在查詢條件中使用不等於,包括<符號、>符號和!=會導致索引失效。
        7.在查詢條件中使用IS NULL或者IS NOT NULL會導致索引失效。
        8.字符串不加單引號會導致索引失效。更準確的說是類型不一致會導致失效,比如字段email
        是字符串類型的,使用WHERE email=99999 則會導致失敗,應該改爲WHERE email='99999'。
        9.在查詢條件中使用OR連接多個條件會導致索引失效,除非OR鏈接的每個條件都加上索引,
        這時應該改爲兩次查詢,然後用UNION ALL連接起來。
        10.如果排序的字段使用了索引,那麼select的字段也要是索引字段,否則索引失效。特別的
        是如果排序的是主鍵索引則select * 也不會導致索引失效。
    
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章