程序員面試備戰篇:18個經典MySQL面試專題解析,乾貨分享答案

1.數據庫三範式是什麼?

  1. 第一範式(1NF):字段具備原子性,不可再分。(全部關係型數據庫系統都知足第一範式數據庫表中的字段都是單一屬性的,不可再分)
  2. 第二範式(2NF)是在第一範式(1NF)的基礎上創建起來的,即知足第二範式(2NF)必須先知足第一範式(1NF)。要求數據庫表中的每一個實例或行必須能夠被唯一地區分。一般須要爲表加上一個列,以存儲各個實例的唯一標識。這個唯一屬性列被稱爲主關鍵字或主鍵。
  3. 知足第三範式(3NF)必須先知足第二範式(2NF)。簡而言之,第三範式(3NF)要求一個數據庫表中不包含已在其它表中已包含的非主關鍵字信息。>因此第三範式具備以下特徵:>>1. 每一列只有一個值 >>2. 每一行都能區分。>>3. 每個表都不包含其餘表已經包含的非主關鍵字信息。

2.有哪些數據庫優化方面的經驗?

  1. 用 PreparedStatement, 通常來講比 Statement 性能高:一個 sql發給服務器去執行,涉及步驟:語法檢查、語義分析, 編譯,緩存。
  2. 有外鍵約束會影響插入和刪除性能,若是程序可以保證數據的完整性,那在設計數據庫時就去掉外鍵。
  3. 表中容許適當冗餘,譬如,主題帖的回覆數量和最後回覆時間等4. UNION ALL 要比UNION 快不少,因此,若是能夠確認合併的兩個結果集中不包含重複數據且不須要排序時的話,那麼就使用 UNIONALL。>>UNION 和 UNION ALL 關鍵字都是將兩個結果集合併爲一個,但這二者從使用和效率上來講都有所不一樣。>1. 對重複結果的處理:UNION 在進行表連接後會篩選掉重複的記錄,Union All 不會去除重複記錄。>2. 對排序的處理:Union 將會按照字段的順序進行排序;UNION ALL 只是簡單的將兩個結果合併後就返回。

3.請簡述經常使用的索引有哪些種類?

  1. 普通索引: 即針對數據庫表建立索引
  2. 惟一索引: 與普通索引相似,不一樣的就是:MySQL 數據庫索引列的值必須惟一,但容許有空值
  3. 主鍵索引: 它是一種特殊的惟一索引,不容許有空值。通常是在建表的時候同時建立主鍵索引
  4. 組合索引: 爲了進一步榨取 MySQL 的效率,就要考慮創建組合索引。即將數據庫表中的多個字段聯合起來做爲一個組合索引。

4.以及在 mysql 數據庫中索引的工做機制是什麼?

  • 數據庫索引,是數據庫管理系統中一個排序的數據結構,以協助快速查詢、更新數據庫表中數據。索引的實現一般使用 B 樹及其變種 B+樹

5.MySQL 的基礎操做命令:

  1. MySQL 是否處於運行狀態:Debian 上運行命令 service mysqlstatus,在 RedHat上運行命令 service mysqld status
  2. 開啓或中止 MySQL 服務 :運行命令 service mysqld start 開啓服務;運行命令service mysqld stop 中止服務
  3. Shell 登入 MySQL: 運行命令 mysql -u root -p
  4. 列出全部數據庫:運行命令 show databases;
  5. 切換到某個數據庫並在上面工做:運行命令 use databasename; 進入名爲databasename 的數據庫
  6. 列出某個數據庫內全部表: show tables;
  7. 獲取表內全部 Field 對象的名稱和類型 :describe table_name;

6.mysql 的複製原理以及流程。

Mysql 內建的複製功能是構建大型,高性能應用程序的基礎。將 Mysql 的數據分佈到多個系統上去,這種分佈的機制,是經過將 Mysql 的某一臺主機的數據複製到其它主機(slaves)上,並從新執行一遍來實現的。* 複製過程當中一個服務器充當主服務器,而一個或多個其它服務器充當從服務器。php

主服務器將更新寫入二進制日誌文件,並維護文件的一個索引以跟蹤日誌循環。這些日誌能夠記錄發送到從服務器的更新。當一個從服務器鏈接主服務器時,它通知主服務器在日誌中讀取的最後一次成功更新的位置。mysql

從服務器接收從那時起發生的任何更新,而後封鎖並等待主服務器通知新的更新。過程以下sql

1. 主服務器把更新記錄到二進制日誌文件中。數據庫

