最常問的MySQL面試題集合(一)

除了基礎題部分,小編收集整理的MySQL面試題還包括以下知識點或題型:

  • MySQL高性能索引
  • SQL語句
  • MySQL查詢優化
  • MySQL高擴展高可用
  • MySQL安全性
爲了不收藏不看,讓你們更有耐心看下去,印象更深入些,民工哥將分幾回分別發佈這些內容,歡迎持續關注公衆號後續文章分享。

問題1:char、varchar的區別是什麼?
varchar是變長而char的長度是固定的。若是你的內容是固定大小的,你會獲得更好的性能。mysql

問題2: TRUNCATE和DELETE的區別是什麼?
DELETE命令從一個表中刪除某一行,或多行,TRUNCATE命令永久地從表中刪除每一行。程序員

問題3:什麼是觸發器,MySQL中都有哪些觸發器?
觸發器是指一段代碼,當觸發某個事件時,自動執行這些代碼。在MySQL數據庫中有以下六種觸發器:面試

  • 一、Before Insert
  • 二、After Insert
  • 三、Before Update
  • 四、After Update
  • 五、Before Delete
  • 六、After Delete

問題4:FLOAT和DOUBLE的區別是什麼?sql

  • FLOAT類型數據能夠存儲至多8位十進制數,並在內存中佔4字節。
  • DOUBLE類型數據能夠存儲至多18位十進制數,並在內存中佔8字節。

問題5:如何在MySQL種獲取當前日期?數據庫

SELECT CURRENT_DATE();

問題6:如何查詢第n高的工資?安全

SELECT DISTINCT(salary) from employee ORDER BY salary DESC LIMIT n-1,1

問題7:請寫出下面MySQL數據類型表達的意義(int(0)、char(16)、varchar(16)、datetime、text)服務器

知識點分析

此題考察的是MySQL數據類型。MySQL數據類型屬於MySQL數據庫基礎,由此延伸出的知識點還包括以下內容:數據結構

  • MySQL基礎操做
  • MySQL存儲引擎
  • MySQL鎖機制
  • MySQL事務處理、存儲過程、觸發器

數據類型考點:併發

  • 一、整數類型,包括TINYINT、SMALLINT、MEDIUMINT、INT、BIGINT,分別表示1字節、2字節、3字節、4字節、8字節整數。任何整數類型均可以加上UNSIGNED屬性,表示數據是無符號的,即非負整數。
    長度:整數類型能夠被指定長度,例如:INT(11)表示長度爲11的INT類型。長度在大多數場景是沒有意義的,它不會限制值的合法範圍,只會影響顯示字符的個數,並且須要和UNSIGNED ZEROFILL屬性配合使用纔有意義。
    例子,假定類型設定爲INT(5),屬性爲UNSIGNED ZEROFILL,若是用戶插入的數據爲12的話,那麼數據庫實際存儲數據爲00012。
  • 二、實數類型,包括FLOAT、DOUBLE、DECIMAL。
    DECIMAL能夠用於存儲比BIGINT還大的整型,能存儲精確的小數。
    而FLOAT和DOUBLE是有取值範圍的,並支持使用標準的浮點進行近似計算。
    計算時FLOAT和DOUBLE相比DECIMAL效率更高一些,DECIMAL你能夠理解成是用字符串進行處理。
  • 三、字符串類型,包括VARCHAR、CHAR、TEXT、BLOB
    VARCHAR用於存儲可變長字符串,它比定長類型更節省空間。
    VARCHAR使用額外1或2個字節存儲字符串長度。列長度小於255字節時,使用1字節表示,不然使用2字節表示。
    VARCHAR存儲的內容超出設置的長度時,內容會被截斷。
    CHAR是定長的,根據定義的字符串長度分配足夠的空間。
    CHAR會根據須要使用空格進行填充方便比較。
    CHAR適合存儲很短的字符串,或者全部值都接近同一個長度。
    CHAR存儲的內容超出設置的長度時,內容一樣會被截斷。

