MySQL
事務(wù)隔離級(jí)別有哪幾種?
MySQL支持 4 種事務(wù)隔離級(jí)別,這些隔離級(jí)別定義了事務(wù)之間的可見(jiàn)性和并發(fā)控制方式。
- READ UNCOMMITTED(讀未提交):這是最低的隔離級(jí)別。在該級(jí)別下,事務(wù)可以讀取未提交事務(wù)的數(shù)據(jù),可能會(huì)導(dǎo)致臟讀、不可重復(fù)讀和幻像讀問(wèn)題。一般情況下不建議使用此級(jí)別。
- READ COMMITTED(讀已提交):在這個(gè)級(jí)別下,事務(wù)只能讀取已經(jīng)提交的數(shù)據(jù),可以避免臟讀,但仍可能出現(xiàn)不可重復(fù)讀和幻像讀問(wèn)題。
- REPEATABLE READ(可重復(fù)讀):這是MySQL默認(rèn)的隔離級(jí)別。在該級(jí)別下,事務(wù)能夠讀取和鎖定事務(wù)開(kāi)始時(shí)的數(shù)據(jù)快照,從而避免了臟讀和不可重復(fù)讀。但幻像讀問(wèn)題仍然可能出現(xiàn)。
-
SERIALIZABLE(串行化):這是最高的隔離級(jí)別。在該級(jí)別下,事務(wù)完全隔離,不會(huì)發(fā)生臟讀、不可重復(fù)讀和幻像讀。但它也是最慢的級(jí)別,因?yàn)樗鼤?huì)在讀取數(shù)據(jù)時(shí)對(duì)數(shù)據(jù)進(jìn)行鎖定,阻止其他事務(wù)的并發(fā)操作。
如果不考慮隔離性,可能會(huì)引發(fā)如下問(wèn)題:
- 臟讀(Dirty Read):臟讀指的是一個(gè)事務(wù)讀取了另一個(gè)事務(wù)尚未提交的數(shù)據(jù)。如果另一個(gè)事務(wù)在最終沒(méi)有提交的情況下回滾了,那么讀取的數(shù)據(jù)就是無(wú)效的。臟讀可能導(dǎo)致不一致的數(shù)據(jù)和不準(zhǔn)確的查詢(xún)結(jié)果。
- 幻讀(Phantom Read):幻讀是指在同一事務(wù)內(nèi)的兩次查詢(xún)中,第二次查詢(xún)發(fā)現(xiàn)了更多的數(shù)據(jù)行,這是由于在兩次查詢(xún)之間有另一個(gè)事務(wù)插入了新的數(shù)據(jù)行?;米x與不可重復(fù)讀不同之處在于,不可重復(fù)讀是由于已提交事務(wù)的更新導(dǎo)致的數(shù)據(jù)不一致,而幻讀是由于新插入的數(shù)據(jù)導(dǎo)致的數(shù)據(jù)不一致。
- 不可重復(fù)讀(Non-Repeatable Read):不可重復(fù)讀是指在同一事務(wù)內(nèi)的兩次查詢(xún)中,第二次查詢(xún)發(fā)現(xiàn)了不同的數(shù)據(jù)。這是由于在兩次查詢(xún)之間有另一個(gè)事務(wù)修改了數(shù)據(jù)并提交了事務(wù)。不可重復(fù)讀可能導(dǎo)致事務(wù)內(nèi)部的一致性問(wèn)題,因?yàn)槭聞?wù)在兩次查詢(xún)之間看到了不一致的數(shù)據(jù)。
MySQL的常用的存儲(chǔ)引擎有哪些?特點(diǎn)是什么,分別適合什么場(chǎng)景下使用
MySQL的表類(lèi)型由存儲(chǔ)引擎決定,主要包括:myisam、innodb、memory等
- innodb 存儲(chǔ)引擎:支持事務(wù)和外鍵,行級(jí)鎖
- myisam 存儲(chǔ)引擎:不支持事務(wù)和外鍵,支持全文搜索,添加速度快,表級(jí)鎖
-
memory 存儲(chǔ)引擎:不支持事務(wù)和外鍵,表級(jí)鎖,數(shù)據(jù)存儲(chǔ)在內(nèi)存中(關(guān)閉了MySQL服務(wù),數(shù)據(jù)丟失,但是表結(jié)構(gòu)還在), 執(zhí)行速度很快(沒(méi)有IO讀寫(xiě)),默認(rèn)支持索引(hash表)
如何選擇存儲(chǔ)引擎
- 如果不需要事務(wù),讀多寫(xiě)少的業(yè)務(wù),選擇 myisam。
- 如果需要支持事務(wù)和數(shù)據(jù)完整性和外鍵約束等要求,選擇 innodb。
- memory存儲(chǔ)引擎將表數(shù)據(jù)存儲(chǔ)在內(nèi)存中,因此速度非常快。但它的數(shù)據(jù)是臨時(shí)的,重啟MySQL后數(shù)據(jù)會(huì)丟失,適用于臨時(shí)數(shù)據(jù)存儲(chǔ)或緩存。(經(jīng)典用法:用戶的在線狀態(tài))
MySQL有數(shù)據(jù)緩存嗎?原理是怎么樣的?
MySQL具有數(shù)據(jù)緩存機(jī)制,其中包括查詢(xún)緩存和innodb緩沖池(Buffer Pool)。
MySQL的數(shù)據(jù)庫(kù)緩存機(jī)制默認(rèn)是開(kāi)啟的,但不同部分的緩存可以根據(jù)配置進(jìn)行調(diào)整。
不同存儲(chǔ)引擎對(duì)數(shù)據(jù)緩存的支持程序可能不同。一般來(lái)說(shuō),innodb存儲(chǔ)引擎具有較強(qiáng)的緩沖機(jī)制,而其他存儲(chǔ)引擎比如myisam也支持一些緩存機(jī)制。
-
innodb緩沖池:innodb存儲(chǔ)引擎默認(rèn)啟用了緩沖池,用于緩存表數(shù)據(jù)和索引??梢酝ㄟ^(guò)配置
innodb_buffer_pool_size
參數(shù)來(lái)控制緩沖池的大小。- 原理:用于存儲(chǔ)數(shù)據(jù)庫(kù)表數(shù)據(jù)和索引的內(nèi)存緩存區(qū)域。當(dāng)查詢(xún)需要訪問(wèn)表數(shù)據(jù)或索引時(shí),MySQL會(huì)先檢查緩沖池中是否有相應(yīng)的數(shù)據(jù)頁(yè)。如果有,將從內(nèi)存中獲取數(shù)據(jù),而不是從磁盤(pán)讀取,以提高查詢(xún)性能。
- 作用:提高查詢(xún)性能,因?yàn)閮?nèi)存訪問(wèn)比磁盤(pán)訪問(wèn)快的多??梢?strong>顯著減少 IO 操作。特別是在大型數(shù)據(jù)庫(kù)中。緩沖池還可以存儲(chǔ)最常用的數(shù)據(jù),以減少磁盤(pán)訪問(wèn)的需求。
- 數(shù)據(jù)一致性保護(hù)措施:默認(rèn)情況下,innodb存儲(chǔ)引擎已經(jīng)采取了一些措施來(lái)確保數(shù)據(jù)的一致性。
-
查詢(xún)緩存:在MySQL8.0 版本已被棄用。因?yàn)樗诟卟l(fā)和寫(xiě)入頻繁的數(shù)據(jù)庫(kù)中可能引發(fā)性能問(wèn)題。在較早的MySQL版本中,可以通過(guò)設(shè)置
query_cache_type
和query_cache_size
參數(shù)來(lái)啟用和配置查詢(xún)緩存。- 原理:是MySQL的查詢(xún)結(jié)果緩存,會(huì)存儲(chǔ)已經(jīng)執(zhí)行過(guò)的查詢(xún)的結(jié)果集。當(dāng)一個(gè)查詢(xún)執(zhí)行時(shí),MySQL會(huì)檢查查詢(xún)緩存是否已經(jīng)有了相同查詢(xún)的結(jié)果,如果有,就直接返回緩存中的結(jié)果,而不執(zhí)行實(shí)際的查詢(xún)。以減少查詢(xún)的執(zhí)行時(shí)間,提高性能。
- 問(wèn)題:可以提供性能,但存在限制。比如:如果數(shù)據(jù)庫(kù)中的數(shù)據(jù)發(fā)生了變化,查詢(xún)緩存可能導(dǎo)致臟數(shù)據(jù)的返回。因此,在高并發(fā)、頻繁寫(xiě)入的數(shù)據(jù)庫(kù)中不太適用。
- 鍵緩存:MySQL支持鍵緩存,用于緩存表的索引??梢允褂?code>key_buffer_size參數(shù)來(lái)配置鍵緩存的大小。
如何避免緩存帶來(lái)的臟數(shù)據(jù)問(wèn)題?
- 合理配置緩沖區(qū)大?。捍_保為緩沖池和其他緩沖區(qū)分配合理的大小,以適應(yīng)數(shù)據(jù)庫(kù)的工作負(fù)載和可用內(nèi)存。不要過(guò)分依賴(lài)緩存,否則可能導(dǎo)致臟數(shù)據(jù)問(wèn)題。
- 使用事務(wù)隔離級(jí)別:通過(guò)配置適當(dāng)?shù)氖聞?wù)隔離級(jí)別,減少臟讀和不可重復(fù)讀的可能性,從而提高數(shù)據(jù)一致性。
- 定期刷新緩存:在高并發(fā)的寫(xiě)入場(chǎng)景中,定期刷新緩存可以確保數(shù)據(jù)的一致性。使用
innodb_flush_method
等參數(shù)來(lái)配置刷新策略。 - 監(jiān)控性能和緩存命中率:通過(guò)監(jiān)視數(shù)據(jù)庫(kù)性能和緩存命中率,及時(shí)發(fā)現(xiàn)性能問(wèn)題和緩存引起的臟數(shù)據(jù)問(wèn)題。
InnoDB的緩沖池默認(rèn)是開(kāi)啟的嗎?基本原理是什么?會(huì)有臟數(shù)據(jù)的問(wèn)題嗎?
InnoDB的緩沖池是默認(rèn)啟用的,而且在大多數(shù)情況下,使用默認(rèn)配置的InnoDB緩沖池不會(huì)導(dǎo)致臟數(shù)據(jù)問(wèn)題。
默認(rèn)情況下,InnoDB存儲(chǔ)引擎已經(jīng)采取了一些措施來(lái)確保數(shù)據(jù)的一致性,即使在默認(rèn)的事務(wù)隔離級(jí)別下也應(yīng)該是安全的。
以下是一些有關(guān)InnoDB緩沖池和臟數(shù)據(jù)的重要考慮因素:
- 默認(rèn)配置:默認(rèn)情況下,InnoDB使用行級(jí)鎖和可重復(fù)讀(REPEATABLE READ)的事務(wù)隔離級(jí)別。這意味著InnoDB在默認(rèn)情況下已經(jīng)配置為盡量減少臟數(shù)據(jù)的風(fēng)險(xiǎn)。
- 緩沖池管理:InnoDB緩沖池會(huì)根據(jù)需要自動(dòng)管理,它會(huì)將頻繁訪問(wèn)的數(shù)據(jù)頁(yè)加載到內(nèi)存中,并根據(jù)LRU(最近最少使用)算法來(lái)替換不常使用的數(shù)據(jù)頁(yè)。這有助于提高性能,并減少臟數(shù)據(jù)的可能性。
- 臟數(shù)據(jù)問(wèn)題:臟數(shù)據(jù)問(wèn)題通常出現(xiàn)在高并發(fā)寫(xiě)入的情況下,當(dāng)多個(gè)事務(wù)同時(shí)修改相同數(shù)據(jù)時(shí),可能會(huì)導(dǎo)致臟數(shù)據(jù)。但默認(rèn)的InnoDB配置和事務(wù)隔離級(jí)別通常會(huì)確保數(shù)據(jù)的一致性,盡管可能會(huì)導(dǎo)致一些性能開(kāi)銷(xiāo)。
InnoDB存儲(chǔ)引擎使用了一種稱(chēng)為寫(xiě)前日志(Write-Ahead Logging,WAL)的機(jī)制來(lái)確保數(shù)據(jù)的一致性和持久性。具體操作流程如下:
- 當(dāng)有數(shù)據(jù)更新操作時(shí),InnoDB首先將這個(gè)更新操作記錄在事務(wù)的寫(xiě)前日志(redo log)中。這個(gè)寫(xiě)前日志是磁盤(pán)上的一個(gè)特殊文件。
- 同時(shí),InnoDB會(huì)將數(shù)據(jù)修改操作應(yīng)用到內(nèi)存中的緩沖池(Buffer Pool),從而提高讀取和寫(xiě)入性能。這意味著數(shù)據(jù)的修改首先是在內(nèi)存中的緩沖池中進(jìn)行的。
- 為了確保數(shù)據(jù)的持久性,InnoDB在適當(dāng)?shù)臅r(shí)機(jī)將緩沖池中的數(shù)據(jù)異步刷新到磁盤(pán)。這個(gè)操作通常發(fā)生在后臺(tái)線程中,而不會(huì)阻塞用戶事務(wù)。
- 當(dāng)事務(wù)提交時(shí),InnoDB將事務(wù)的寫(xiě)前日志記錄標(biāo)記為已提交,從而使這個(gè)事務(wù)的修改在崩潰恢復(fù)時(shí)可以被應(yīng)用。
這個(gè)操作流程保證了數(shù)據(jù)的持久性和一致性,即使在數(shù)據(jù)修改過(guò)程中出現(xiàn)了崩潰或故障。這是InnoDB存儲(chǔ)引擎的核心特性,確保了數(shù)據(jù)在事務(wù)隔離下的一致性。
在這個(gè)過(guò)程中,InnoDB使用了行級(jí)鎖來(lái)確保多個(gè)事務(wù)之間的并發(fā)性。每個(gè)數(shù)據(jù)行都可以被多個(gè)事務(wù)并發(fā)訪問(wèn),而行級(jí)鎖會(huì)確保數(shù)據(jù)的一致性。如果多個(gè)事務(wù)嘗試同時(shí)修改相同的數(shù)據(jù)行,InnoDB會(huì)使用鎖機(jī)制來(lái)協(xié)調(diào)它們的訪問(wèn),以避免數(shù)據(jù)損壞和不一致。
總之,InnoDB存儲(chǔ)引擎通過(guò)使用寫(xiě)前日志、內(nèi)存緩沖池、異步刷新到磁盤(pán)以及行級(jí)鎖等機(jī)制,來(lái)確保數(shù)據(jù)的一致性和持久性,即使在高并發(fā)和崩潰情況下也能保持?jǐn)?shù)據(jù)的完整性。這是InnoDB在事務(wù)隔離下操作的基本原理。
Redo Log(重做日志) 和 Bin Log(二進(jìn)制日志)的區(qū)別是什么?
Redo Log(重做日志)和Binary Log(二進(jìn)制日志) 是MySQL中兩種不同的日志文件,它們有不同的目的和用途。
-
Redo Log(重做日志):
- 目的:Redo Log是InnoDB存儲(chǔ)引擎特有的一種日志,其主要目的是確保事務(wù)的持久性。它記錄了每個(gè)事務(wù)所做的修改操作,以便在數(shù)據(jù)庫(kù)發(fā)生故障或崩潰時(shí)進(jìn)行恢復(fù)。Redo Log用于保證數(shù)據(jù)的一致性和完整性。
- 持久性:Redo Log是持久性的,它通常存儲(chǔ)在磁盤(pán)上,并且不會(huì)輕易被刪除。
- 格式:Redo Log是二進(jìn)制格式,記錄了事務(wù)的修改操作,但不包含SQL語(yǔ)句。
-
Binary Log(二進(jìn)制日志):
- 目的:Binary Log用于記錄數(shù)據(jù)庫(kù)的所有變更操作,包括數(shù)據(jù)修改、DDL語(yǔ)句、數(shù)據(jù)導(dǎo)入等。它的主要目的是實(shí)現(xiàn)數(shù)據(jù)復(fù)制和恢復(fù),以便在不同服務(wù)器之間同步數(shù)據(jù)或進(jìn)行數(shù)據(jù)恢復(fù)。
- 持久性:Binary Log通常也是持久性的,但它可以配置為自動(dòng)刪除舊日志以減少磁盤(pán)空間占用。
- 格式:Binary Log可以以文本格式或二進(jìn)制格式存儲(chǔ),它包含了SQL語(yǔ)句或二進(jìn)制事件。
主要區(qū)別在于目的和內(nèi)容:
* Redo Log 是InnoDB存儲(chǔ)引擎用來(lái)確保事務(wù)持久性和一致性的日志,它記錄了事務(wù)的修改操作,是二進(jìn)制格式,通常不包含SQL語(yǔ)句。
* Binary Log 用于數(shù)據(jù)復(fù)制和恢復(fù),它記錄了數(shù)據(jù)庫(kù)的所有變更操作,包括數(shù)據(jù)修改、DDL語(yǔ)句等,可以以文本或二進(jìn)制格式存儲(chǔ)。
MySQL的查詢(xún)緩存默認(rèn)是開(kāi)啟的嗎?
自 MySQL 5.7.20 版本起,查詢(xún)緩存(Query Cache)已被棄用,并且從 MySQL 8.0.20 版本開(kāi)始,查詢(xún)緩存已完全刪除,不再可用。
在這之前的 MySQL 版本中,查詢(xún)緩存默認(rèn)是啟用的,但隨著時(shí)間的推移,它被認(rèn)為不再適合高性能和高并發(fā)的數(shù)據(jù)庫(kù)系統(tǒng),因此被棄用并刪除。文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-739586.html
MySQL的sql注入怎么解決?
SQL注入是一種常見(jiàn)的數(shù)據(jù)庫(kù)攻擊,它可以允許攻擊者執(zhí)行惡意SQL查詢(xún)或修改數(shù)據(jù)庫(kù)數(shù)據(jù)。為了防止SQL注入,可以采取以下措施:文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-739586.html
-
使用參數(shù)化查詢(xún):最有效的防止SQL注入的方法是使用參數(shù)化查詢(xún),也叫預(yù)編譯語(yǔ)句或綁定變量。在參數(shù)化查詢(xún)中,SQL查詢(xún)中的參數(shù)值是作為參數(shù)傳遞給數(shù)據(jù)庫(kù),而不是通過(guò)字符串拼接直接插入SQL查詢(xún)中。這樣可以防止惡意輸入作為SQL代碼執(zhí)行。
示例(使用Golang的database/sql包):query := "SELECT * FROM users WHERE username = ? AND password = ?" rows, err := db.Query(query, username, password)
- 輸入驗(yàn)證和過(guò)濾:對(duì)用戶輸入進(jìn)行驗(yàn)證和過(guò)濾,確保只允許合法的字符和數(shù)據(jù)。這可以通過(guò)正則表達(dá)式或其他驗(yàn)證方法來(lái)實(shí)現(xiàn)。
- 避免拼接SQL查詢(xún):避免使用字符串拼接來(lái)構(gòu)建SQL查詢(xún),因?yàn)檫@樣容易受到注入攻擊。使用參數(shù)化查詢(xún)或ORM(對(duì)象關(guān)系映射)工具來(lái)構(gòu)建和執(zhí)行數(shù)據(jù)庫(kù)查詢(xún)。
- 限制數(shù)據(jù)庫(kù)用戶權(quán)限:數(shù)據(jù)庫(kù)用戶應(yīng)該被授予最小必要的權(quán)限。不要為應(yīng)用程序使用的數(shù)據(jù)庫(kù)用戶授予過(guò)多的權(quán)限,以降低潛在攻擊的影響。
- 錯(cuò)誤信息處理:不要向用戶顯示詳細(xì)的數(shù)據(jù)庫(kù)錯(cuò)誤信息,因?yàn)楣粽呖赡軙?huì)利用這些信息來(lái)發(fā)起攻擊。將錯(cuò)誤信息記錄到服務(wù)器日志而不是向用戶顯示。
- 定期更新和維護(hù):定期更新數(shù)據(jù)庫(kù)管理系統(tǒng)以獲得最新的安全性修復(fù)和補(bǔ)丁。同時(shí),確保應(yīng)用程序的依賴(lài)項(xiàng)也是最新的,包括數(shù)據(jù)庫(kù)驅(qū)動(dòng)程序。
- 安全編碼實(shí)踐:編寫(xiě)安全的代碼,包括防止SQL注入。審查和審計(jì)應(yīng)用程序代碼以識(shí)別潛在的漏洞。
- 使用Web應(yīng)用程序防火墻(WAF):WAF可以檢測(cè)和阻止常見(jiàn)的注入攻擊嘗試,為應(yīng)用程序提供額外的保護(hù)層。
MySQL中char和varchar有什么區(qū)別?
- 存儲(chǔ)方式
- char:是固定長(zhǎng)度的字符列。意味著無(wú)論實(shí)際存儲(chǔ)的字符串有多長(zhǎng),該列始終占用指定的固定字節(jié)數(shù)。如果 char(10),那么不管存儲(chǔ)的字符串是 hello 還是 world,都會(huì)占用 10 個(gè)字節(jié)的存儲(chǔ)空間。
- varchar:是可變長(zhǎng)度的字符列。只會(huì)占用實(shí)際存儲(chǔ)的字符串的字節(jié)數(shù),加上一些額外的字節(jié)用于存儲(chǔ)字符串的長(zhǎng)度信息。因此,varchar 列在存儲(chǔ)上更加節(jié)省空間,特別是對(duì)于存儲(chǔ)較短的字符串。
- 空間效率
- char:通常在存儲(chǔ)上更節(jié)省空間效率,因?yàn)樗徽加脤?shí)際數(shù)據(jù)的空間,而不浪費(fèi)額外的字節(jié)。這對(duì)于存儲(chǔ)邊長(zhǎng)的文本數(shù)據(jù)非常有用。
- varchar:在存儲(chǔ)上可能會(huì)浪費(fèi)空間,特別是當(dāng)大多數(shù)存儲(chǔ)的字符串都比指定長(zhǎng)度短時(shí),因?yàn)樗鼈內(nèi)匀粫?huì)占用固定的字節(jié)數(shù)。
- 查詢(xún)性能:char列的查詢(xún)性能通常略?xún)?yōu)于varchar,因?yàn)樗鼈兪枪潭ㄩL(zhǎng)度的,所以數(shù)據(jù)庫(kù)管理系統(tǒng)可以更容易的進(jìn)行索引操作和查詢(xún)優(yōu)化。但這個(gè)差異通常在實(shí)際應(yīng)用中并不顯著。
- 存儲(chǔ)和檢索速度:varchar可能在存儲(chǔ)和檢索速度上稍微快一些,因?yàn)樗ǔV淮鎯?chǔ)實(shí)際數(shù)據(jù),而不需要額外的字節(jié)來(lái)填充列的長(zhǎng)度。
Redis
到了這里,關(guān)于數(shù)據(jù)庫(kù)面試題整理的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!