2. 從服務器把主服務器的二進制日誌拷貝到本身的中繼日誌(replay log)中。3. 從服務器重作中繼日誌中的時間,把更新應用到本身的數據庫上。緩存

7.mysql 支持的複製類型?

  1. 基於語句的複製:在主服務器上執行的 SQL 語句,在從服務器上執行一樣的語句。MySQL 默認採用基於語句的複製,效率比較高。一旦發現無法精確複製時,會自動選着基於行的複製。
  2. 基於行的複製:把改變的內容複製過去,而不是把命令在從服務器上執行一遍. 從mysql5.0 開始支持
  3. 混合類型的複製: 默認採用基於語句的複製,一旦發現基於語句的沒法精確的複製時,就會採用基於行的複製。

8.mysql 中 myisam 與 innodb 的區別?

  1. 事務支持 > *MyISAM:強調的是性能,每次查詢具備原子性,其執行速度比 InnoDB 類型更快,可是不提供事務支持。> *InnoDB:提供事務支持事務,外部鍵等高級數據庫功能。具備事務(commit)、回滾(rollback)和崩潰修復能力(crash recovery capabilities)的事務安全(transaction-safe (ACID compliant))型表。
  2. InnoDB 支持行級鎖,而 MyISAM 支持表級鎖. >> 用戶在操做myisam 表時,select,update,delete,insert 語句都會給表自動加鎖,若是加鎖之後的表知足insert 併發的狀況下,能夠在表的尾部插入新的數據。
  3. InnoDB 支持 MVCC, 而 MyISAM 不支持
  4. InnoDB 支持外鍵,而 MyISAM 不支持
  5. 表主鍵 > *MyISAM:容許沒有任何索引和主鍵的表存在,索引都是保存行的地址。> *InnoDB:若是沒有設定主鍵或者非空惟一索引,就會自動生成一個6 字節的主鍵(用戶不可見),數據是主索引的一部分,附加索引保存的是主索引的值。
  6. InnoDB 不支持全文索引,而 MyISAM 支持。
  7. 可移植性、備份及恢復 > *MyISAM:數據是以文件的形式存儲,因此在跨平臺的數據轉移中會很方便。在備份和恢復時可單獨針對某個表進行操做。> *InnoDB:免費的方案能夠是拷貝數據文件、備份binlog,或者用 mysqldump,在數據量達到幾十 G 的時候就相對痛苦了
  8. 存儲結構 > *MyISAM:每一個 MyISAM 在磁盤上存儲成三個文件。第一個文件的名字以表的名字開始,擴展名指出文件類型。.frm 文件存儲表定義。數據文件的擴展名爲.MYD (MYData)。索引文件的擴展名是.MYI (MYIndex)。> *InnoDB:全部的表都保存在同一個數據文件中(也多是多個文件,或者是獨立的表空間文件),InnoDB表的大小隻受限於操做系統文件的大小,通常爲 2GB。

9.mysql 中 varchar 與 char 的區別以及 varchar(50)中的 50 表明的涵義?

  1. varchar 與 char 的區別: char 是一種固定長度的類型,varchar 則是一種可變長度的類型.
  2. varchar(50)中 50 的涵義 : 最多存放 50 個字節
  3. int(20)中 20 的涵義: int(M)中的 M indicates the maximumdisplay width (最大顯示寬度)for integer types. The maximumlegal display width is 255.

10.MySQL 中 InnoDB 支持的四種事務隔離級別名稱,以及逐級之間的區別?

  1. Read Uncommitted(讀取未提交內容) >> 在該隔離級別,全部事務均可以看到其餘未提交事務的執行結果。本隔離級別不多用於實際應用,由於它的性能也不比其餘級別好多少。讀取未提交的數據,也被稱之爲髒讀(Dirty Read)。
  2. Read Committed(讀取提交內容) >> 這是大多數數據庫系統的默認隔離級別(但不是 MySQL 默認的)。它知足了隔離的簡單定義:一個事務只能看見已經提交事務所作的改變。這種隔離級別也支持所謂的不可重複讀(Nonrepeatable Read),由於同一事務的其餘實例在該實例處理其間可能會有新的 commit,因此同一 select 可能返回不一樣結果。
  3. Repeatable Read(可重讀) >> 這是 MySQL 的默認事務隔離級別,它確保同一事務的多個實例在併發讀取數據時,會看到一樣的數據行。不過理論上,這會致使另外一個棘手的問題:幻讀(PhantomRead)。簡單的說,幻讀指當用戶讀取某一範圍的數據行時,另外一個事務又在該範圍內插入了新行,當用戶再讀取該範圍的數據行時,會發現有新的「幻影」 行。InnoDB 和 Falcon 存儲引擎經過多版本併發控制(MVCC,Multiversion Concurrency Control 間隙鎖)機制解決了該問題。注:其實多版本只是解決不可重複讀問題,而加上間隙鎖(也就是它這裏所謂的併發控制)才解決了幻讀問題。
  4. Serializable(可串行化) >> 這是最高的隔離級別,它經過強制事務排序,使之不可能相互衝突,從而解決幻讀問題。簡言之,它是在每一個讀的數據行上加上共享鎖。在這個級別,可能致使大量的超時現象和鎖競爭。

