100道MySQL數據庫經典面試題解析(收藏版)

前言

100道MySQL數據庫經典面試題解析,已經上傳github啦html

github.com/whx123/Java…java

公衆號:撿田螺的小男孩mysql

數據庫

1. MySQL 索引使用有哪些注意事項呢?

能夠從三個維度回答這個問題:索引哪些狀況會失效,索引不適合哪些場景,索引規則git

索引哪些狀況會失效

  • 查詢條件包含or,可能致使索引失效
  • 如何字段類型是字符串,where時必定用引號括起來,不然索引失效
  • like通配符可能致使索引失效。
  • 聯合索引,查詢時的條件列不是聯合索引中的第一個列,索引失效。
  • 在索引列上使用mysql的內置函數,索引失效。
  • 對索引列運算(如,+、-、*、/),索引失效。
  • 索引字段上使用(!= 或者 < >,not in)時,可能會致使索引失效。
  • 索引字段上使用is null, is not null,可能致使索引失效。
  • 左鏈接查詢或者右鏈接查詢查詢關聯的字段編碼格式不同,可能致使索引失效。
  • mysql估計使用全表掃描要比使用索引快,則不使用索引。

後端程序員必備:索引失效的十大雜症程序員

索引不適合哪些場景

  • 數據量少的不適合加索引
  • 更新比較頻繁的也不適合加索引
  • 區分度低的字段不適合加索引(如性別)

索引的一些潛規則

  • 覆蓋索引
  • 回表
  • 索引數據結構(B+樹)
  • 最左前綴原則
  • 索引下推

2. MySQL 遇到過死鎖問題嗎,你是如何解決的?

我排查死鎖的通常步驟是醬紫的:github

  • 查看死鎖日誌show engine innodb status;
  • 找出死鎖Sql
  • 分析sql加鎖狀況
  • 模擬死鎖案發
  • 分析死鎖日誌
  • 分析死鎖結果

能夠看我這兩篇文章哈:面試

3. 平常工做中你是怎麼優化SQL的?

能夠從這幾個維度回答這個問題:redis

  • 加索引
  • 避免返回沒必要要的數據
  • 適當分批量進行
  • 優化sql結構
  • 分庫分表
  • 讀寫分離

能夠看我這篇文章哈: 後端程序員必備:書寫高質量SQL的30條建議算法

4. 說說分庫與分表的設計

分庫分表方案,分庫分表中間件,分庫分表可能遇到的問題sql

分庫分表方案:

  • 水平分庫:以字段爲依據,按照必定策略(hash、range等),將一個庫中的數據拆分到多個庫中。
  • 水平分表:以字段爲依據,按照必定策略(hash、range等),將一個表中的數據拆分到多個表中。
  • 垂直分庫:以表爲依據,按照業務歸屬不一樣,將不一樣的表拆分到不一樣的庫中。
  • 垂直分表:以字段爲依據,按照字段的活躍性,將表中字段拆到不一樣的表(主表和擴展表)中。

經常使用的分庫分表中間件:

  • sharding-jdbc(噹噹)
  • Mycat
  • TDDL(淘寶)
  • Oceanus(58同城數據庫中間件)
  • vitess(谷歌開發的數據庫中間件)
  • Atlas(Qihoo 360)

分庫分表可能遇到的問題

  • 事務問題:須要用分佈式事務啦
  • 跨節點Join的問題:解決這一問題能夠分兩次查詢實現
  • 跨節點的count,order by,group by以及聚合函數問題:分別在各個節點上獲得結果後在應用程序端進行合併。
  • 數據遷移,容量規劃,擴容等問題
  • ID問題:數據庫被切分後,不能再依賴數據庫自身的主鍵生成機制啦,最簡單能夠考慮UUID
  • 跨分片的排序分頁問題(後臺加大pagesize處理?)

我的以爲網上這兩篇文章不錯,小夥伴們能夠去看一下哈:

5. InnoDB與MyISAM的區別

  • InnoDB支持事務,MyISAM不支持事務
  • InnoDB支持外鍵,MyISAM不支持外鍵
  • InnoDB 支持 MVCC(多版本併發控制),MyISAM 不支持
  • select count(*) from table時,MyISAM更快,由於它有一個變量保存了整個表的總行數,能夠直接讀取,InnoDB就須要全表掃描。
  • Innodb不支持全文索引,而MyISAM支持全文索引(5.7之後的InnoDB也支持全文索引)
  • InnoDB支持表、行級鎖,而MyISAM支持表級鎖。
  • InnoDB表必須有主鍵,而MyISAM能夠沒有主鍵
  • Innodb表須要更多的內存和存儲,而MyISAM可被壓縮,存儲空間較小,。
  • Innodb按主鍵大小有序插入,MyISAM記錄插入順序是,按記錄插入順序保存。
  • InnoDB 存儲引擎提供了具備提交、回滾、崩潰恢復能力的事務安全,與 MyISAM 比 InnoDB 寫的效率差一些,而且會佔用更多的磁盤空間以保留數據和索引

6. 數據庫索引的原理,爲何要用 B+樹,爲何不用二叉樹?

能夠從幾個維度去看這個問題,查詢是否夠快,效率是否穩定,存儲數據多少,以及查找磁盤次數,爲何不是二叉樹,爲何不是平衡二叉樹,爲何不是B樹,而恰恰是B+樹呢?

爲何不是通常二叉樹?

若是二叉樹特殊化爲一個鏈表,至關於全表掃描。平衡二叉樹相比於二叉查找樹來講,查找效率更穩定,整體的查找速度也更快。

爲何不是平衡二叉樹呢?

咱們知道,在內存比在磁盤的數據,查詢效率快得多。若是樹這種數據結構做爲索引,那咱們每查找一次數據就須要從磁盤中讀取一個節點,也就是咱們說的一個磁盤塊,可是平衡二叉樹但是每一個節點只存儲一個鍵值和數據的,若是是B樹,能夠存儲更多的節點數據,樹的高度也會下降,所以讀取磁盤的次數就降下來啦,查詢效率就快啦。

那爲何不是B樹而是B+樹呢?

1)B+樹非葉子節點上是不存儲數據的,僅存儲鍵值,而B樹節點中不只存儲鍵值,也會存儲數據。innodb中頁的默認大小是16KB,若是不存儲數據,那麼就會存儲更多的鍵值,相應的樹的階數(節點的子節點樹)就會更大,樹就會更矮更胖,如此一來咱們查找數據進行磁盤的IO次數有會再次減小,數據查詢的效率也會更快。

2)B+樹索引的全部數據均存儲在葉子節點,並且數據是按照順序排列的,鏈表連着的。那麼B+樹使得範圍查找,排序查找,分組查找以及去重查找變得異常簡單。

能夠看這篇文章哈: 再有人問你爲何MySQL用B+樹作索引,就把這篇文章發給她