使用策略:
對於常常變動的數據來講,CHAR比VARCHAR更好,由於CHAR不容易產生碎片。
對於很是短的列,CHAR比VARCHAR在存儲空間上更有效率。
使用時要注意只分配須要的空間,更長的列排序時會消耗更多內存。
儘可能避免使用TEXT/BLOB類型,查詢時會使用臨時表,致使嚴重的性能開銷。函數

  • 四、枚舉類型(ENUM),把不重複的數據存儲爲一個預約義的集合。
    有時可使用ENUM代替經常使用的字符串類型。
    ENUM存儲很是緊湊,會把列表值壓縮到一個或兩個字節。
    ENUM在內部存儲時,其實存的是整數。
    儘可能避免使用數字做爲ENUM枚舉的常量,由於容易混亂。
    排序是按照內部存儲的整數
  • 五、日期和時間類型,儘可能使用timestamp,空間效率高於datetime,
    用整數保存時間戳一般不方便處理。
    若是須要存儲微妙,可使用bigint存儲。
    看到這裏,這道真題是否是就比較容易回答了。

答:int(0)表示數據是INT類型,長度是0、char(16)表示固定長度字符串,長度爲1六、varchar(16)表示可變長度字符串,長度爲1六、datetime表示時間類型、text表示字符串類型,能存儲大字符串,最多存儲65535字節數據)

MySQL基礎操做:

常見操做

MySQL的鏈接和關閉:mysql -u -p -h -P
-u:指定用戶名
-p:指定密碼
-h:主機
-P:端口
進入MySQL命令行後:G、c、q、s、h、d
G:打印結果垂直顯示
c:取消當前MySQL命令
q:退出MySQL鏈接
s:顯示服務器狀態
h:幫助信息
d:改變執行符

MySQL存儲引擎:

一、InnoDB存儲引擎,

  • 默認事務型引擎,最重要最普遍的存儲引擎,性能很是優秀。
  • 數據存儲在共享表空間,能夠經過配置分開。也就是多個表和索引都存儲在一個表空間中,能夠經過配置文件改變此配置。
  • 對主鍵查詢的性能高於其餘類型的存儲引擎。
  • 內部作了不少優化,從磁盤讀取數據時會自動構建hash索引,插入數據時自動構建插入緩衝區。
  • 經過一些機制和工具支持真正的熱備份。
  • 支持崩潰後的安全恢復。
  • 支持行級鎖。
  • 支持外鍵。

二、MyISAM存儲引擎,

  • 擁有全文索引、壓縮、空間函數。
  • 不支持事務和行級鎖、不支持崩潰後的安全恢復。
  • 表存儲在兩個文件,MYD和MYI。
  • 設計簡單,某些場景下性能很好,例如獲取整個表有多少條數據,性能很高。
  • 全文索引不是很經常使用,不如使用外部的ElasticSearch或Lucene。

三、其餘表引擎,
Archive、Blackhole、CSV、Memory

使用策略
在大多數場景下建議使用InnoDB存儲引擎。

MySQL鎖機制

表鎖是平常開發中的常見問題,所以也是面試當中最多見的考察點,當多個查詢同一時刻進行數據修改時,就會產生併發控制的問題。共享鎖和排他鎖,就是讀鎖和寫鎖。

  • 共享鎖,不堵塞,多個用戶能夠同時讀一個資源,互不干擾。
  • 排他鎖,一個寫鎖會阻塞其餘的讀鎖和寫鎖,這樣能夠只容許一個用戶進行寫入,防止其餘用戶讀取正在寫入的資源。
鎖的粒度
  • 表鎖,系統開銷最小,會鎖定整張表,MyIsam使用表鎖。
  • 行鎖,最大程度的支持併發處理,可是也帶來了最大的鎖開銷,InnoDB使用行鎖。

MySQL事務處理

  • MySQL提供事務處理的表引擎,也就是InnoDB。
  • 服務器層無論理事務,由下層的引擎實現,因此同一個事務中,使用多種引擎是不靠譜的。
  • 須要注意,在非事務表上執行事務操做,MySQL不會發出提醒,也不會報錯。

存儲過程

  • 爲之後的使用保存的一條或多條MySQL語句的集合,所以也能夠在存儲過程當中加入業務邏輯和流程。
  • 能夠在存儲過程當中建立表,更新數據,刪除數據等等。

使用策略

  • 能夠經過把SQL語句封裝在容易使用的單元中,簡化複雜的操做
  • 能夠保證數據的一致性
  • 能夠簡化對變更的管理

