自己實戰整理面試題--Mysql(帶答案,不斷更新)
mysql目前用的版本?
5.1.21;目前最高5.7.*
left join,right join,inner join?
left join(左連線) 返回包括左表中的所有記錄和右表中連線欄位相等的記錄
right join(右連線) 返回包括右表中的所有記錄和左表中連線欄位相等的記錄
左連線和右連線很像只是順序問題。
inner join(等值連線、內連線) 只返回兩個表中連線欄位相等的行
MySQL 分頁查詢語句
select * from table limit (start-1)*limit,limit; 其中start是頁碼,limit是每頁顯示的條數
髒讀、幻讀、不可重複讀?
https://blog.csdn.net/w372426096/article/details/80798062
資料庫的幾大正規化?
第一正規化----資料庫中的表(所有欄位值)都是不可分割的原子資料項。
第二正規化----資料庫表中的每一列都和主鍵相關,而不能只和主鍵的某一部分相關。也就是說 一個表中只能只能包含一個,不能把多種資料儲存在同一個表中。
第三正規化----資料庫表中每一列資料都和主鍵直接相關,不能間接相關。
資料庫常見的命令?
https://www.cnblogs.com/zhouzetian/p/6429181.html
注意truncat,drop(DDL),delete(操作語句)區別
DDL、DML、DCL分別指什麼?
一、DDL :資料定義語言,用於定義和管理 SQL 資料庫中的所有物件的語言
1.CREATE - to create objects in the database 建立
2.ALTER - alters the structure of the database 修改
3.DROP - delete objects from the database 刪除
4.TRUNCATE - remove all records from a table, including all spaces allocated for the records are removed
Truncate table 表名 速度快,而且效率高,因為:
TRUNCATE TABLE 在功能上與不帶 WHERE 子句的 DELETE 語句相同:二者均刪除表中的全部行。但 TRUNCATE TABLE 比 DELETE 速度快,且使用的系統和事務日誌資源少。
DELETE 語句每次刪除一行,並在事務日誌中為所刪除的每行記錄一項。TRUNCATE TABLE 通過釋放儲存表資料所用的資料頁來刪除資料,並且只在事務日誌中記錄頁的釋放。
TRUNCATE TABLE 刪除表中的所有行,但表結構及其列、約束、索引等保持不變。新行標識所用的計數值重置為該列的種子。如果想保留標識計數值
對於由 FOREIGN KEY 約束引用的表,不能使用 TRUNCATE TABLE,而應使用不帶 WHERE 子句的 DELETE 語句。由於 TRUNCATE TABLE 不記錄在日誌中,所以它不能啟用觸發器。
TRUNCATE TABLE 不能用於參與了索引檢視的表。
5.COMMENT - add comments to the data dictionary 註釋
6.GRANT - gives user's access privileges to database 授權
7.REVOKE - withdraw access privileges given with the GRANT command 收回已經授予的許可權
二、DML:資料操作語言,SQL中處理資料等操作統稱為資料操縱語言
1.SELECT - retrieve data from the a database 查詢
2.INSERT - insert data into a table 新增
3.UPDATE - updates existing data within a table 更新
4.DELETE - deletes all records from a table, the space for the records remain 刪除
5.CALL - call a PL/SQL or Java subprogram
6.EXPLAIN PLAN - explain access path to data
7.LOCK TABLE - control concurrency 鎖,用於控制併發
三、DCL:資料控制語言,用來授予或回收訪問資料庫的某種特權,並控制資料庫操縱事務發生的時間及效果,對資料庫實行監視等
1.COMMIT - save work done 提交
2.SAVEPOINT - identify a point in a transaction to which you can later roll back 儲存點
3.ROLLBACK - restore database to original since the last COMMIT 回滾
4.SET TRANSACTION - Change transaction options like what rollback segment to use 設定當前事務的特性,它對後面的事務沒有影響.
SQL的整個解析、執行過程原理、SQL行轉列;
將一個連結串列反轉(用三個指標,但是每次只發轉一個)
sql語句各種條件的執行順序,如select, where, order by, group by
檢視執行計劃
索引
SQL 索引的順序,欄位的順序?
最左原則?
資料庫的索引實現和非主鍵的二級索引?
MySQL 索引使用的注意事項
最重要的索性及底層實現
索引類別(B+樹索引、全文索引、雜湊索引)、索引的原理?
什麼是自適應雜湊索引(AHI)?
為什麼要用 B+tree作為MySQL索引的資料結構?
聚集索引與非聚集索引的區別?
遇到過索引失效的情況沒,什麼時候可能會出現,如何解決?
索引失效的場景
優化:
常見的資料庫優化方案?
第一階段 優化sql和索引
這一步成本最低啊,不需要加什麼中介軟體。你沒經過索引優化和SQL優化。
步驟大概
-
用慢查詢日誌定位執行效率低的
SQL
語句 -
用
explain
分析SQL
的執行計劃 -
確定問題,採取相應的優化措施,建立索引啊,等
第二階段 搭建快取
在優化sql無法解決問題的情況下,才考慮搭建快取。畢竟你使用快取的目的,就是將複雜的、耗時的、不常變的執行結果快取起來,降低資料庫的資源消耗。
這裡需要注意的是:搭建快取後,系統的複雜性增加了。你需要考慮很多問題,比如:
-
快取和資料庫一致性問題?(比如是更快取,還是刪快取),這點可以看我的一篇文章《資料庫和快取雙寫一致性方案解析》。
-
快取擊穿、快取穿透、快取雪崩問題如何解決?是否有做快取預熱的必要。不過我猜,大部分中小公司應該都沒考慮。這點可以看我的另一篇《分散式之redis複習精講》
第三階段 讀寫分離
快取也搞不定的情況下,搞主從複製,上讀寫分離。在應用層,區分讀寫請求。或者利用現成的中介軟體 mycat
或者 altas
等做讀寫分離。
需要注意的是,只要你敢說你用了主從架構,有三個問題,你要準備:
1.主從的好處?
回答:實現資料庫備份,實現資料庫負載均衡,提高資料庫可用性
2.主從的原理?
回答:如圖所示(圖片不是自己畫的,偷懶了)
主庫有一個 logdump
執行緒,將 binlog
傳給從庫
從庫有兩個執行緒,一個I/O執行緒,一個SQL執行緒,I/O執行緒讀取主庫傳過來的 binlog
內容並寫入到 relay log
,SQL執行緒從 relay log
裡面讀取內容,寫入從庫的資料庫。
3.如何解決主從一致性?
回答:這個問題,我不建議在資料庫層面解決該問題。根據 CAP 定理,主從架構本來就是一種高可用架構,是無法滿足一致性的。 哪怕你採用同步複製模式或者半同步複製模式,都是弱一致性,並不是強一致性。所以,推薦還是利用快取,來解決該問題。
步驟如下:
-
自己通過測試,計算主從延遲時間,建議mysql版本為5.7以後,因為mysql自5.7開始,多執行緒複製功能比較完善,一般能保證延遲在1s內。不過話說回來,mysql現在都出到8.x了,還有人用5.x的版本麼。
-
資料庫的寫操作,先寫資料庫,再寫cache,但是有效期很短,就比主從延時的時間稍微長一點。
-
讀請求的時候,先讀快取,快取存在則直接返回。如果快取不存在(這時主從同步已經完成),再讀資料庫。
第四階段 利用分割槽表
說句實在話,你們面試的時候,其實可以略過這個階段。因為很多網際網路公司都不建議用分割槽表,我自己也不太建議用分割槽表,採用這個分割槽表,坑太多。
這裡引用一下其他文章的回答:
什麼是mysql的分割槽表?
回答:所有資料還在一個表中,但物理儲存根據一定的規則放在不同的檔案中。這個是mysql支援的功能,業務程式碼不需要改動,但是sql語句需要改動,sql條件需要帶上分割槽的列。
缺點
-
分割槽鍵設計不太靈活,如果不走分割槽鍵,很容易出現全表鎖
-
在分割槽表使用
ALTER TABLE
…ORDER BY
,只能在每個分割槽內進行orderby
。 -
分割槽表的分割槽鍵建立索引,那麼這個索引也將被分割槽。分割槽鍵沒有全域性索引一說。
-
自己分庫分表,自己掌控業務場景與訪問模式,可控。分割槽表,研發寫了一個sql,都不確定該去哪個分割槽查,不太可控。 …不列舉了,不推薦
第五階段 垂直拆分
上面四個階段都沒搞定,就來垂直拆分了。垂直拆分的複雜度還是比水平拆分小的。將你的表,按模組拆分為不同的小表。大家應該都看過《大型網站架構演變之路》,這種型別的文章或者書籍,基本都有提到這一階段。
如果你有幸能夠在什麼運營商、銀行等公司上班,你會發現他們一個表,幾百個欄位都是很常見的事情。所以,應該要進行拆分,拆分原則一般是如下三點:
-
把不常用的欄位單獨放在一張表。
-
把常用的欄位單獨放一張表
-
經常組合查詢的列放在一張表中(聯合索引)。
第六階段 水平拆分
OK,水平拆分是最麻煩的一個階段,拆分後會有很多的問題,我再強調一次,水平拆分一定是最最最最後的選擇。從某種意義上,我覺得還不如垂直拆分。因為你用垂直拆分,分成不同模組後,發現單模組的壓力過大,你完全可以給該模組單獨做優化,例如提高該模組的機器配置等。如果是水平拆分,拆成兩張表,程式碼需要變動,然後發現兩張表還不行,再變程式碼,再拆成三張表的?水平拆分後,各模組間耦合性太強,成本太大,慎重。
在你的專案中資料庫如何進行優化的?
慢sql優化,快取,讀寫分離,設計表時候垂直拆分,終極水平拆分
SQL 優化的常見方法有哪些?
explain命令?
https://blog.csdn.net/w372426096/article/details/82421378
對於SQL慢查詢的優化?(主要是從查詢語句和資料庫表設計兩個方面來考慮,查詢語句方面可以增加索引,增加查詢篩選的限制條件;資料庫表設計的時候可以拆分表,設計得更細粒度。但是後來才發現面試官想要的就是查詢大量資料的慢查詢問題的優化。)
MySQL遇到的死鎖問題、如何排查與解決?
limit 20000 載入很慢怎麼解決?
select xx from xx where xx and xx order by xx limit xx; 如何優化這個(看explain)
事務:
mysql是如何實現事務的
MySQL 事務特性及特性和隔離級別
資料庫事務ACID(原子性、一致性、隔離性、永續性)?
事務的隔離級別(讀未提交、讀以提交、可重複讀、可序列化讀)?
事務介紹,分散式事物的理解,常見的解決方案有哪些,什麼事兩階段提交、三階段提交;
分散式事務的原理2階段提交,同步\非同步\阻塞\非阻塞;
資料庫事務隔離級別,MySQL預設的隔離級別、Spring如何實現事務、JDBC如何實現事務、巢狀事務實現、分散式事務實現;
引擎
儲存引擎的 InnoDB與MyISAM區別,優缺點,使用場景
mysql的儲存引擎,區別
innodb對一行資料的讀會枷鎖嗎?不枷鎖,讀實際讀的是副本
myisam的優點,和innodb的區別
求表的size,或做資料統計可用什麼儲存引擎
讀多寫少可用什麼引擎
假如要統計多個表應該用什麼引擎
分表分庫
說說分庫與分表設計
分庫與分錶帶來的分散式困境與應對之策(如何解決分散式下的分庫分表,全域性表?)
鎖
MySQL鎖,悲觀鎖、樂觀鎖、排它鎖、共享鎖、表級鎖、行級鎖;
樂觀鎖的業務場景及實現方式;
mysql的行級鎖加在哪個位置
如何選擇合適的分散式主鍵方案
選擇合適的資料儲存方案
分散式
讀寫分離何時強制要讀主庫,讀哪個從庫是通過什麼方式決定的,從庫的同步mysql用的什麼方式
主從複製
MySQL記錄binlog的方式主要包括三種模式?每種模式的優缺點是什麼?
對錶做統計時可直接看schema info資訊,即查看錶的系統資訊
mysql的binlog
bin log主從複製
統計100G的ip檔案中出現ip次數最多的100個ip
不可重複讀會出現在什麼場景?
專案 MySQL 的資料量和併發量有多大?
mvcc,Next-Key Lock