7. 彙集索引與非彙集索引的區別

  • 一個表中只能擁有一個彙集索引,而非彙集索引一個表能夠存在多個。
  • 彙集索引,索引中鍵值的邏輯順序決定了表中相應行的物理順序;非彙集索引,索引中索引的邏輯順序與磁盤上行的物理存儲順序不一樣。
  • 索引是經過二叉樹的數據結構來描述的,咱們能夠這麼理解聚簇索引:索引的葉節點就是數據節點。而非聚簇索引的葉節點仍然是索引節點,只不過有一個指針指向對應的數據塊。
  • 彙集索引:物理存儲按照索引排序;非彙集索引:物理存儲不按照索引排序;

什麼時候使用匯集索引或非彙集索引?

8. limit 1000000 加載很慢的話,你是怎麼解決的呢?

方案一:若是id是連續的,能夠這樣,返回上次查詢的最大記錄(偏移量),再往下limit

select id,name from employee where id>1000000 limit 10.
複製代碼

方案二:在業務容許的狀況下限制頁數:

建議跟業務討論,有沒有必要查這麼後的分頁啦。由於絕大多數用戶都不會日後翻太多頁。

方案三:order by + 索引(id爲索引)

select id,name from employee order by id  limit 1000000,10
複製代碼

方案四:利用延遲關聯或者子查詢優化超多分頁場景。(先快速定位須要獲取的id段,而後再關聯)

SELECT a.* FROM employee a, (select id from employee where 條件 LIMIT 1000000,10 ) b where a.id=b.id
複製代碼

9. 如何選擇合適的分佈式主鍵方案呢?

  • 數據庫自增加序列或字段。
  • UUID。
  • Redis生成ID
  • Twitter的snowflake算法
  • 利用zookeeper生成惟一ID
  • MongoDB的ObjectId

10. 事務的隔離級別有哪些?MySQL的默認隔離級別是什麼?

  • 讀未提交(Read Uncommitted)
  • 讀已提交(Read Committed)
  • 可重複讀(Repeatable Read)
  • 串行化(Serializable)

Mysql默認的事務隔離級別是可重複讀(Repeatable Read)

能夠看我這篇文章哈:一文完全讀懂MySQL事務的四大隔離級別

11. 什麼是幻讀,髒讀,不可重複讀呢?

  • 事務A、B交替執行,事務A被事務B干擾到了,由於事務A讀取到事務B未提交的數據,這就是髒讀
  • 在一個事務範圍內,兩個相同的查詢,讀取同一條記錄,卻返回了不一樣的數據,這就是不可重複讀
  • 事務A查詢一個範圍的結果集,另外一個併發事務B往這個範圍中插入/刪除了數據,並靜悄悄地提交,而後事務A再次查詢相同的範圍,兩次讀取獲得的結果集不同了,這就是幻讀

能夠看我這篇文章哈:一文完全讀懂MySQL事務的四大隔離級別

12. 在高併發狀況下,如何作到安全的修改同一行數據?

要安全的修改同一行數據,就要保證一個線程在修改時其它線程沒法更新這行記錄。通常有悲觀鎖和樂觀鎖兩種方案~

使用悲觀鎖

悲觀鎖思想就是,當前線程要進來修改數據時,別的線程都得拒之門外~ 好比,可使用select…for update ~

select * from User where name=‘jay’ for update
複製代碼

以上這條sql語句會鎖定了User表中全部符合檢索條件(name=‘jay’)的記錄。本次事務提交以前,別的線程都沒法修改這些記錄。

使用樂觀鎖

樂觀鎖思想就是,有線程過來,先放過去修改,若是看到別的線程沒修改過,就能夠修改爲功,若是別的線程修改過,就修改失敗或者重試。實現方式:樂觀鎖通常會使用版本號機制或CAS算法實現。

能夠看一下我這篇文章,主要是思路哈~ CAS樂觀鎖解決併發問題的一次實踐

13. 數據庫的樂觀鎖和悲觀鎖。

悲觀鎖:

悲觀鎖她專注且缺少安全感了,她的心只屬於當前事務,每時每刻都擔憂着它心愛的數據可能被別的事務修改,因此一個事務擁有(得到)悲觀鎖後,其餘任何事務都不能對數據進行修改啦,只能等待鎖被釋放才能夠執行。

樂觀鎖:

樂觀鎖的「樂觀情緒」體如今,它認爲數據的變更不會太頻繁。所以,它容許多個事務同時對數據進行變更。實現方式:樂觀鎖通常會使用版本號機制或CAS算法實現。

以前轉載了的這篇文章,以爲做者寫得挺詳細的~

圖文並茂的帶你完全理解悲觀鎖與樂觀鎖

14. SQL優化的通常步驟是什麼,怎麼看執行計劃(explain),如何理解其中各個字段的含義。

  • show status 命令瞭解各類 sql 的執行頻率
  • 經過慢查詢日誌定位那些執行效率較低的 sql 語句
  • explain 分析低效 sql 的執行計劃(這點很是重要,平常開發中用它分析Sql,會大大下降Sql致使的線上事故)

看過這篇文章,以爲很不錯: 優化sql 語句的通常步驟

15. select for update有什麼含義,會鎖表仍是鎖行仍是其餘。

select for update 含義

select查詢語句是不會加鎖的,可是select for update除了有查詢的做用外,還會加鎖呢,並且它是悲觀鎖哦。至於加了是行鎖仍是表鎖,這就要看是否是用了索引/主鍵啦。

沒用索引/主鍵的話就是表鎖,不然就是是行鎖。

select for update 加鎖驗證

表結構:

