常問的MySQL面試題整理


  • char、varchar 的區別是什么?

    • varchar是變長而char的長度是固定的。如果創建的列是固定大小的,你會得到更好的性能
  • truncate 和 delete 的區別是什么?

    • delete 命令從一個表中刪除某一行,或多行,可以使用用where,truncate 命令清空表里的所有數據,再插入數據時自增 id 從 1 開始
  • 什么是觸發器,MySQL 中都有哪些觸發器?

    • 觸發器是指一段代碼,當觸發某個事件,自動執行這些代碼(維護數據庫的一致性的完整性)。MySQL中的觸發器有如下六種:
    1. Before Insert
    2. After Insert
    3. Before Update
    4. After Update
    5. Before Delete
    6. After Delete
  • float 和 double 的區別是什么?

    • float 類型數據可以存儲之多8位十進制數,並在內存中占4字節
    • double類型數據可以存儲至多18位十進制數,並在內存中占8字節
  • 如何在 MySQL 中獲取當前日期?

    • select curdate();
    • select current_date();
    • select date_format(now(), '%y%m%d');
  • 如何查詢第 n 高的工資?

    • select distinct(salary) from employee order by salary desc limit n-1, 1;
  • 請寫出下面 MySQL 數據類型表達的意義(int(0), char(16), varchar(16), datetime, text)

  • 數據類型考點:

    • 整數類型:包括 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,但是如果表中有timestamp類的列,每次更新時timestamp列都會自動更新為當前時間戳

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存儲引擎:

1、InnoDB存儲引擎

  • 默認事物型引擎,最重要最廣泛的存儲引擎,性能非常優秀。
  • 數據存儲在共享表空間,可以通過配置分開。也就是多個表和索引都存儲在一個表空間中,可以通過配置文件改變此配置
  • 對主鍵查詢的性能高於其他類型的存儲引擎
  • 內部做了很多優化,從磁盤讀取數據時會自動構建hash索引,插入數據時自動構建插入緩沖區
  • 通過一些機制和工具支持真正的熱備份
  • 支持崩潰后的安全回復
  • 支持行級鎖
  • 支持外鍵

2、MyISAM存儲引擎

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

3、其他引擎

Archive、Blackhole、CSV、Memory

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

MySQL鎖機制

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

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

MySQL事物處理

  • MySQL提供事物處理的表引擎,InnoDB
  • 服務器層不管理事物,由下層的引擎實現,所以同一個事物中,使用多種引擎是不靠譜的
  • 需要注意,在非事物表上執行事物操作,MySQL不會發出提醒,也不會報錯

存儲過程

  • 為以后的使用保存的一條或多條MySQL語句的集合,因此也可以在存儲過程中加入業務邏輯和流程
  • 可以在存儲過程中創建表,更新數據,刪除數據等等

使用策略

  • 可以通過把SQL語句封裝在容易使用的單元中,簡化復雜的操作
  • 可以保證數據的一致性
  • 可以簡化對變動的管理

觸發器

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

使用場景

  • 可以通過數據庫中的相關表實現級聯更改

  • 實時監控某張表中的某個字段的更改而需要做出相應的處理

  • 例如可以生成某些業務的編號

  • 注意不要濫用。否則會造成數據庫及應用程序的維護困難

  • InnoDB和MyISAM的區別

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

    • 插入緩沖(insert buffer)
    • 二次寫(double write)
    • 自適應哈希索引(ahi)
    • 預讀(read ahead)
  • varchar和text的區別

    • varchar可指定字符數,text不能指定,內部存儲varchar是存入的實際字符數+1個字節(n<=255)或2個字節(n>255),text是實際字符數+2個字節
    • text類型不能有默認值
    • varchar可直接創建索引,text創建索引要指定前多少個字符。varchar查詢速度快於text,在都創建索引的情況下,text的索引幾乎不起作用
    • 查詢text需要創建臨時表
  • varchar(50)中50的涵義
    最多存放50個字符,varchar(50)和(200)存儲hello所占空間一樣,但后者在排序時會消耗更多內存,因為order by col采用fixed_lengtn計算col長度(memory引擎也一樣)

  • MySQL中,索引,主鍵,唯一索引,聯合索引的區別,對數據庫性能有什么影響

    • 索引的基礎
      • 索引類似於書籍的目錄,要想找到一本書的某個特定主題,需要先查找書的目錄,定位對應的頁面
      • 存儲引擎使用類似的方式進行數據查詢,先去索引當中找到對應的值,然后根據匹配的索引找到對應的數據行
    • 創建索引的語法
      • 首先創建一個表:create table t1 (id int primary key,username varchar(20),password varchar(20));
      • 創建單個索引的語法:create index 索引名 on 表名(字段名);
      • 索引名一般是:表名_字段名
      • 給id創建索引:create index ti_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關鍵字后的列
      • 索引列的基數越大,數據區分度越高,索引的效果越好
      • 對於字符串進行索引,應該制定一個前綴長度,可以節省大量的索引空間
      • 根據情況創建聯合索引,聯合索引可以提高查詢效率
      • 避免創建過多的所有,所有會額外占用磁盤空間,降低寫操作效率
      • 主鍵盡可能選擇較短的數據類型,可以有效減少索引的磁盤占用提高查詢效率


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM