來(lái)自:CSDN,作者:IT邦德
鏈接:https://jeames.blog.csdn.net/article/details/123676215
MySQL在面試中經(jīng)常被問(wèn)到,本文總結了面試中的經(jīng)典問(wèn)題。
第一范式:每個(gè)列都不可以再拆分。
第二范式:在第一范式的基礎上,非主鍵列完全依賴(lài)于主鍵,而不能是依賴(lài)于主鍵的一部分。
第三范式:在第二范式的基礎上,非主鍵列只依賴(lài)于主鍵,不依賴(lài)于其他非主鍵。
在設計數據庫結構的時(shí)候,要盡量遵守三范式,如果不遵守,必須有足夠的理由。
比如性能。事實(shí)上我們經(jīng)常會(huì )為了性能而妥協(xié)數據庫的設計。
MySQL服務(wù)器通過(guò)權限表來(lái)控制用戶(hù)對數據庫的訪(fǎng)問(wèn),權限表存放在mysql數據庫里,由mysql_install_db腳本初始化。
這些權限表分別user,db,table_priv,columns_priv和host。
user權限表:記錄允許連接到服務(wù)器的用戶(hù)賬號信息,里面的權限是全局級的。
db權限表:記錄各個(gè)賬號在各個(gè)數據庫上的操作權限。
table_priv權限表:記錄數據表級的操作權限。
columns_priv權限表:記錄數據列級的操作權限。
host權限表:配合db權限表對給定主機上數據庫級操作權限作更細致的控制。這個(gè)權限表不受GRANT和REVOKE語(yǔ)句的影響。

原子性:事務(wù)是最小的執行單位,不允許分割。
事務(wù)的原子性確保動(dòng)作要么全部完成,要么完全不起作用;
一致性:執行事務(wù)前后,數據保持一致,多個(gè)事務(wù)對同一個(gè)數據讀取的結果是相同的;
隔離性:并發(fā)訪(fǎng)問(wèn)數據庫時(shí),一個(gè)用戶(hù)的事務(wù)不被其他事務(wù)所干擾,
各并發(fā)事務(wù)之間數據庫是獨立的;
持久性:一個(gè)事務(wù)被提交之后。它對數據庫中數據的改變是持久的, 即使數據庫發(fā)生故障也不應該對其有任何影響。
數據定義語(yǔ)言DDL(Data Ddefinition Language)CREATE,DROP,ALTER
主要為以上操作 即對邏輯結構等有操作的,其中包括表結構,視圖和索引。
數據查詢(xún)語(yǔ)言DQL(Data Query Language)SELECT
這個(gè)較為好理解 即查詢(xún)操作,以select關(guān)鍵字。
各種簡(jiǎn)單查詢(xún),連接查詢(xún)等 都屬于DQL。
數據操縱語(yǔ)言DML(Data Manipulation Language)INSERT,UPDATE,DELETE
主要為以上操作 即對數據進(jìn)行操作的,
對應上面所說(shuō)的查詢(xún)操作 DQL與DML共同構建了多數初級程序員常用的增刪改查操作。
而查詢(xún)是較為特殊的一種 被劃分到DQL中。
數據控制功能DCL(Data Control Language)GRANT,REVOKE,COMMIT,ROLLBACK
主要為以上操作 即對數據庫安全性完整性等有操作的,可以簡(jiǎn)單的理解為權限控制等。
分庫分表就是為了 解決由于數據量過(guò)大而導致數據庫性能降低的問(wèn)題, 將原來(lái)獨立的數據庫拆分成若干數據庫組成,將數據大表拆分成若干數據表組成, 使得單一數據庫、單一數據表的數據量變小,從而達到提升數據庫性能的目的。
分庫分表常用的中間件如下:

死鎖是指兩個(gè)或多個(gè)事務(wù)在同一資源上相互占用,并請求鎖定對方的資源,從而導致惡性循環(huán)的現象。
常見(jiàn)的解決死鎖的方法
如果業(yè)務(wù)處理不好可以用分布式事務(wù)鎖或者使用樂(lè )觀(guān)鎖
臟讀(Drity Read):某個(gè)事務(wù)已更新一份數據,另一個(gè)事務(wù)在此時(shí)讀取了同一份數據, 由于某些原因,前一個(gè)RollBack了操作,則后一個(gè)事務(wù)所讀取的數據就會(huì )是不正確的。
不可重復讀(Non-repeatable read):在一個(gè)事務(wù)的兩次查詢(xún)之中數據不一致, 這可能是兩次查詢(xún)過(guò)程中間插入了一個(gè)事務(wù)更新的原有的數據。
幻讀(Phantom Read):在一個(gè)事務(wù)的兩次查詢(xún)中數據筆數不一致, 例如有一個(gè)事務(wù)查詢(xún)了幾列(Row)數據, 而另一個(gè)事務(wù)卻在此時(shí)插入了新的幾列數據,先前的事務(wù)在接下來(lái)的查詢(xún)中, 就會(huì )發(fā)現有幾列數據是它先前所沒(méi)有的。
視圖的特點(diǎn)如下: 視圖的列可以來(lái)自不同的表,是表的抽象和在邏輯意義上建立的新關(guān)系。
視圖是由基本表(實(shí)表)產(chǎn)生的表(虛表)。視圖的建立和刪除不影響基本表。
對視圖內容的更新(添加,刪除和修改)直接影響基本表。
當視圖來(lái)自多個(gè)基本表時(shí),不允許添加和刪除數據。
視圖的操作包括創(chuàng )建視圖,查看視圖,刪除視圖和修改視圖。

推薦使用自增ID,不要使用UUID。
因為在InnoDB存儲引擎中,主鍵索引是作為聚簇索引存在的,也就是說(shuō), 主鍵索引的B+樹(shù)葉子節點(diǎn)上存儲了主鍵索引以及全部的數據(按照順序), 如果主鍵索引是自增ID,那么只需要不斷向后排列即可,如果是UUID, 由于到來(lái)的ID與原來(lái)的大小不確定,會(huì )造成非常多的數據插入,數據移動(dòng),然后導致產(chǎn)生很多的內存碎片,進(jìn)而造成插入性能的下降。
總之,在數據量大一些的情況下,用自增主鍵性能會(huì )好一些。
關(guān)于主鍵是聚簇索引,如果沒(méi)有主鍵,InnoDB會(huì )選擇一個(gè)唯一鍵來(lái)作為聚簇索引,如果沒(méi)有唯一鍵,會(huì )生成一個(gè)隱式的主鍵。
當 cpu 飆升到 100%時(shí),先用操作系統命令 top 命令觀(guān)察是不是 mysqld 占用導致的。
如果不是,找出占用高的進(jìn)程,并進(jìn)行相關(guān)處理。
如果是 mysqld 造成的, show processlist,看看里面跑的 session 情況,是不是有消耗資源的 sql 在運行。找出消耗高的 sql,看看執行計劃是否準確,index 是否缺失,或者實(shí)在是數據量太大造成。
一般來(lái)說(shuō),肯定要 kill 掉這些線(xiàn)程(同時(shí)觀(guān)察 cpu 使用率是否下降), 等進(jìn)行相應的調整(比如說(shuō)加索引、改 sql、改內存參數)之后,再重新跑這些 SQL。
也有可能是每個(gè) sql 消耗資源并不多,但是突然之間,有大量的 session 連進(jìn)來(lái)導致 cpu 飆升, 這種情況就需要跟應用一起來(lái)分析為何連接數會(huì )激增, 再做出相應的調整,比如說(shuō)限制連接數等。
主從復制的作用是:
主數據庫出現問(wèn)題,可以切換到從數據庫??梢赃M(jìn)行數據庫層面的讀寫(xiě)分離??梢栽趶臄祿焐线M(jìn)行日常備份。
數據分布:隨意開(kāi)始或停止復制,并在不同地理位置分布數據備份
負載均衡:降低單個(gè)服務(wù)器的壓力
高可用和故障切換:幫助應用程序避免單點(diǎn)失敗
升級測試:可以用更高版本的MySQL作為從庫
TID(Global Transaction ID,全局事務(wù)ID)是全局事務(wù)標識符, 是一個(gè)已提交事務(wù)的編號,并且是一個(gè)全局唯一的編號。
GTID是從MySQL 5.6版本開(kāi)始在主從復制方面推出的重量級特性。
GTID實(shí)際上是由UUID+TID組成的。其中UUID是一個(gè)MySQL實(shí)例的唯一標識。
GTID代表了該實(shí)例上已經(jīng)提交的事務(wù)數量,并且隨著(zhù)事務(wù)提交單調遞增。
GTID有如下幾點(diǎn)作用:
常用備份工具mysql復制
邏輯備份(mysqldump,mydumper)
物理備份(copy,xtrabackup)
備份工具差異對比:
copy:直接拷貝文件到數據目錄下,可能引起表?yè)p壞或者數據不一致。
xtrabackup對于innodb表是不需要鎖表的,對于myisam表仍然需要鎖表。
視庫的大小來(lái)定,一般來(lái)說(shuō) 100G 內的庫,可以考慮使用 mysqldump 來(lái)做, 因為 mysqldump更加輕巧靈活,備份時(shí)間選在業(yè)務(wù)低峰期, 可以每天進(jìn)行都進(jìn)行全量備份(mysqldump 備份出來(lái)的文件比較小,壓縮之后更小)。
100G 以上的庫,可以考慮用 xtranbackup 來(lái)做,備份速度明顯要比 mysqldump 要快。
一般是選擇一周一個(gè)全備,其余每天進(jìn)行增量備份,備份時(shí)間為業(yè)務(wù)低峰期。
聯(lián)系客服