//id 爲主鍵,name爲惟一索引
CREATE TABLE `account` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(255) DEFAULT NULL,
  `balance` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `idx_name` (`name`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=1570068 DEFAULT CHARSET=utf8
複製代碼

id爲主鍵,select for update 1270070這條記錄時,再開一個事務對該記錄更新,發現更新阻塞啦,實際上是加鎖了。以下圖:

咱們再開一個事務對另一條記錄1270071更新,發現更新成功,所以,若是查詢條件用了索引/主鍵, 會加行鎖~

咱們繼續一路向北吧,換普通字段balance吧,發現又阻塞了。所以,沒用索引/主鍵的話,select for update加的就是表鎖

16. MySQL事務得四大特性以及實現原理

  • 原子性: 事務做爲一個總體被執行,包含在其中的對數據庫的操做要麼所有被執行,要麼都不執行。
  • 一致性: 指在事務開始以前和事務結束之後,數據不會被破壞,假如A帳戶給B帳戶轉10塊錢,無論成功與否,A和B的總金額是不變的。
  • 隔離性: 多個事務併發訪問時,事務之間是相互隔離的,即一個事務不影響其它事務運行效果。簡言之,就是事務之間是進水不犯河水的。
  • 持久性: 表示事務完成之後,該事務對數據庫所做的操做更改,將持久地保存在數據庫之中。

事務ACID特性的實現思想

  • 原子性:是使用 undo log來實現的,若是事務執行過程當中出錯或者用戶執行了rollback,系統經過undo log日誌返回事務開始的狀態。
  • 持久性:使用 redo log來實現,只要redo log日誌持久化了,當系統崩潰,便可經過redo log把數據恢復。
  • 隔離性:經過鎖以及MVCC,使事務相互隔離開。
  • 一致性:經過回滾、恢復,以及併發狀況下的隔離性,從而實現一致性。

17. 若是某個表有近千萬數據,CRUD比較慢,如何優化。

分庫分表

某個表有近千萬數據,能夠考慮優化表結構,分表(水平分表,垂直分表),固然,你這樣回答,須要準備好面試官問你的分庫分表相關問題呀,如

  • 分表方案(水平分表,垂直分表,切分規則hash等)
  • 分庫分表中間件(Mycat,sharding-jdbc等)
  • 分庫分表一些問題(事務問題?跨節點Join的問題)
  • 解決方案(分佈式事務等)

索引優化

除了分庫分表,優化表結構,固然還有因此索引優化等方案~

有興趣能夠看我這篇文章哈~ 後端程序員必備:書寫高質量SQL的30條建議

18. 如何寫sql可以有效的使用到複合索引。

複合索引,也叫組合索引,用戶能夠在多個列上創建索引,這種索引叫作複合索引。

當咱們建立一個組合索引的時候,如(k1,k2,k3),至關於建立了(k1)、(k1,k2)和(k1,k2,k3)三個索引,這就是最左匹配原則。

select * from table where k1=A AND k2=B AND k3=D 
複製代碼

有關於複合索引,咱們須要關注查詢Sql條件的順序,確保最左匹配原則有效,同時能夠刪除沒必要要的冗餘索引。

19. mysql中in 和exists的區別。

這個,跟一下demo來看更刺激吧,啊哈哈

假設表A表示某企業的員工表,表B表示部門表,查詢全部部門的全部員工,很容易有如下SQL:

select * from A where deptId in (select deptId from B);
複製代碼

這樣寫等價於:

先查詢部門表B

select deptId from B

再由部門deptId,查詢A的員工

select * from A where A.deptId = B.deptId

能夠抽象成這樣的一個循環:

List<> resultSet ;
    for(int i=0;i<B.length;i++) {
          for(int j=0;j<A.length;j++) {
          if(A[i].id==B[j].id) {
             resultSet.add(A[i]);
             break;
          }
       }
    }
複製代碼

顯然,除了使用in,咱們也能夠用exists實現同樣的查詢功能,以下:

select * from A where exists (select 1 from B where A.deptId = B.deptId); 
複製代碼

由於exists查詢的理解就是,先執行主查詢,得到數據後,再放到子查詢中作條件驗證,根據驗證結果(true或者false),來決定主查詢的數據結果是否得意保留。

那麼,這樣寫就等價於:

select * from A,先從A表作循環

select * from B where A.deptId = B.deptId,再從B表作循環.

同理,能夠抽象成這樣一個循環:

List<> resultSet ;
    for(int i=0;i<A.length;i++) {
          for(int j=0;j<B.length;j++) {
          if(A[i].deptId==B[j].deptId) {
             resultSet.add(A[i]);
             break;
          }
       }
    }
複製代碼

數據庫最費勁的就是跟程序連接釋放。假設連接了兩次,每次作上百萬次的數據集查詢,查完就走,這樣就只作了兩次;相反創建了上百萬次連接,申請連接釋放反覆重複,這樣系統就受不了了。即mysql優化原則,就是小表驅動大表,小的數據集驅動大的數據集,從而讓性能更優。

所以,咱們要選擇最外層循環小的,也就是,若是B的數據量小於A,適合使用in,若是B的數據量大於A,即適合選擇exists,這就是in和exists的區別。

20. 數據庫自增主鍵可能遇到什麼問題。

  • 使用自增主鍵對數據庫作分庫分表,可能出現諸如主鍵重複等的問題。解決方案的話,簡單點的話能夠考慮使用UUID哈
  • 自增主鍵會產生表鎖,從而引起問題
  • 自增主鍵可能用完問題。

21. MVCC熟悉嗎,它的底層原理?

MVCC,多版本併發控制,它是經過讀取歷史版本的數據,來下降併發事務衝突,從而提升併發性能的一種機制。

MVCC須要關注這幾個知識點:

  • 事務版本號
  • 表的隱藏列
  • undo log
  • read view

能夠看我這篇文章哈:一文完全讀懂MySQL事務的四大隔離級別

22. 數據庫中間件瞭解過嗎,sharding jdbc,mycat?

  • sharding-jdbc目前是基於jdbc驅動,無需額外的proxy,所以也無需關注proxy自己的高可用。
  • Mycat 是基於 Proxy,它複寫了 MySQL 協議,將 Mycat Server 假裝成一個 MySQL 數據庫,而 Sharding-JDBC 是基於 JDBC 接口的擴展,是以 jar 包的形式提供輕量級服務的。

有網友推薦這篇文章:

深度認識Sharding-JDBC:作最輕量級的數據庫中間層

23. MYSQL的主從延遲,你怎麼解決?

嘻嘻,先複習一下主從複製原理吧,如圖:

主從複製分了五個步驟進行:

  • 步驟一:主庫的更新事件(update、insert、delete)被寫到binlog
  • 步驟二:從庫發起鏈接,鏈接到主庫。
  • 步驟三:此時主庫建立一個binlog dump thread,把binlog的內容發送到從庫。
  • 步驟四:從庫啓動以後,建立一個I/O線程,讀取主庫傳過來的binlog內容並寫入到relay log
  • 步驟五:還會建立一個SQL線程,從relay log裏面讀取內容,從Exec_Master_Log_Pos位置開始執行讀取到的更新事件,將更新內容寫入到slave的db

有興趣的小夥伴也能夠看看我這篇文章: 後端程序員必備:mysql數據庫相關流程圖/原理圖

主從同步延遲的緣由

一個服務器開放N個連接給客戶端來鏈接的,這樣有會有大併發的更新操做, 可是從服務器的裏面讀取binlog的線程僅有一個,當某個SQL在從服務器上執行的時間稍長 或者因爲某個SQL要進行鎖表就會致使,主服務器的SQL大量積壓,未被同步到從服務器裏。這就致使了主從不一致, 也就是主從延遲。

主從同步延遲的解決辦法

  • 主服務器要負責更新操做,對安全性的要求比從服務器要高,因此有些設置參數能夠修改,好比sync_binlog=1,innodb_flush_log_at_trx_commit = 1 之類的設置等。
  • 選擇更好的硬件設備做爲slave。
  • 把一臺從服務器當度做爲備份使用, 而不提供查詢, 那邊他的負載下來了, 執行relay log 裏面的SQL效率天然就高了。
  • 增長從服務器嘍,這個目的仍是分散讀的壓力,從而下降服務器負載。

能夠看這篇文章哈~ MySQL 主從同步延遲的緣由及解決辦法

24. 說一下大表查詢的優化方案

  • 優化shema、sql語句+索引;
  • 能夠考慮加緩存,memcached, redis,或者JVM本地緩存;
  • 主從複製,讀寫分離;
  • 分庫分表;

25. 什麼是數據庫鏈接池?爲何須要數據庫鏈接池呢?

鏈接池基本原理: 數據庫鏈接池原理:在內部對象池中,維護必定數量的數據庫鏈接,並對外暴露數據庫鏈接的獲取和返回方法。

應用程序和數據庫創建鏈接的過程:

  • 經過TCP協議的三次握手和數據庫服務器創建鏈接
  • 發送數據庫用戶帳號密碼,等待數據庫驗證用戶身份
  • 完成身份驗證後,系統能夠提交SQL語句到數據庫執行
  • 把鏈接關閉,TCP四次揮手告別。

數據庫鏈接池好處:

  • 資源重用 (鏈接複用)
  • 更快的系統響應速度
  • 新的資源分配手段
  • 統一的鏈接管理,避免數據庫鏈接泄漏

有興趣的夥伴能夠看看我這篇文章哈~ 數據庫鏈接池內存泄漏問題的分析和解決方案

26. 一條SQL語句在MySQL中如何執行的?

先看一下Mysql的邏輯架構圖吧~

查詢語句:

  • 先檢查該語句是否有權限
  • 若是沒有權限,直接返回錯誤信息
  • 若是有權限,在 MySQL8.0 版本之前,會先查詢緩存。
  • 若是沒有緩存,分析器進行詞法分析,提取 sql 語句select等的關鍵元素。而後判斷sql 語句是否有語法錯誤,好比關鍵詞是否正確等等。
  • 優化器進行肯定執行方案
  • 進行權限校驗,若是沒有權限就直接返回錯誤信息,若是有權限就會調用數據庫引擎接口,返回執行結果。

這篇文章很是不錯,你們去看一下吧: 一條SQL語句在MySQL中如何執行的

27. InnoDB引擎中的索引策略,瞭解過嗎?

  • 覆蓋索引
  • 最左前綴原則
  • 索引下推

索引下推優化是 MySQL 5.6 引入的, 能夠在索引遍歷過程當中,對索引中包含的字段先作判斷,直接過濾掉不知足條件的記錄,減小回表次數。

這篇文章很是不錯,你們去看一下吧: 聊一聊 InnoDB 引擎中的這些索引策略

28. 數據庫存儲日期格式時,如何考慮時區轉換問題?

  • datetime類型適合用來記錄數據的原始的建立時間,修改記錄中其餘字段的值,datetime字段的值不會改變,除非手動修改它。
  • timestamp類型適合用來記錄數據的最後修改時間,只要修改了記錄中其餘字段的值,timestamp字段的值都會被自動更新。

如何考慮時區轉換問題/看一下這個吧: 數據庫存儲日期格式時,如何考慮時區轉換問題?

29. 一條sql執行過長的時間,你如何優化,從哪些方面入手?

  • 查看是否涉及多表和子查詢,優化Sql結構,如去除冗餘字段,是否可拆表等
  • 優化索引結構,看是否能夠適當添加索引
  • 數量大的表,能夠考慮進行分離/分表(如交易流水錶)
  • 數據庫主從分離,讀寫分離
  • explain分析sql語句,查看執行計劃,優化sql
  • 查看mysql執行日誌,分析是否有其餘方面的問題

30. MYSQL數據庫服務器性能分析的方法命令有哪些?

  • Show status, 一些值得監控的變量值:
  • Bytes_received和Bytes_sent 和服務器之間來往的流量。
  • Com_*服務器正在執行的命令。
  • Created_*在查詢執行期限間建立的臨時表和文件。
  • Handler_*存儲引擎操做。
  • Select_*不一樣類型的聯接執行計劃。
  • Sort_*幾種排序信息。
  • Show profiles 是MySql用來分析當前會話SQL語句執行的資源消耗狀況

31. Blob和text有什麼區別?

  • Blob用於存儲二進制數據,而Text用於存儲大字符串。
  • Blob值被視爲二進制字符串(字節字符串),它們沒有字符集,而且排序和比較基於列值中的字節的數值。
  • text值被視爲非二進制字符串(字符字符串)。它們有一個字符集,並根據字符集的排序規則對值進行排序和比較。

32. mysql裏記錄貨幣用什麼字段類型比較好?

  • 貨幣在數據庫中MySQL經常使用Decimal和Numric類型表示,這兩種類型被MySQL實現爲一樣的類型。他們被用於保存與金錢有關的數據。
  • salary DECIMAL(9,2),9(precision)表明將被用於存儲值的總的小數位數,而2(scale)表明將被用於存儲小數點後的位數。存儲在salary列中的值的範圍是從-9999999.99到9999999.99。
  • DECIMAL和NUMERIC值做爲字符串存儲,而不是做爲二進制浮點數,以便保存那些值的小數精度。

33. Mysql中有哪幾種鎖,列舉一下?

若是按鎖粒度劃分,有如下3種:

  • 表鎖: 開銷小,加鎖快;鎖定力度大,發生鎖衝突機率高,併發度最低;不會出現死鎖。
  • 行鎖: 開銷大,加鎖慢;會出現死鎖;鎖定粒度小,發生鎖衝突的機率低,併發度高。
  • 頁鎖: 開銷和加鎖速度介於表鎖和行鎖之間;會出現死鎖;鎖定粒度介於表鎖和行鎖之間,併發度通常

有興趣的小夥伴能夠看我這篇文章,有介紹到各類鎖哈:

後端程序員必備:mysql數據庫相關流程圖/原理圖

34. Hash索引和B+樹區別是什麼?你在設計索引是怎麼抉擇的?

  • B+樹能夠進行範圍查詢,Hash索引不能。
  • B+樹支持聯合索引的最左側原則,Hash索引不支持。
  • B+樹支持order by排序,Hash索引不支持。
  • Hash索引在等值查詢上比B+樹效率更高。
  • B+樹使用like 進行模糊查詢的時候,like後面(好比%開頭)的話能夠起到優化的做用,Hash索引根本沒法進行模糊查詢。

35. mysql 的內鏈接、左鏈接、右鏈接有什麼區別?

  • Inner join 內鏈接,在兩張表進行鏈接查詢時,只保留兩張表中徹底匹配的結果集
  • left join 在兩張表進行鏈接查詢時,會返回左表全部的行,即便在右表中沒有匹配的記錄。
  • right join 在兩張表進行鏈接查詢時,會返回右表全部的行,即便在左表中沒有匹配的記錄。

36. 說說MySQL 的基礎架構圖

Mysql邏輯架構圖主要分三層:

  • 第一層負責鏈接處理,受權認證,安全等等
  • 第二層負責編譯並優化SQL
  • 第三層是存儲引擎。

37. 什麼是內鏈接、外鏈接、交叉鏈接、笛卡爾積呢?

  • 內鏈接(inner join):取得兩張表中知足存在鏈接匹配關係的記錄。
  • 外鏈接(outer join):取得兩張表中知足存在鏈接匹配關係的記錄,以及某張表(或兩張表)中不知足匹配關係的記錄。
  • 交叉鏈接(cross join):顯示兩張表全部記錄一一對應,沒有匹配關係進行篩選,也被稱爲:笛卡爾積。

38. 說一下數據庫的三大範式

  • 第一範式:數據表中的每一列(每一個字段)都不能夠再拆分。
  • 第二範式:在第一範式的基礎上,分主鍵列徹底依賴於主鍵,而不能是依賴於主鍵的一部分。
  • 第三範式:在知足第二範式的基礎上,表中的非主鍵只依賴於主鍵,而不依賴於其餘非主鍵。

39. mysql有關權限的表有哪幾個呢?

MySQL服務器經過權限表來控制用戶對數據庫的訪問,權限表存放在mysql數據庫裏,由mysql_install_db腳本初始化。這些權限表分別user,db,table_priv,columns_priv和host。

  • user權限表:記錄容許鏈接到服務器的用戶賬號信息,裏面的權限是全局級的。
  • db權限表:記錄各個賬號在各個數據庫上的操做權限。
  • table_priv權限表:記錄數據表級的操做權限。
  • columns_priv權限表:記錄數據列級的操做權限。
  • host權限表:配合db權限表對給定主機上數據庫級操做權限做更細緻的控制。這個權限表不受GRANT和REVOKE語句的影響。

40. Mysql的binlog有幾種錄入格式?分別有什麼區別?

有三種格式哈,statement,row和mixed。

  • statement,每一條會修改數據的sql都會記錄在binlog中。不須要記錄每一行的變化,減小了binlog日誌量,節約了IO,提升性能。因爲sql的執行是有上下文的,所以在保存的時候須要保存相關的信息,同時還有一些使用了函數之類的語句沒法被記錄複製。
  • row,不記錄sql語句上下文相關信息,僅保存哪條記錄被修改。記錄單元爲每一行的改動,基本是能夠所有記下來可是因爲不少操做,會致使大量行的改動(好比alter table),所以這種模式的文件保存的信息太多,日誌量太大。
  • mixed,一種折中的方案,普通操做使用statement記錄,當沒法使用statement的時候使用row。

41. InnoDB引擎的4大特性,瞭解過嗎

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

42. 索引有哪些優缺點?

優勢:

  • 惟一索引能夠保證數據庫表中每一行的數據的惟一性
  • 索引能夠加快數據查詢速度,減小查詢時間

缺點:

  • 建立索引和維護索引要耗費時間
  • 索引須要佔物理空間,除了數據表佔用數據空間以外,每個索引還要佔用必定的物理空間
  • 以表中的數據進行增、刪、改的時候,索引也要動態的維護。

43. 索引有哪幾種類型?

  • 主鍵索引: 數據列不容許重複,不容許爲NULL,一個表只能有一個主鍵。
  • 惟一索引: 數據列不容許重複,容許爲NULL值,一個表容許多個列建立惟一索引。
  • 普通索引: 基本的索引類型,沒有惟一性的限制,容許爲NULL值。
  • 全文索引:是目前搜索引擎使用的一種關鍵技術,對文本的內容進行分詞、搜索。
  • 覆蓋索引:查詢列要被所建的索引覆蓋,沒必要讀取數據行
  • 組合索引:多列值組成一個索引,用於組合搜索,效率大於索引合併

44. 建立索引有什麼原則呢?

  • 最左前綴匹配原則
  • 頻繁做爲查詢條件的字段纔去建立索引
  • 頻繁更新的字段不適合建立索引
  • 索引列不能參與計算,不能有函數操做
  • 優先考慮擴展索引,而不是新建索引,避免沒必要要的索引
  • 在order by或者group by子句中,建立索引須要注意順序
  • 區分度低的數據列不適合作索引列(如性別)
  • 定義有外鍵的數據列必定要創建索引。
  • 對於定義爲text、image數據類型的列不要創建索引。
  • 刪除再也不使用或者不多使用的索引

45. 建立索引的三種方式

  • 在執行CREATE TABLE時建立索引
CREATE TABLE `employee` (
  `id` int(11) NOT NULL,
  `name` varchar(255) DEFAULT NULL,
  `age` int(11) DEFAULT NULL,
  `date` datetime DEFAULT NULL,
  `sex` int(1) DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `idx_name` (`name`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
複製代碼
  • 使用ALTER TABLE命令添加索引
ALTER TABLE table_name ADD INDEX index_name (column);
複製代碼
  • 使用CREATE INDEX命令建立
CREATE INDEX index_name ON table_name (column);
複製代碼

46. 百萬級別或以上的數據,你是如何刪除的?

  • 咱們想要刪除百萬數據的時候能夠先刪除索引
  • 而後批量刪除其中無用數據
  • 刪除完成後從新建立索引。

47. 什麼是最左前綴原則?什麼是最左匹配原則?

  • 最左前綴原則,就是最左優先,在建立多列索引時,要根據業務需求,where子句中使用最頻繁的一列放在最左邊。
  • 當咱們建立一個組合索引的時候,如(k1,k2,k3),至關於建立了(k1)、(k1,k2)和(k1,k2,k3)三個索引,這就是最左匹配原則。。

48. B樹和B+樹的區別,數據庫爲何使用B+樹而不是B樹?

  • 在B樹中,鍵和值即存放在內部節點又存放在葉子節點;在B+樹中,內部節點只存鍵,葉子節點則同時存放鍵和值。
  • B+樹的葉子節點有一條鏈相連,而B樹的葉子節點各自獨立的。
  • B+樹索引的全部數據均存儲在葉子節點,並且數據是按照順序排列的,鏈表連着的。那麼B+樹使得範圍查找,排序查找,分組查找以及去重查找變得異常簡單。.
  • B+樹非葉子節點上是不存儲數據的,僅存儲鍵值,而B樹節點中不只存儲鍵值,也會存儲數據。innodb中頁的默認大小是16KB,若是不存儲數據,那麼就會存儲更多的鍵值,相應的樹的階數(節點的子節點樹)就會更大,樹就會更矮更胖,如此一來咱們查找數據進行磁盤的IO次數有會再次減小,數據查詢的效率也會更快.

49. 覆蓋索引、回表等這些,瞭解過嗎?

  • 覆蓋索引: 查詢列要被所建的索引覆蓋,沒必要從數據表中讀取,換句話說查詢列要被所使用的索引覆蓋。
  • 回表:二級索引沒法直接查詢全部列的數據,因此經過二級索引查詢到聚簇索引後,再查詢到想要的數據,這種經過二級索引查詢出來的過程,就叫作回表。

網上這篇文章講得很清晰: mysql覆蓋索引與回表

50. B+樹在知足聚簇索引和覆蓋索引的時候不須要回表查詢數據?

  • 在B+樹的索引中,葉子節點可能存儲了當前的key值,也可能存儲了當前的key值以及整行的數據,這就是聚簇索引和非聚簇索引。 在InnoDB中,只有主鍵索引是聚簇索引,若是沒有主鍵,則挑選一個惟一鍵創建聚簇索引。若是沒有惟一鍵,則隱式的生成一個鍵來創建聚簇索引。
  • 當查詢使用聚簇索引時,在對應的葉子節點,能夠獲取到整行數據,所以不用再次進行回表查詢。

51. 什麼時候使用聚簇索引與非聚簇索引

52. 非聚簇索引必定會回表查詢嗎?

不必定,若是查詢語句的字段所有命中了索引,那麼就沒必要再進行回表查詢(哈哈,覆蓋索引就是這麼回事)。

舉個簡單的例子,假設咱們在學生表的上創建了索引,那麼當進行select age from student where age < 20的查詢時,在索引的葉子節點上,已經包含了age信息,不會再次進行回表查詢。

53. 組合索引是什麼?爲何須要注意組合索引中的順序?

組合索引,用戶能夠在多個列上創建索引,這種索引叫作組合索引。

由於InnoDB引擎中的索引策略的最左原則,因此須要注意組合索引中的順序。

54. 什麼是數據庫事務?

數據庫事務(簡稱:事務),是數據庫管理系統執行過程當中的一個邏輯單位,由一個有限的數據庫操做序列構成,這些操做要麼所有執行,要麼所有不執行,是一個不可分割的工做單位。

55. 隔離級別與鎖的關係

回答這個問題,能夠先闡述四種隔離級別,再闡述它們的實現原理。隔離級別就是依賴鎖和MVCC實現的。

能夠看我這篇文章哈:一文完全讀懂MySQL事務的四大隔離級別

56. 按照鎖的粒度分,數據庫鎖有哪些呢?鎖機制與InnoDB鎖算法

  • 按鎖粒度分有:表鎖,頁鎖,行鎖
  • 按鎖機制分有:樂觀鎖,悲觀鎖

57. 從鎖的類別角度講,MySQL都有哪些鎖呢?

從鎖的類別上來說,有共享鎖和排他鎖。

  • 共享鎖: 又叫作讀鎖。當用戶要進行數據的讀取時,對數據加上共享鎖。共享鎖能夠同時加上多個。
  • 排他鎖: 又叫作寫鎖。當用戶要進行數據的寫入時,對數據加上排他鎖。排他鎖只能夠加一個,他和其餘的排他鎖,共享鎖都相斥。

鎖兼容性以下:

58. MySQL中InnoDB引擎的行鎖是怎麼實現的?

基於索引來完成行鎖的。

select * from t where id = 666 for update;
複製代碼

for update 能夠根據條件來完成行鎖鎖定,而且 id 是有索引鍵的列,若是 id 不是索引鍵那麼InnoDB將實行表鎖。

59. 什麼是死鎖?怎麼解決?

死鎖是指兩個或多個事務在同一資源上相互佔用,並請求鎖定對方的資源,從而致使惡性循環的現象。看圖形象一點,以下:

死鎖有四個必要條件:互斥條件,請求和保持條件,環路等待條件,不剝奪條件。

解決死鎖思路,通常就是切斷環路,儘可能避免併發造成環路。

  • 若是不一樣程序會併發存取多個表,儘可能約定以相同的順序訪問表,能夠大大下降死鎖機會。
  • 在同一個事務中,儘量作到一次鎖定所須要的全部資源,減小死鎖產生機率;
  • 對於很是容易產生死鎖的業務部分,能夠嘗試使用升級鎖定顆粒度,經過表級鎖定來減小死鎖產生的機率;
  • 若是業務處理很差能夠用分佈式事務鎖或者使用樂觀鎖
  • 死鎖與索引密不可分,解決索引問題,須要合理優化你的索引,

有興趣的朋友,能夠看個人這篇死鎖分析: 手把手教你分析Mysql死鎖問題

60. 爲何要使用視圖?什麼是視圖?

爲何要使用視圖?

爲了提升複雜SQL語句的複用性和表操做的安全性,MySQL數據庫管理系統提供了視圖特性。

什麼是視圖?

視圖是一個虛擬的表,是一個表中的數據通過某種篩選後的顯示方式,視圖由一個預約義的查詢select語句組成。

61. 視圖有哪些特色?哪些使用場景?

視圖特色:

  • 視圖的列能夠來自不一樣的表,是表的抽象和在邏輯意義上創建的新關係。
  • 視圖是由基本表(實表)產生的表(虛表)。
  • 視圖的創建和刪除不影響基本表。
  • 對視圖內容的更新(添加,刪除和修改)直接影響基本表。
  • 當視圖來自多個基本表時,不容許添加和刪除數據。

視圖用途: 簡化sql查詢,提升開發效率,兼容老的表結構。

視圖的常見使用場景:

  • 重用SQL語句;
  • 簡化複雜的SQL操做。
  • 使用表的組成部分而不是整個表;
  • 保護數據
  • 更改數據格式和表示。視圖可返回與底層表的表示和格式不一樣的數據。

62. 視圖的優勢,缺點,講一下?

  • 查詢簡單化。視圖能簡化用戶的操做
  • 數據安全性。視圖使用戶能以多種角度看待同一數據,可以對機密數據提供安全保護
  • 邏輯數據獨立性。視圖對重構數據庫提供了必定程度的邏輯獨立性

63. count(1)、count(*) 與 count(列名) 的區別?

  • count(*)包括了全部的列,至關於行數,在統計結果的時候,不會忽略列值爲NULL
  • count(1)包括了忽略全部列,用1表明代碼行,在統計結果的時候,不會忽略列值爲NULL
  • count(列名)只包括列名那一列,在統計結果的時候,會忽略列值爲空(這裏的空不是隻空字符串或者0,而是表示null)的計數,即某個字段值爲NULL時,不統計。

64. 什麼是遊標?

遊標提供了一種對從表中檢索出的數據進行操做的靈活手段,就本質而言,遊標其實是一種能從包括多條數據記錄的結果集中每次提取一條記錄的機制。

65. 什麼是存儲過程?有哪些優缺點?

存儲過程,就是一些編譯好了的SQL語句,這些SQL語句代碼像一個方法同樣實現一些功能(對單表或多表的增刪改查),而後給這些代碼塊取一個名字,在用到這個功能的時候調用便可。

優勢:

  • 存儲過程是一個預編譯的代碼塊,執行效率比較高
  • 存儲過程在服務器端運行,減小客戶端的壓力
  • 容許模塊化程序設計,只須要建立一次過程,之後在程序中就能夠調用該過程任意次,相似方法的複用
  • 一個存儲過程替代大量T_SQL語句 ,能夠下降網絡通訊量,提升通訊速率
  • 能夠必定程度上確保數據安全

缺點:

  • 調試麻煩
  • 可移植性不靈活
  • 從新編譯問題

66. 什麼是觸發器?觸發器的使用場景有哪些?

觸發器,指一段代碼,當觸發某個事件時,自動執行這些代碼。

使用場景:

  • 能夠經過數據庫中的相關表實現級聯更改。
  • 實時監控某張表中的某個字段的更改而須要作出相應的處理。
  • 例如能夠生成某些業務的編號。
  • 注意不要濫用,不然會形成數據庫及應用程序的維護困難。

67. MySQL中都有哪些觸發器?

MySQL 數據庫中有六種觸發器:

  • Before Insert
  • After Insert
  • Before Update
  • After Update
  • Before Delete
  • After Delete

68. 超鍵、候選鍵、主鍵、外鍵分別是什麼?

  • 超鍵:在關係模式中,能惟一知標識元組的屬性集稱爲超鍵。
  • 候選鍵:是最小超鍵,即沒有冗餘元素的超鍵。
  • 主鍵:數據庫表中對儲存數據對象予以惟一和完整標識的數據列或屬性的組合。一個數據列只能有一個主鍵,且主鍵的取值不能缺失,即不能爲空值(Null)。
  • 外鍵:在一個表中存在的另外一個表的主鍵稱此表的外鍵。。

69. SQL 約束有哪幾種呢?

  • NOT NULL: 約束字段的內容必定不能爲NULL。
  • UNIQUE: 約束字段惟一性,一個表容許有多個 Unique 約束。
  • PRIMARY KEY: 約束字段惟一,不可重複,一個表只容許存在一個。
  • FOREIGN KEY: 用於預防破壞表之間鏈接的動做,也能防止非法數據插入外鍵。
  • CHECK: 用於控制字段的值範圍。

70. 談談六種關聯查詢,使用場景。

  • 交叉鏈接
  • 內鏈接
  • 外鏈接
  • 聯合查詢
  • 全鏈接
  • 交叉鏈接

71. varchar(50)中50的涵義

  • 字段最多存放 50 個字符
  • 如 varchar(50) 和 varchar(200) 存儲 "jay" 字符串所佔空間是同樣的,後者在排序時會消耗更多內存

72. mysql中int(20)和char(20)以及varchar(20)的區別

  • int(20) 表示字段是int類型,顯示長度是 20
  • char(20)表示字段是固定長度字符串,長度爲 20
  • varchar(20) 表示字段是可變長度字符串,長度爲 20

73. drop、delete與truncate的區別

delete truncate drop
類型 DML DDL DDL
回滾 可回滾 不可回滾 不可回滾
刪除內容 表結構還在,刪除表的所有或者一部分數據行 表結構還在,刪除表中的全部數據 從數據庫中刪除表,全部的數據行,索引和權限也會被刪除
刪除速度 刪除速度慢,逐行刪除 刪除速度快 刪除速度最快

74. UNION與UNION ALL的區別?

  • Union:對兩個結果集進行並集操做,不包括重複行,同時進行默認規則的排序;
  • Union All:對兩個結果集進行並集操做,包括重複行,不進行排序;
  • UNION的效率高於 UNION ALL

75. SQL的生命週期?

  • 服務器與數據庫創建鏈接
  • 數據庫進程拿到請求sql
  • 解析並生成執行計劃,執行
  • 讀取數據到內存,並進行邏輯處理
  • 經過步驟一的鏈接,發送結果到客戶端
  • 關掉鏈接,釋放資源

76. 一條Sql的執行順序?

77. 列值爲NULL時,查詢是否會用到索引?

列值爲NULL也是能夠走索引的

計劃對列進行索引,應儘可能避免把它設置爲可空,由於這會讓 MySQL 難以優化引用了可空列的查詢,同時增長了引擎的複雜度

78. 關心過業務系統裏面的sql耗時嗎?統計過慢查詢嗎?對慢查詢都怎麼優化過?

  • 咱們平時寫Sql時,都要養成用explain分析的習慣。
  • 慢查詢的統計,運維會按期統計給咱們

優化慢查詢:

  • 分析語句,是否加載了沒必要要的字段/數據。
  • 分析SQl執行句話,是否命中索引等。
  • 若是SQL很複雜,優化SQL結構
  • 若是表數據量太大,考慮分表

能夠看我這篇文章哈: 後端程序員必備:書寫高質量SQL的30條建議

79. 主鍵使用自增ID仍是UUID,爲何?

若是是單機的話,選擇自增ID;若是是分佈式系統,優先考慮UUID吧,但仍是最好本身公司有一套分佈式惟一ID生產方案吧。

  • 自增ID:數據存儲空間小,查詢效率高。可是若是數據量過大,會超出自增加的值範圍,多庫合併,也有可能有問題。
  • uuid:適合大量數據的插入和更新操做,可是它無序的,插入數據效率慢,佔用空間大。

80. mysql自增主鍵用完了怎麼辦?

自增主鍵通常用int類型,通常達不到最大值,能夠考慮提早分庫分表的。

81. 字段爲何要求定義爲not null?

null值會佔用更多的字節,而且null有不少坑的。

82. 若是要存儲用戶的密碼散列,應該使用什麼字段進行存儲?

密碼散列,鹽,用戶身份證號等固定長度的字符串,應該使用char而不是varchar來存儲,這樣能夠節省空間且提升檢索效率。

83. Mysql驅動程序是什麼?

這個jar包: mysql-connector-java-5.1.18.jar

Mysql驅動程序主要幫助編程語言與 MySQL服務端進行通訊,如鏈接、傳輸數據、關閉等。

84. 如何優化長難的查詢語句?有實戰過嗎?

  • 將一個大的查詢分爲多個小的相同的查詢
  • 減小冗餘記錄的查詢。
  • 一個複雜查詢能夠考慮拆成多個簡單查詢
  • 分解關聯查詢,讓緩存的效率更高。

85. 優化特定類型的查詢語句

平時積累吧:

  • 好比使用select 具體字段代替 select *
  • 使用count(*) 而不是count(列名)
  • 在不影響業務的狀況,使用緩存
  • explain 分析你的SQL

能夠看我這篇文章哈: 後端程序員必備:書寫高質量SQL的30條建議

86. MySQL數據庫cpu飆升的話,要怎麼處理呢?

排查過程:

  • 使用top 命令觀察,肯定是mysqld致使仍是其餘緣由。
  • 若是是mysqld致使的,show processlist,查看session狀況,肯定是否是有消耗資源的sql在運行。
  • 找出消耗高的 sql,看看執行計劃是否準確, 索引是否缺失,數據量是否太大。

處理:

  • kill 掉這些線程(同時觀察 cpu 使用率是否降低),
  • 進行相應的調整(好比說加索引、改 sql、改內存參數)
  • 從新跑這些 SQL。

其餘狀況:

也有多是每一個 sql 消耗資源並很少,可是忽然之間,有大量的 session 連進來致使 cpu 飆升,這種狀況就須要跟應用一塊兒來分析爲什麼鏈接數會激增,再作出相應的調整,好比說限制鏈接數等

87. 讀寫分離常見方案?

  • 應用程序根據業務邏輯來判斷,增刪改等寫操做命令發給主庫,查詢命令發給備庫。
  • 利用中間件來作代理,負責對數據庫的請求識別出讀仍是寫,並分發到不一樣的數據庫中。(如:amoeba,mysql-proxy)

88. MySQL的複製原理以及流程

主從複製原理,簡言之,就三步曲,以下:

  • 主數據庫有個bin-log二進制文件,紀錄了全部增刪改Sql語句。(binlog線程)
  • 從數據庫把主數據庫的bin-log文件的sql語句複製過來。(io線程)
  • 從數據庫的relay-log重作日誌文件中再執行一次這些sql語句。(Sql執行線程)

以下圖所示:

上圖主從複製分了五個步驟進行:

步驟一:主庫的更新事件(update、insert、delete)被寫到binlog

步驟二:從庫發起鏈接,鏈接到主庫。

步驟三:此時主庫建立一個binlog dump thread,把binlog的內容發送到從庫。

步驟四:從庫啓動以後,建立一個I/O線程,讀取主庫傳過來的binlog內容並寫入到relay log

步驟五:還會建立一個SQL線程,從relay log裏面讀取內容,從Exec_Master_Log_Pos位置開始執行讀取到的更新事件,將更新內容寫入到slave的db

89. MySQL中DATETIME和TIMESTAMP的區別

存儲精度都爲秒

區別:

  • DATETIME 的日期範圍是 1001——9999 年;TIMESTAMP 的時間範圍是 1970——2038 年
  • DATETIME 存儲時間與時區無關;TIMESTAMP 存儲時間與時區有關,顯示的值也依賴於時區
  • DATETIME 的存儲空間爲 8 字節;TIMESTAMP 的存儲空間爲 4 字節
  • DATETIME 的默認值爲 null;TIMESTAMP 的字段默認不爲空(not null),默認值爲當前時間(CURRENT_TIMESTAMP)

90. Innodb的事務實現原理?

  • 原子性:是使用 undo log來實現的,若是事務執行過程當中出錯或者用戶執行了rollback,系統經過undo log日誌返回事務開始的狀態。
  • 持久性:使用 redo log來實現,只要redo log日誌持久化了,當系統崩潰,便可經過redo log把數據恢復。
  • 隔離性:經過鎖以及MVCC,使事務相互隔離開。
  • 一致性:經過回滾、恢復,以及併發狀況下的隔離性,從而實現一致性。

91. 談談MySQL的Explain

Explain 執行計劃包含字段信息以下:分別是 id、select_type、table、partitions、type、possible_keys、key、key_len、ref、rows、filtered、Extra 等12個字段。

咱們重點關注的是type,它的屬性排序以下:

system  > const > eq_ref > ref  > ref_or_null >
index_merge > unique_subquery > index_subquery > 
range > index > ALL
複製代碼

推薦你們看這篇文章哈: 面試官:不會看 Explain執行計劃,簡歷敢寫 SQL 優化?

92. Innodb的事務與日誌的實現方式

有多少種日誌

innodb兩種日誌redo和undo。

日誌的存放形式

  • redo:在頁修改的時候,先寫到 redo log buffer 裏面, 而後寫到 redo log 的文件系統緩存裏面(fwrite),而後再同步到磁盤文件( fsync)。
  • Undo:在 MySQL5.5 以前, undo 只能存放在 ibdata文件裏面, 5.6 以後,能夠經過設置 innodb_undo_tablespaces 參數把 undo log 存放在 ibdata以外。

事務是如何經過日誌來實現的

  • 由於事務在修改頁時,要先記 undo,在記 undo 以前要記 undo 的 redo, 而後修改數據頁,再記數據頁修改的 redo。 Redo(裏面包括 undo 的修改) 必定要比數據頁先持久化到磁盤。
  • 當事務須要回滾時,由於有 undo,能夠把數據頁回滾到前鏡像的 狀態,崩潰恢復時,若是 redo log 中事務沒有對應的 commit 記錄,那麼須要用 undo把該事務的修改回滾到事務開始以前。
  • 若是有 commit 記錄,就用 redo 前滾到該事務完成時並提交掉。

93. MySQL中TEXT數據類型的最大長度

  • TINYTEXT:256 bytes
  • TEXT:65,535 bytes(64kb)
  • MEDIUMTEXT:16,777,215 bytes(16MB)
  • LONGTEXT:4,294,967,295 bytes(4GB)

94. 500臺db,在最快時間以內重啓。

  • 可使用批量 ssh 工具 pssh 來對須要重啓的機器執行重啓命令。
  • 也可使用 salt(前提是客戶端有安裝 salt)或者 ansible( ansible 只須要 ssh 免登通了就行)等多線程工具同時操做多臺服務

95. 你是如何監控大家的數據庫的?大家的慢日誌都是怎麼查詢的?

監控的工具備不少,例如zabbix,lepus,我這裏用的是lepus

96. 你是否作過主從一致性校驗,若是有,怎麼作的,若是沒有,你打算怎麼作?

主從一致性校驗有多種工具 例如checksum、mysqldiff、pt-table-checksum等

97. 大家數據庫是否支持emoji表情存儲,若是不支持,如何操做?

更換字符集utf8-->utf8mb4

98. MySQL如何獲取當前日期?

SELECT CURRENT_DATE();

99. 一個6億的表a,一個3億的表b,經過外間tid關聯,你如何最快的查詢出知足條件的第50000到第50200中的這200條數據記錄。

一、若是A表TID是自增加,而且是連續的,B表的ID爲索引 select * from a,b where a.tid = b.id and a.tid>500000 limit 200;

二、若是A表的TID不是連續的,那麼就須要使用覆蓋索引.TID要麼是主鍵,要麼是輔助索引,B表ID也須要有索引。 select * from b , (select tid from a limit 50000,200) a where b.id = a .tid;

100. Mysql一條SQL加鎖分析

一條SQL加鎖,能夠分9種狀況進行:

  • 組合一:id列是主鍵,RC隔離級別
  • 組合二:id列是二級惟一索引,RC隔離級別
  • 組合三:id列是二級非惟一索引,RC隔離級別
  • 組合四:id列上沒有索引,RC隔離級別
  • 組合五:id列是主鍵,RR隔離級別
  • 組合六:id列是二級惟一索引,RR隔離級別
  • 組合七:id列是二級非惟一索引,RR隔離級別
  • 組合八:id列上沒有索引,RR隔離級別
  • 組合九:Serializable隔離級別

公衆號

  • 歡迎關注我我的公衆號,交個朋友,一塊兒學習哈~
  • 若是答案整理有錯,歡迎指出哈,感激涕零~
相關文章
相關標籤/搜索