觸發器

提供給程序員和數據分析員來保證數據完整性的一種方法,它是與表事件相關的特殊的存儲過程。
使用場景

  • 能夠經過數據庫中的相關表實現級聯更改。
  • 實時監控某張表中的某個字段的更改而須要作出相應的處理。
  • 例如能夠生成某些業務的編號。
  • 注意不要濫用,不然會形成數據庫及應用程序的維護困難。
  • 你們須要牢記以上基礎知識點,重點是理解數據類型CHAR和VARCHAR的差別,表存儲引擎InnoDB和MyISAM的區別。

問題8:請說明InnoDB和MyISAM的區別

  • InnoDB支持事務,MyISAM不支持;
  • InnoDB數據存儲在共享表空間,MyISAM數據存儲在文件中;
  • InnoDB支持行級鎖,MyISAM只支持表鎖;
  • InnoDB支持崩潰後的恢復,MyISAM不支持;
  • InnoDB支持外鍵,MyISAM不支持;
  • InnoDB不支持全文索引,MyISAM支持全文索引;

問題9:innodb引擎的特性

  • 插入緩衝(insert buffer)
  • 二次寫(double write)
  • 自適應哈希索引(ahi)
  • 預讀(read ahead)

問題10:請列舉3個以上表引擎
InnoDB、MyISAM、Memory

問題11:請說明varchar和text的區別

  • varchar可指定字符數,text不能指定,內部存儲varchar是存入的實際字符數+1個字節(n<=255)或2個字節(n>255),text是實際字符數+2個字節。
  • text類型不能有默認值。
  • varchar可直接建立索引,text建立索引要指定前多少個字符。varchar查詢速度快於text,在都建立索引的狀況下,text的索引幾乎不起做用。
  • 查詢text須要建立臨時表。

問題11:varchar(50)中50的含義
最多存放50個字符,varchar(50)和(200)存儲hello所佔空間同樣,但後者在排序時會消耗更多內存,由於order by col採用fixed_length計算col長度(memory引擎也同樣)。

問題12:int(20)中20的含義
是指顯示字符的長度,不影響內部存儲,只是當定義了ZEROFILL時,前面補多少個 0

問題13:簡單描述MySQL中,索引,主鍵,惟一索引,聯合索引的區別,對數據庫的性能有什麼影響?

知識點分析

此真題主要考察的是MySQL索引的基礎和類型,由此延伸出的知識點還包括以下內容:

  • MySQL索引的建立原則
  • MySQL索引的注意事項
  • MySQL索引的原理
下面咱們就來將這些知識一網打盡

索引的基礎

  • 索引相似於書籍的目錄,要想找到一本數的某個特定主題,須要先查找書的目錄,定位對應的頁碼
  • 存儲引擎使用相似的方式進行數據查詢,先去索引當中找到對應的值,而後根據匹配的索引找到對應的數據行。

建立索引的語法:

  • 首先建立一個表:create table t1 (id int primary key,username varchar(20),password varchar(20));
  • 建立單個索引的語法:CREATE INDEX 索引名 on 表名(字段名)
  • 索引名通常是:表名_字段名
  • 給id建立索引:CREATE INDEX t1_id on t1(id);
  • 建立聯合索引的語法:CREATE INDEX 索引名 on 表名(字段名1,字段名2)
  • 給username和password建立聯合索引:CREATE index t1_username_password ON t1(username,password)
  • 其中index還能夠替換成unique,primary key,分別表明惟一索引和主鍵索引
  • 刪除索引:DROP INDEX t1_username_password ON t1

索引對性能的影響:

  • 大大減小服務器須要掃描的數據量。
  • 幫助服務器避免排序和臨時表。
  • 將隨機I/O變順序I/O。
  • 大大提升查詢速度。
  • 下降寫的速度(不良影響)。
  • 磁盤佔用(不良影響)。

索引的使用場景:

  • 對於很是小的表,大部分狀況下全表掃描效率更高。
  • 中到大型表,索引很是有效。
  • 特大型的表,創建和使用索引的代價會隨之增大,可使用分區技術來解決。

