MySQL面試總結面試
# MySQL的存儲引擎算法
`MyISAM`(默認表類型):非事務的存儲引擎,基於傳統的`ISAM`(有索引的順序訪問方法)類型,是存儲記錄和文件的標準方法,不是事務安全,不支持外鍵,適用於頻繁的查詢。表鎖,不會出現死鎖,適合小數據和小併發。sql
- 爲何不會出死鎖?(沒有事務就不會繼續持有鎖)數據庫
答:由於`MyISAM`再查詢的時候,會同時鎖定這個`sql`裏面全部用到的表(獲取鎖的順序是一致的),不侷限與一張表,再寫鎖又重疊時,就得等待。緩存
**注意:【`MySQL5.5`以前默認的是`MyISAM`引擎了,5.5以後的版本默認都是`innodb`做爲存儲引擎】**安全
`innodb`:支持事務安全的存儲引擎,適用於插入和更新,支持外鍵,行鎖,事務。適合大數據,大併發。特別是針對多個併發和`QPS`較高的狀況。服務器
- `QPS:`就是每秒查詢率,`QPS`是對一個特定服務器再規定時間內能處理多少流量的衡量標準。網絡
- `TPS:`就是每秒傳輸處理的事務個數。併發
- `innodb`的行鎖模式:共享鎖,排他鎖,意向共享鎖(表鎖),意向排他鎖(表鎖),間隙鎖。(注意:若是`sql`語句沒有使用索引,`innodb`不能肯定操做的行時,使用意向鎖(表鎖))。負載均衡
- 死鎖問題
- 什麼是死鎖?
死鎖就是當倆個事務都須要獲取對方持有的排他鎖才能完成事務的時候,就致使了循環鎖等待,常見的死鎖類型。
- 解決辦法
1. 數據庫參數
2. 儘可能約定程序讀取表的順序
3. 在處理一個表時,儘可能對處理的順序排序
4. 調整事務隔離級別(避免倆個事務同時操做一行不存在的數據,容易發生死鎖)
存儲引擎還有:
- `MERGE:`將多個相似的`MyISAM`表分組爲一個表,能夠處理非事務性表,默認狀況下包括這些表。
- `MEMORY:`提供內存中的表,之前稱爲堆。它在RAM中處理全部數據,以便比在磁盤上存儲數據更快地訪問。用於快速查找引用和其餘相同的數據。
- `EXAMPLE:`可使用此引擎建立表,但不能存儲或獲取數據。這樣作的目的是教開發人員如何編寫新的存儲引擎。
- `ARCHIVE:`用於存儲大量數據,不支持索引。
- `CSV:`在文本文件中以逗號分隔值格式存儲數據。
- `BLACKHOLE:`受要存儲的數據,但始終返回空。
- `FEDERATED:`將數據存儲在遠程數據庫中。
# 數據表的類型
`MyISAM`,`InnoDB`,`MEMORY`,`HEAP`,`BOB`,`ARCHIVE`,`CSV`等
- `MYISAM:`成熟穩定,易於管理,快速讀取。表級鎖。
- `Innodb:`數據行鎖。佔用空間大,不支持全文索引。
# `MySQL`做爲發佈系統的儲存,一天五萬條以上的增量,怎麼優化?
1. 設計良好的數據庫結構,容許部分數據冗餘,儘可能避免join查詢,提升效率。
2. 選擇合適的表字段類型和存儲引擎,適當添加索引。
3. `MySQL`庫主從讀寫分離。
4. 找規律分表,減小表單中的數據量,提升查詢速度。
5. 添加緩存機制。可使用`Redis`緩存。
6. 不常常改動的頁面,生成靜態頁面。
7. 寫高效率的`sql`語句。如:`SELECT * FROM TABEL 改成 SELECT field_1, field_2, field_3 FROM TABLE`。
爲何要避免使用join查詢?
答:減小消耗。
# 對於大流量網站,如何解決各頁面統計訪問量問題?
1. 確認服務器是否能支撐當前訪問量。
2. 優化數據庫訪問。
3. 禁止外部訪問,如圖片盜鏈。
4. 控制文件下載。
5. 使用不一樣主機進行分流。
6. 使用瀏覽統計軟件,瞭解訪問量,有針對性的進行優化。
# 如何進行`SQL`優化?
1. 選擇正確的存儲引擎。
每一個引擎都有利有弊,好比`MyISAM`,適用於大量查詢,對大量寫操做並非很好,`update`一個字段都會把整個表鎖起來,而I`nnodb`,對一些小的應用,它比`MyISAM`慢,但它支持行鎖,再寫操做的時候,很優秀,它還支持更多的高級應用。
2. 優化字段的數據類型
一個原則,越小的越快,若是一個表只有幾列,那咱們就不用用`INT`來作主鍵,可使用`MEDIUMINT`,`SMALLINT`或是更小的`TINYINT`會更經濟一些,若是不須要記錄時間,使用`DATE`要比`DATETIME`好的多,也要留夠足夠的空間進行擴展。
3. 爲搜索字段添加索引
索引不必定只添加給主鍵或惟一的字段,若是在表中有某個字段常常用來作搜索,那就爲它創建索引,若是要搜索的字段是大的文本字段,那應該爲它創建全文索引。
4. 避免使用`select *`由於從數據庫讀出的數據越多,那麼查詢就會越慢。若是數據庫服務和WEB服務器在不一樣的機器上的話,還會增長網絡傳輸的負載。即便要查詢表的全部字段,也儘可能不要用`*`通配符。
5. 使用`ENUM`而不是`VARCHAR`
`ENUM`類型是很是快和緊湊的,它保存的是`TINYINT`,但外表上顯示的是字符串,作一些選項列表很好,好比:性別,民族,部門,狀態之類的字段,取值有限並且固定。
6. 儘量使用`NOT NULL`
`NULL`其實也須要額外空間的,在進行比較的時候,程序也會變得複雜,並非並不能夠用`NULL`,在現實的複雜狀況下,依然會有些狀況須要使用`NULL`值。
7. 固定長度的表會更快
若是表中的全部字段都是固定長度的,那整個表會被認爲是`「static」`或「`fixed-lenght」`。例如表中沒有`VARCHAR`,`TEXT`,`BLOB`,只要表中其中一個字段是這些類型,那麼這個表就不是「固定長度靜態表」了,這樣的話`MySQL`引擎會用另外一種方法來處理。
固定長度的表也容易被緩存和重建,惟一的反作用就是,固定長度的字段會浪費一些空間,由於固定長度的字段不管用不用,都會分配那麼多的空間。
# 如何設計一個高併發的系統
1. 數據庫優化,喝的事務隔離級別,`SQL`語句,索引優化。
2. 使用緩存,儘可能減小數據庫`IO`操做。
3. 分佈式數據庫,分佈式緩存。
4. 服務器負載均衡。
# 什麼狀況下設置了索引卻沒法使用
1. 以%開頭`LIKE`,模糊匹配。
2. `OR`語句先後沒有同時使用索引。
3. 數據類型出現隱式轉化,如`varchar`不加單引號可能會轉換爲`int`型。
# `SQL`注入的主要特色
1. 變種極多,攻擊簡單,危害極大。
2. 未經受權操做數據庫的數據。
3. 惡意篡改網頁。
4. 網頁掛木馬。
5. 私自添加系統帳號或是數據庫使用者帳號。
# 優化數據庫的方法
1. 選取最適合的字段屬性,儘量減小定義字段寬度,儘可能把字段設成`NOT NULL`。
2. 使用`exists`替代`in`,用`not exists`替代`not in`。
3. 使用鏈接`(JOIN)`來替代子查詢。
4. 適用聯合`(NUION)`來代替手動建立的臨時表。
5. 事務處理。
6. 鎖定表,優化事務處理。
7. 適當用外鍵,優化鎖定表。
8. 創建索引。
9. 優化查詢語句。
# 數據庫中的事務是什麼
事務做爲一個單元的一組有序的數據操做,若是組中的全部操做都完成,則認定事務成功,即便只有一個失敗,事務也不成功。若是全部操做完成,事務則進行提交,其修改將做用於全部其餘數據庫進程。若是一個操做失敗,則事務將回滾,該事務全部的操做的影響都會取消。
- `ACID`四大特性
- 原子性:不可分割,事務要麼所有被執行,要麼所有不執行。
- 一致性:事務的執行使得數據庫從一種正確的狀態轉換成另外一種正確的狀態。
- 隔離性:在事務正確提交前,不容許把該事務對數據的任何改變提供給任何其餘事務。
- 持久性:事務正確提交後,將結果永久保存到數據庫中,即便在事務提交後,有了其餘故障,事務處理結果也會獲得保存。
# 索引的目的是什麼?
1. 快速訪問數據表中特定信息,提升檢索速度。
2. 建立惟一性索引,保證每一行數據的惟一性。
3. 加速表和表之間的鏈接。
4. 使用分組和排序子句進行數據檢索時,可顯著的減小分組和排序的時間。
# 索引對數據庫系統的負面影響是什麼?
建立索引和維護索引須要消耗時間,這個時間會隨着數據量的增長而增長,索引須要佔用物理空間。當對錶進行增刪改查的時候索引也須要動態維護,這樣就下降了數據的維護速度。
# 爲數據表創建索引的原則
1. 頻繁使用的,用以縮小查詢範圍的字段上創建索引。
2. 頻繁使用的,須要排序的字段上創建索引。
# 什麼狀況下不宜創建索引
對於查詢中涉及不多的列,或是重複值較多的列,不宜創建索引。
一些特殊的數據類型,不宜就創建索引。如`text`文本字段。
# 左鏈接和右鏈接的區別
左鏈接:
- 左鏈接會讀取左表中的所有數據,即便右表中沒有對應的數據(若是倆個表有相同的數據,只會顯示一個),用`NULL`填充。
右鏈接:
- 右鏈接會讀取右表的所有數據,即便左表中沒有對應的數據(若是倆個表有相同的數據,只會顯示一個),用`NULL`填充。
# 什麼是鎖?
數據庫是一個多用戶使用的共享資源,當多個用戶併發的存取數據時,在數據庫中就會產生多個事務同時存取同一個數據的狀況,若對併發操做不加控制可能就會讀取和儲存不正確的數據,破壞數據庫的一致性。
# 什麼是存儲過程,用什麼來調用?
存儲過程就是一個預編譯的`SQL`語句,優勢是容許模塊化設計,只須要建立一次,就能夠在該程序中屢次調用,若是某次操做須要執行屢次`SQL`,使用存儲過程比單純的`SQL`語句要快。可使用一個命令對象進行調用。
# 索引的做用,和它的優缺點
索引就是一種特殊的查詢表,數據庫引擎能夠用它加速對數據的檢索,索引是惟一的,在建立時能夠以指定單個列或是多個列。缺點是它減慢了數據錄入的速度,同時也增長了數據庫的尺寸大小。
# 主鍵,外鍵,索引的區別?
主鍵:
- 惟一標識一條記錄,不可重複,不可爲`NULL`。
- 用來保證數據的完整性。
- 只能有一個。
外鍵:
- 表的外鍵是另外一個表的主鍵,外鍵能夠重複,能夠爲空。
- 用來和其餘表創建聯繫。
- 一個表能夠有多個外鍵。
索引:
- 該字段沒有重複值,能夠有一個是空值。
- 提升查詢效率排序速度。
- 一個表能夠有多個惟一索引。
# 對`SQL`語句的優化方法
1. 避免在索引列上使用計算。
2. 避免在索引列上使用`IS NULL`和`IS NOT NULL`。
3. 對查詢進行優化,儘可能避免全表掃描,首先因該考慮在`where`和`order by`涉及的列上創建索引。
4. 避免在`where`子句對字段進行null值判斷,這件致使引擎放棄使用索引而進行全表掃描。
5. 避免在`where`子句中對字段進行表達式操做,也會致使引擎放棄使用索引而進行全表掃描。
# `SQL`語句中「相關子查詢」和「非相關子查詢」有什麼區別
若是你想加載一篇你寫過的.md文件,在上方工具欄能夠選擇導入功能進行對應擴展名的文件導入,
繼續你的創做。
子查詢:嵌套在其餘查詢中的查詢。
非相關子查詢:
- 非相關子查詢是獨立於外部查詢的子查詢,子查詢總共執行一次,執行完畢後將值傳遞給外部的查詢。
相關子查詢:
- 相關子查詢的執行依賴於外部的查詢數據,外部查詢執行一次,子查詢就會執行一次。
【因此非相關子查詢比相關子查詢效率高】
# `char`和`varchar`的區別
- char`類型的數據列裏,每一個值都佔`M`個字節,若是長度小於`M`,就會在它的右邊用空格字符進行補足(在檢索操做中填補出來的空格符將會被去掉)。
- `vachar`類型的數據列裏,每一個值只佔用恰好夠用的字節再加上一個用來記錄長度的字節,因此總長度爲`L+1`字節。
# `SQL`問題
- 髒讀
- 在一個事務處理過程當中讀取到了另外一個未提交事務中的數據。
【例子】
A在一個轉帳事務中,轉了100給B,此時B讀到了這個轉帳的數據,而後作了一些操做(給A發貨,或是其餘),但是這個時候A的事務並無提交,若是A回滾了事務,那這就是髒讀。
- 不可重複讀
- 對數據庫中的某個數據,一個事務範圍內屢次查詢卻返回了不一樣的數據值,是因爲在查詢間隔,被另外一個事務修改並提交了。
【例子】
事務A在讀取某一數據,而事務B立馬修改了這個數據而且提交了事務到數據庫,事務A再次讀取就獲得了不一樣的結果。發生了不重複讀。
- 幻讀
- 事務非獨立執行時發生的一種現象。
【例子】
事務A對一個表中全部的行的某個數據項作了從「1」修改成「2」的操做,這時事務B又對這個表中插入了一行數據項,這個數據的數值仍是「1」而且提給了數據庫,若是事務A查看剛剛修改的數據,會發現還有一數據沒有修改,而這行數據時事務B中添加的,就像產生的幻覺同樣。發生了幻讀。
# `MySQL`事務隔離級別
1. `read uncmmited`:讀到未提交數據
- 最低級別,沒法保證任狀況
2. `read commited`:讀已提交
- 可避免髒讀
3. `repeatable read`:可重複讀
- 可避免髒讀、不可重複讀
4. `serializable`:串行事務
- 可避免髒讀、不可重複讀、幻讀
**【`MySQL`默認事務隔離級別爲`Repeatable Read`(可重複讀)】**
# `MySQL`臨時表
什麼是臨時表:臨時表是`MySQL`用於存儲中間結果集的表,臨時表只在當前鏈接可看,當鏈接關閉時會自動刪除表並釋放全部空間。
爲何會產生臨時表:通常是由於複雜的`SQL`致使臨時表被大量建立
- 進行`union`查詢時
- 用到`temptable`算法或者是`union`查詢中的視圖
- `ORDER BY`和`GROUP BY`的子句不同時
- 錶鏈接中,`ORDER BY`的列不是驅動表中的
- `DISTINCT`查詢而且加上`ORDER BY`時
- `SQL`中用到`SLQ_SMALL_RESULT`選項時
- `RROM`中的子查詢
臨時表分爲倆種:
- 內存臨時表
- 採用的是`memory`存儲引擎
- 磁盤臨時表
- 菜用的是`myisam`存儲引擎
# 什麼是視圖,遊標是什麼?
視圖:視圖是一種虛擬表,具備和物理表相同的功能。能夠對視圖表進行增刪改查操做,視圖一般是有一個表或者多個表的子集。對視圖的修改不會影響基本表。
- 【使得咱們獲取數據更容易,相比多表查詢】
遊標:是對查詢出來的結果集做爲一個單元來有效的處理。遊標能夠定在該單元的特定行,從結果集的當前行檢索一行或多行。能夠對結果集當前行進行修改。
- 【通常不會使用,但須要逐條處理數據的時候,遊標顯得十分重要】