讓眼睛休息休息,再繼續吧!

11.表中有大字段 X(例如:text 類型),且字段 X 不會常常更新,以讀爲爲主,將該字段拆成子表好處是什麼?

若是字段裏面有大字段(text,blob)類型的,並且這些字段的訪問並很少,這時候放在一塊兒就變成缺點了。MYSQL 數據庫的記錄存儲是按行存儲的,數據塊大小又是固定的(16K),每條記錄越小,相同的塊存儲的記錄就越多。此時應該把大字段拆走,這樣應付大部分小字段的查詢時,就能提升效率。當須要查詢大字段時,此時的關聯查詢是不可避免的,但也是值得的。拆分開後,對字段的 UPDAE 就要 UPDATE 多個表了安全

12.MySQL 中 InnoDB 引擎的行鎖是經過加在什麼上完成(或稱實現)的?

InnoDB 行鎖是經過給索引上的索引項加鎖來實現的,這一點 MySQL 與Oracle 不一樣,後者是經過在數據塊中對相應數據行加鎖來實現的。InnoDB 這種行鎖實現特色意味着:只有經過索引條件檢索數據,InnoDB 才使用行級鎖,不然,InnoDB 將使用表鎖!bash

13.MySQL 中控制內存分配的全局參數,有哪些?

  1. Keybuffersize:> * keybuffersize 指定索引緩衝區的大小,它決定索引處理的速度,尤爲是索引讀的速度。經過檢查狀態值Keyreadrequests 和 Keyreads,能夠知道 keybuffersize 設置是否合理。比例 keyreads /keyreadrequests 應該儘量的低,至少是1:100,1:1000 更好(上述狀態值可使用 SHOW STATUS LIKE‘keyread%'得到)。> * keybuffersize 只對 MyISAM 表起做用。即便你不使用MyISAM 表,可是內部的臨時磁盤表是 MyISAM 表,也要使用該值。可使用檢查狀態值 createdtmpdisktables 得知詳情。對於 1G 內存的機器,若是不使用 MyISAM表,推薦值是 16M(8-64M) > * keybuffersize 設置注意事項 >>>1. 單個keybuffer 的大小不能超過 4G,若是設置超過 4G,就有可能遇到下面 3 個bug: >>>>> bugs.mysql.com/bug.php?id=…
    >>>>> bugs.mysql.com/bug.php?id=…
    >>>>> bugs.mysql.com/bug.php?id=…
    >>>2. 建議 key
    buffer 設置爲物理內存的 1/4(針對 MyISAM 引 擎),甚至是物理內存的 30%~40%,若是keybuffersize 設置太大,系統就會頻繁的換頁,下降系統性能。由於 MySQL 使用操做系統的緩存來緩存數據,因此咱們得爲系統留夠足夠的內存;在不少狀況下數據要比索引大得多。>>>3. 若是機器性能優越,能夠設置多個keybuffer,分別讓不一樣的keybuffer 來緩存專門的索引
  2. innodbbufferpool_size > 表示緩衝池字節大小,InnoDB 緩存表和索引數據的內存區域。mysql 默認的值是 128M。最大值與你的CPU 體系結構有關,在 32 位操做系統,最大值是 4294967295(2^32-1) ,在 64 位操做系統,最大值爲18446744073709551615 (2^64-1)。> 在 32 位操做系統中,CPU 和操做系統實用的最大大小低於設置的最大值。若是設定的緩衝池的大小大於 1G,設置innodbbufferpoolinstances 的值大於 1. > 數據讀寫在內存中很是快, innodbbufferpoolsize 減小了對磁盤的讀寫。當數據提交或知足檢查點條件後才一次性將內存數據刷新到磁盤中。然而內存還有操做系統或數據庫其餘進程使用, 通常設置bufferpool 大小爲總內存的 3/4 至 4/5。若設置不當, 內存使用可能浪費或者使用過多。對於繁忙的服務器, buffer pool 將劃分爲多個實例以提升系統併發性, 減小線程間讀寫緩存的爭用。buffer pool 的大小首先受 innodbbuffer*pool_instances 影響,固然影響較小。
  3. querycachesize > *當 mysql 接收到一條 select 類型的 query時,mysql 會對這條query 進行 hash 計算而獲得一個 hash 值,而後經過該 hash 值到 query cache 中去匹配,若是沒有匹配中,則將這個hash 值存放在一個 hash 鏈表中,同時將 query 的結果集存放進cache 中,存放 hash 值的鏈表的每個 hash 節點存放了相應query結果集在 cache 中的地址,以及該 query 所涉及到的一些 table 的相關信息;若是經過 hash 值匹配到了同樣的 query,則直接將 cache 中相應的 query 結果集返回給客戶端。若是 mysql 任何一個表中的任何一條數據發生了變化,便會通知query cache 須要與該 table 相關的query 的 cache 所有失效,並釋放佔用的內存地址。> *query cache優缺點 >> 1. query 語句的 hash 計算和 hash 查找帶來的資源消耗。mysql 會對每條接收到的 select 類型的 query 進行 hash 計算而後查找該query 的 cache 是否存在,雖然 hash 計算和查找的效率已經足夠高了,一條query 所帶來的消耗能夠忽略,但一旦涉及到高併發,有成千上萬條 query 時,hash計算和查找所帶來的開銷就的重視了;>> 2. query cache 的失效問題。若是表變動比較頻繁,則會形成 query cache 的失效率很是高。表變動不只僅指表中的數據發生變化,還包括結構或者索引的任何變化;>> 3. 對於不一樣 sql 但同一結果集的 query都會被緩存,這樣便會形成內存資源的過渡消耗。sql 的字符大小寫、空格或者註釋的不一樣,緩存都是認爲是不一樣的 sql(由於他們的 hash 值會不一樣);>> 4. 相關參數設置不合理會形成大量內存碎片,相關的參數設置會稍後介紹。
  4. readbuffersize >是 MySQL 讀入緩衝區大小。對錶進行順序掃描的請求將分配一個讀入緩衝區,MySQL 會爲它分配一段內存緩衝區。readbuffersize 變量控制這一緩衝區的大小。若是對錶的順序掃描請求很是頻繁,而且你認爲頻繁掃描進行得太慢,能夠經過增長該變量值以及內存緩衝區大小提升其性能。

14.若一張表中只有一個字段 VARCHAR(N)類型,utf8 編碼,則 N 最大值爲多少(精確到數量級便可)?

因爲 utf8 的每一個字符最多佔用 3 個字節。而 MySQL 定義行的長度不能超過65535,所以 N 的最大值計算方法爲:(65535-1-2)/3。減去 1 的緣由是實際存儲從第二個字節開始,減去 2 的緣由是由於要在列表長度存儲實際的字符長度,除以 3 是由於utf8 限制:每一個字符最多佔用 3 個字節。服務器

15. [SELECT *] 和[SELECT 所有字段]的 2 種寫法有何優缺點?

  1. 前者要解析數據字典,後者不須要
  2. 結果輸出順序,前者與建表列順序相同,後者按指定字段順序。
  3. 表字段更名,前者不須要修改,後者須要改
  4. 後者能夠創建索引進行優化,前者沒法優化
  5. 後者的可讀性比前者要高

16.HAVNG 子句 和 WHERE 的異同點?

  1. 語法上:where 用表中列名,having 用 select 結果別名
  2. 影響結果範圍:where 從表讀出數據的行數,having 返回客戶端的行數
  3. 索引:where 可使用索引,having 不能使用索引,只能在臨時結果集操做
  4. where 後面不能使用匯集函數,having 是專門使用匯集函數的。

17.MySQL 當記錄不存在時 insert,當記錄存在時 update,語句怎麼寫?

INSERT INTO table (a,b,c) VALUES (1,2,3) ON DUPLICATE KEYUPDATE c=c+1;微信

18.MySQL 的 insert 和 update 的 select 語句語法

SQL insert into student (stuid,stuname,deptid) select 10,'xzm',3from student where stuid > 8;
update student a inner join student b on b.stuID=10 seta.
stuname=concat(b.stuname, b.stuID) where a.stuID=10 ;

複製代碼

您的關注轉發是我繼續前行的動力,感謝您的閱讀,讚揚。數據結構

歡迎關注微信公衆號:慕容千語的架構筆記。歡迎關注一塊兒進步。
相關文章
相關標籤/搜索