索引的類型:
索引不少種類型,是在MySQL的存儲引擎實現的。

  • 普通索引:最基本的索引,沒有任何約束限制。
  • 惟一索引:和普通索引相似,可是具備惟一性約束。
  • 主鍵索引:特殊的惟一索引,不容許有空值。

索引的區別:
-一個表只能有一個主鍵索引,可是能夠有多個惟一索引。

  • 主鍵索引必定是惟一索引,惟一索引不是主鍵索引。
  • 主鍵能夠與外鍵構成參照完整性約束,防止數據不一致。
  • 聯合索引:將多個列組合在一塊兒建立索引,能夠覆蓋多個列。(也叫複合索引,組合索引)
  • 外鍵索引:只有InnoDB類型的表纔可使用外鍵索引,保證數據的一致性、完整性、和實現級聯操做(基本不用)。
  • 全文索引:MySQL自帶的全文索引只能用於MyISAM,而且只能對英文進行全文檢索 (基本不用)

MySQL索引的建立原則

  • 最適合建立索引的列是出如今WHERE或ON子句中的列,或鏈接子句中的列而不是出如今SELECT關鍵字後的列。
  • 索引列的基數越大,數據區分度越高,索引的效果越好。
  • 對於字符串進行索引,應該制定一個前綴長度,能夠節省大量的索引空間。
  • 根據狀況建立聯合索引,聯合索引能夠提升查詢效率。
  • 避免建立過多的索引,索引會額外佔用磁盤空間,下降寫操做效率。
  • 主鍵儘量選擇較短的數據類型,能夠有效減小索引的磁盤佔用提升查詢效率。

MySQL索引的注意事項
一、聯合索引遵循前綴原則

KEY(a,b,c)WHERE a = 1 AND b = 2 AND c = 3WHERE a = 1 AND b = 2WHERE a = 1#以上SQL語句能夠用到索引WHERE b = 2 AND c = 3WHERE a = 1 AND c = 3#以上SQL語句用不到索引

二、LIKE查詢,%不能在前

WHERE name LIKE "%wang%"#以上語句用不到索引,能夠用外部的ElasticSearch、Lucene等全文搜索引擎替代。

三、列值爲空(NULL)時是可使用索引的,但MySQL難以優化引用了可空列的查詢,它會使索引、索引統計和值更加複雜。可空列須要更多的儲存空間,還須要在MySQL內部進行特殊處理。

四、若是MySQL估計使用索引比全表掃描更慢,會放棄使用索引,例如:
表中只有100條數據左右。對於SQL語句WHERE id > 1 AND id < 100,MySQL會優先考慮全表掃描。

五、若是關鍵詞or前面的條件中的列有索引,後面的沒有,全部列的索引都不會被用到。

六、列類型是字符串,查詢時必定要給值加引號,不然索引失效,例如:
列name varchar(16),存儲了字符串"100"
WHERE name = 100;
以上SQL語句能搜到,但沒法用到索引。

MySQL索引的原理

  • MySQL索引是用一種叫作聚簇索引的數據結構實現的,下面咱們就來看一下什麼是聚簇索引。
  • 聚簇索引是一種數據存儲方式,它其實是在同一個結構中保存了B+樹索引和數據行,InnoDB表是按照聚簇索引組織的(相似於Oracle的索引組織表)。
注:B+ 樹是一種樹數據結構,是一個n叉排序樹,每一個節點一般有多個孩子,一棵B+樹包含根節點、內部節點和葉子節點。根節點多是一個葉子節點,也多是一個包含兩個或兩個以上孩子節點的節點。B+ 樹一般用於數據庫和操做系統的文件系統中。NTFS, ReiserFS, NSS, XFS, JFS, ReFS 和BFS等文件系統都在使用B+樹做爲元數據索引。B+ 樹的特色是可以保持數據穩定有序,其插入與修改擁有較穩定的對數時間複雜度。B+ 樹元素自底向上插入。

InnoDB經過主鍵聚簇數據,若是沒有定義主鍵,會選擇一個惟一的非空索引代替,若是沒有這樣的索引,會隱式定義個主鍵做爲聚簇索引。
下圖形象說明了聚簇索引表(InnoDB)和普通的堆組織表(MyISAM)的區別:

最常問的MySQL面試題三——每一個開發人員都應該知道
對於普通的堆組織表來講(右圖),表數據和索引是分別存儲的,主鍵索引和二級索引存儲上沒有任何區別。
而對於聚簇索引表來講(左圖),表數據是和主鍵一塊兒存儲的,主鍵索引的葉結點存儲行數據,二級索引的葉結點存儲行的主鍵值。
聚簇索引表最大限度地提升了I/O密集型應用的性能,但它也有如下幾個限制:

  • 1)插入速度嚴重依賴於插入順序,按照主鍵的順序插入是最快的方式,不然將會出現頁分裂,嚴重影響性能。所以,對於InnoDB表,咱們通常都會定義一個自增的ID列爲主鍵。
  • 2)更新主鍵的代價很高,由於將會致使被更新的行移動。所以,對於InnoDB表,咱們通常定義主鍵爲不可更新。
  • 3)二級索引訪問須要兩次索引查找,第一次找到主鍵值,第二次根據主鍵值找到行數據。

二級索引的葉節點存儲的是主鍵值,而不是行指針,這是爲了減小當出現行移動或數據頁分裂時二級索引的維護工做,但會讓二級索引佔用更多的空間。

解題方法

在一些MySQL索引基礎考題中,咱們能夠輕鬆的經過索引基礎和類型來解決此類問題,對於一些索引建立注意事項方面的考點,咱們能夠經過索引建立原則和注意事項來解決。

問題14:建立MySQL聯合索引應該注意什麼?
需遵循前綴原則

問題15:列值爲NULL時,查詢是否會用到索引?
在MySQL裏NULL值的列也是走索引的。固然,若是計劃對列進行索引,就要儘可能避免把它設置爲可空,MySQL難以優化引用了可空列的查詢,它會使索引、索引統計和值更加複雜。

_問題16:如下語句是否會應用索引:SELECT_FROM users WHERE YEAR(adddate) < 2007;*
不會,由於只要列涉及到運算,MySQL就不會使用索引。

問題17:MyISAM索引實現?
MyISAM存儲引擎使用B+Tree做爲索引結構,葉節點的data域存放的是數據記錄的地址。MyISAM的索引方式也叫作非聚簇索引的,之因此這麼稱呼是爲了與InnoDB的聚簇索引區分。

問題17:MyISAM索引與InnoDB索引的區別?

  • InnoDB索引是聚簇索引,MyISAM索引是非聚簇索引。
  • InnoDB的主鍵索引的葉子節點存儲着行數據,所以主鍵索引很是高效。
  • MyISAM索引的葉子節點存儲的是行數據地址,須要再尋址一次才能獲得數據。
  • InnoDB非主鍵索引的葉子節點存儲的是主鍵和其餘帶索引的列數據,所以查詢時作到覆蓋索引會很是高效。

問題18:如下三條sql 如何建索引,只建一條怎麼建?

WHERE a=1 AND b=1WHERE b=1WHERE b=1 ORDER BY time DESC

以順序b,a,time創建聯合索引,CREATE INDEX table1_b_a_time ON index_test01(b,a,time)。由於最新MySQL版本會優化WHERE子句後面的列順序,以匹配聯合索引順序。

問題19:有A(id,sex,par,c1,c2),B(id,age,c1,c2)兩張表,其中A.id與B.id關聯,如今要求寫出一條SQL語句,將B中age>50的記錄的c1,c2更新到A表中同一記錄中的c1,c2字段中
考點分析
這道題主要考察的是MySQL的關聯UPDATE語句
延伸考點:

  • MySQL的關聯查詢語句
  • MySQL的關聯UPDATE語句
針對剛纔這道題,答案能夠是以下兩種形式的寫法:
UPDATE A,B SET A.c1 = B.c1, A.c2 = B.c2 WHERE A.id = B.idUPDATE A INNER JOIN B ON A.id=B.id SET A.c1 = B.c1,A.c2=B.c2再加上B中age>50的條件:UPDATE A,B set A.c1 = B.c1, A.c2 = B.c2 WHERE A.id = B.id and B.age > 50;UPDATE A INNER JOIN B ON A.id = B.id set A.c1 = B.c1,A.c2 = B.c2 WHERE B.age > 50
相關文章
相關標籤/搜索