c++后台開發面試常見知識點總結(四)數據庫


  • 數據庫的索引類型
  • 聚集索引和非聚集索引的區別(葉節點存儲內容)
  • 唯一性索引和主碼索引的區別
  • 索引的優缺點,什么時候使用索引,什么時候不能使用索引(重點)
  • 索引最左前綴問題
  • 數據庫中事務的ACID
  • 數據庫隔離性設置不同會出現的問題(臟讀、不可重復讀、丟失修改、幻讀)
  • Mysql有四個隔離級別:未提交讀,提交讀,可重復讀,可串行化。
  • Mysql的優化(高頻,索引優化,性能優化)
  • 數據庫引擎介紹,innodbmyisam的特點與區別
  • 數據庫連接池的作用
  • 講講你用過的所有鎖,除了互斥鎖與讀寫鎖比如自旋鎖,遞歸鎖,樂觀鎖,悲觀鎖
  • 兩段鎖協議
  • 關系型和非關系型數據庫的區別(各自優點)
  • 數據庫的范式
  • Mysql的表空間方式,各自特點。
  • 分布式事務
  • 視圖的作用與使用方法(如何刪除等)
  • 分庫分表,主從復制,讀寫分離。(我不會,也沒碰到過)
  • memcache中的數據結構是如何實現的
  • memcache,redis內部存儲數據原理

(1) 數據庫的索引類型

索引是在存儲引擎層實現的,不同存儲引擎具有不同的索引類型和實現。

B+Tree索引 :索引是大多數 MySQL 存儲引擎的默認索引類型。如InnoDB 引擎和MyISAM 存儲引擎。

哈希索引:InnoDB 引擎有一個特殊的功能叫“自適應哈希索引”,當某個索引值被使用的非常頻繁時,會在 B+Tree 索引之上再創建一個哈希索引,這樣就讓 B+Tree 索引具有哈希索引的一些優點,比如快速的哈希查找。哈希索引能以 O(1) 時間進行查找,但是失去了有序性,它具有以下限制:1.無法用於排序與分組;2.只支持精確查找,無法用於部分查找和范圍查找。

全文索引:MyISAM 存儲引擎支持全文索引,用於查找文本中的關鍵詞,而不是直接比較是否相等。查找條件使用 MATCH AGAINST,而不是普通的 WHERE。全文索引一般使用倒排索引實現,它記錄着關鍵詞到其所在文檔的映射。InnoDB 存儲引擎在 MySQL 5.6.4 版本中也開始支持全文索引。

空間數據索引(R-Tree)MyISAM 存儲引擎支持空間數據索引,可以用於地理數據存儲。空間數據索引會從所有維度來索引數據,可以有效地使用任意維度來進行組合查詢。

必須使用 GIS 相關的函數來維護數據。

(2) 聚集索引和非聚集索引的區別(葉節點存儲內容)

聚集索引:InnoDB主索引是聚簇索引,在索引中保存了數據,數據庫的表是通過主索引組織起來的,B+樹的葉節點的數據域存儲的完整的數據記錄。一個表只能有一個聚簇索引。

輔助索引的葉子節點的 data 域記錄着主鍵的值,因此在使用輔助索引進行查找時,需要先查找到主鍵值,然后再到主索引中進行查找。通常默認以自動遞增的值為主索引的主鍵,而不是以一個唯一的列作為主鍵。以唯一的列作為主鍵會造成在插入新記錄時數據文件為了維持B+Tree的特性而頻繁的分裂調整,十分低效,而使用自增字段作為主鍵則是一個很好的選擇。

非聚集索引:MyISAM提供的是非聚集索引。MyISAM主索引和輔助索引都是非聚集索引。B+樹的葉節點,存儲的是指向記錄的指針。


(3) 唯一性索引和主碼索引的區別

主鍵約束比唯一索引約束嚴格,當沒有設定主鍵時,非空唯一索引自動稱為主鍵。對於主鍵和唯一索引的一些區別主要如下:1.主鍵不允許空值,唯一索引允許空值。2.主鍵只允許一個,唯一索引允許多個。 3.主鍵產生唯一的聚集索引,唯一索引產生唯一的非聚集索引。

在使用InnoDB存儲引擎時,如果沒有特別的需要,請永遠使用一個與業務無關的自增字段作為主鍵。而不是選擇使用如學號或身份證號這種唯一字段作為主鍵。

創建唯一索引的目的往往不是為了提高訪問速度,而只是為了避免數據出現重復。

(4)索引的優缺點,什么時候使用索引,什么時候不能使用索引(重點)

索引雖然加快了查詢速度,但索引也是有代價的:索引文件本身要消耗存儲空間,同時索引會加重插入、刪除和修改記錄時的負擔,另外,MySQL在運行時也要消耗資源維護索引,因此索引並不是越多越好。一般兩種情況下不建議建索引。

第一種情況是表記錄比較少,沒必要建索引,讓查詢做全表掃描就好了。通常記錄數不超過 2000可以考慮不建索引,超過2000條可以酌情考慮索引。

另一種不建議建索引的情況是索引的選擇性較低。(索引的選擇性)


(5) 索引最左前綴問題

當按照索引中所有列進行精確匹配(這里精確匹配指“=”或“IN”匹配)時,索引可以被用到。

當查詢條件精確匹配索引的左邊連續一個或幾個列時,只能用到一部分索引,即條件所組成的最左前綴。


(6)數據庫中事務的ACID(四大特性都要能夠舉例說明,理解透徹,比如原子性和一致性的關聯,隔離性不好會出現的問題)

原子性:事務被視為不可分割的最小單元,事務的所有操作要么全部提交成功,要么全部失敗回滾。回滾可以用日志來實現,日志記錄着事務所執行的修改操作,在回滾時反向執行這些修改操作即可。

一致性:數據庫在事務執行前后都保持一致性狀態。在一致性狀態下,所有事務對一個數據的讀取結果都是相同的。

隔離性:一個事務所做的修改在最終提交以前,對其它事務是不可見的。

持久性:一旦事務提交,則其所做的修改將會永遠保存到數據庫中。即使系統發生崩潰,事務執行的結果也不能丟失。可以通過數據庫備份和恢復來實現,在系統發生奔潰時,使用備份的數據庫進行數據恢復。

事務的 ACID 特性之間不是一種一種平級關系:

  • 只有滿足一致性,事務的執行結果才是正確的。
  • 在無並發的情況下,事務串行執行,隔離性一定能夠滿足。此時要只要能滿足原子性,就一定能滿足一致性。
  • 在並發的情況下,多個事務並發執行,事務不僅要滿足原子性,還需要滿足隔離性,才能滿足一致性。
  • 事務滿足持久化是為了能應對數據庫奔潰的情況。

MySQL 默認采用自動提交模式。也就是說,如果不顯式使用START TRANSACTION語句來開始一個事務,那么每個查詢都會被當做一個事務自動提交。

在並發的情況下,事務的隔離性不能實現時,就會出現臟讀,不可重復讀,丟失修改,幻影讀等問題。

 

(7) 數據庫隔離性設置不同會出現的問題(臟讀、不可重復讀、丟失修改、幻讀)

丟失修改:T1 和 T2 兩個事務都對一個數據進行修改,T1 先修改,T2 隨后修改,T2 的修改覆蓋了 T1 的修改。則T1丟失修改。可在T1修改時對數據加上X鎖,直到T1結束鎖釋放,在此期間T2不可修改該數據。

臟讀:事務T1在修改數據a后,未commit。事務T2讀取數據a,隨后T1 rollback

撤銷修改,則T2讀到的數據a為臟數據。提交讀隔離級別解決臟讀問題。

不可重復讀:同一個事務中多次讀取同樣數據的結果不一樣。T2 讀取一個數據,T1 對該數據做了修改。如果 T2 再次讀取這個數據,此時讀取的結果和第一次讀取的結果不同。可在T2讀取數據時對數據加上S鎖,直到T2結束鎖釋放,在此期間T1不可修改該數據。可重復讀隔離級別解決了不可重復讀的問題。 

幻讀:T1 讀取某個范圍的數據,T2 在這個范圍內插入新的數據,T1 再次讀取這個范圍的數據,此時讀取的結果和和第一次讀取的結果不同。同上,同樣可以加S鎖解決該問題。

 MySQL 的 InnoDB 存儲引擎,在可重復讀(REPEATABLE READ)隔離級別下,使用 MVCC + Next-Key Locks 可以解決幻讀問題。


(8) 數據庫的隔離級別,mysql和Oracle的隔離級別分別是什么

Mysql有四個隔離級別:未提交讀,提交讀,可重復讀,可串行化。

未提交讀:事務中的修改,即使沒有提交,對其它事務也是可見的。總是讀取最新的數據行即是未提交讀隔離級別。

提交讀:一個事務只能讀取已經提交的事務所做的修改。換句話說,一個事務所做的修改在提交之前對其它事務是不可見的。

可重復讀:保證在同一個事務中多次讀取同樣數據的結果是一樣的。MVCC(多版本並發控制)實現提交讀和可重復讀這兩種隔離級別。

 

可串行化:強制事務串行執行。遵循兩段鎖協議實現可串行化。

(9) Mysql的優化(高頻,索引優化,性能優化)

查詢優化:寫SQL語句時,可以先select再JOIN,盡量把一元操作(select)往樹葉上壓,從而減小二元操作的規模。

 

索引優化:在進行查詢時,索引列不能是表達式的一部分,也不能是函數的參數,否則無法使用索引。

在需要使用多個列作為條件進行查詢時,使用多列索引比使用多個單列索引性能更好。

讓選擇性最強的索引列放在前面,索引的選擇性是指:不重復的索引值和記錄總數的比值。最大值為 1,此時每個記錄都有唯一的索引與其對應。選擇性越高,查詢效率也越高。

對於 類似VARCHAR 類型的列,必須使用前綴索引,只索引開始的部分字符。對於前綴長度的選取需要根據索引選擇性來確定。


(10) 數據庫引擎介紹,innodb和myisam的特點與區別。

Innodb:InnoDB 是 MySQL 默認的事務型存儲引擎,只有在需要 InnoDB 不支持的特性時,才考慮使用其它存儲引擎。實現了四個標准的隔離級別,默認級別是可重復讀。在可重復讀隔離級別下,通過多版本並發控制(MVCC)+ 間隙鎖(next-key locking)防止幻影讀。主索引是聚簇索引,在索引中保存了數據,從而避免直接讀取磁盤,因此對查詢性能有很大的提升。內部做了很多優化,包括從磁盤讀取數據時采用的可預測性讀、能夠加快讀操作並且自動創建的自適應哈希索引、能夠加速插入操作的插入緩沖區等。

Myisam:MyISAM 提供了大量的特性,包括壓縮表、空間數據索引等。不支持事務。不支持行級鎖,只能對整張表加鎖,讀取時會對需要讀到的所有表加共享鎖,寫入時則對表加排它鎖。但在表有讀取操作的同時,也可以往表中插入新的記錄,這被稱為並發插入。

比較

事務:InnoDB 是事務型的,可以使用 Commit 和 Rollback 語句。

並發:MyISAM 只支持表級鎖,而 InnoDB 還支持行級鎖。

外鍵:InnoDB 支持外鍵。

崩潰恢復:MyISAM 崩潰后發生損壞的概率比 InnoDB 高很多,而且恢復的速度也更慢。

備份:InnoDB 支持在線熱備份。

其它特性:MyISAM 支持壓縮表和空間數據索引。

 

11數據庫連接池的作用

什么是數據庫連接池:創建數據庫連接是一個很耗時的操作,也容易對數據庫造成安全隱患。所以,在程序初始化的時候,集中創建多個數據庫連接,並把他們集中管理,供程序使用,可以保證較快的數據庫讀寫速度,還更加安全可靠。數據庫連接池負責分配,管理和釋放數據庫連接,它允許應用程序重復使用一個現有的數據庫連接,而不是重新建立一個。連接池必須要確保某一時間內一個 conn 只能分配給一個線程。不同 conn 的事務是相互獨立的。

 

Java應用程序以傳統的連接機制訪問數據庫的過程:①裝載數據庫驅動程序;②通過JDBC建立數據庫連接;③訪問數據庫,執行SQL語句;④斷開數據庫連接。

使用了數據庫連接池的機制:①程序初始化時創建連接池。②使用時向連接池申請可用連接③使用完畢,將連接返還給連接池。④程序退出時,斷開所有連接,並釋放資源。

 

(12)講講你用過的所有鎖,除了互斥鎖與讀寫鎖比如自旋鎖,遞歸鎖,樂觀鎖,悲觀鎖

1.共享鎖(又稱讀鎖)、排它鎖(又稱寫鎖):

InnoDB引擎的鎖機制:InnoDB支持事務,支持行鎖和表鎖用的比較多,Myisam不支持事務,只支持表鎖。

 共享鎖(S):允許一個事務去讀一行,阻止其他事務獲得相同數據集的排他鎖。

排他鎖(X):允許獲得排他鎖的事務更新數據,阻止其他事務取得相同數據集的共享讀鎖和排他寫鎖。

意向共享鎖(IS):事務打算給數據行加行共享鎖,事務在給一個數據行加共享鎖前必須先取得該表的IS鎖。

意向排他鎖(IX):事務打算給數據行加行排他鎖,事務在給一個數據行加排他鎖前必須先取得該表的IX鎖。

2.樂觀鎖、悲觀鎖:

悲觀鎖:悲觀鎖,正如其名,它指的是對數據被外界(包括本系統當前的其他事務,以及來自外部系統的事務處理)修改持保守態度,因此,在整個數據處理過程中,將數據處於鎖定狀態。悲觀鎖的實現,往往依靠數據庫提供的鎖機制(也只有數據庫層提供的鎖機制才能真正保證數據訪問的排他性,否則,即使在本系統中實現了加鎖機制,也無法保證外部系統不會修改數據)

樂觀鎖:

樂觀鎖( Optimistic Locking ) 相對悲觀鎖而言,樂觀鎖假設認為數據一般情況下不會造成沖突,所以在數據進行提交更新的時候,才會正式對數據的沖突與否進行檢測,如果發現沖突了,則讓返回用戶錯誤的信息,讓用戶決定如何去做(一般是回滾事務)。那么我們如何實現樂觀鎖呢,一般來說有以下2種方式:

 (13)兩段鎖協議

加鎖和解鎖分為兩個階段進行。事務遵循兩段鎖協議是保證可串行化調度的充分條件。

(充分非必要,遵循一定保證可串行化,不遵循也可能會串行化)可串行化調度是指,通過並發控制,使得並發執行的事務結果與某個串行執行的事務結果相同。

(14) 關系型和非關系型數據庫的區別(各自優點)

 (15)數據庫的范式

不符合范式的關系(表),會產生很多異常,范式理論是為了解決異常。常見的異常有冗余數據,修改異常,刪除異常,插入異常。高級別范式的依賴於低級別的范式,1NF 是最低級別的范式。

1NF:屬性不可分。不滿足1NF不是一個合法的關系表。

2NF:每個非主屬性完全函數依賴於鍵碼。不滿足2NF可能會出現上述4種異常。可以通過分解表來滿足。

3NF:非主屬性不傳遞函數依賴於鍵碼。不滿足3NF可能會出現上述4種異常。可以通過分解表來滿足。

 

兩段鎖協議

加鎖和解鎖分為兩個階段進行。事務遵循兩段鎖協議是保證可串行化調度的充分條件。

(充分非必要,遵循一定保證可串行化,不遵循也可能會串行化)

 

可串行化調度是指,通過並發控制,使得並發執行的事務結果與某個串行執行的事務結果相同。


 Mysql的表空間方式,各自特點。

innodb引擎使Mysql有共享表空間和獨占表空間兩種數據存儲方式。

 

共享表空間: 一個數據庫的所有的表數據,索引數據共享一個表空間。多個表及索引在表空間中混合存儲。

優點:可以把表空間分成多個文件存放到各個磁盤上,一個表可以分布在不同步的文件上。

表空間可以分成多個文件存放到各個磁盤,所以表也就可以分成多個文件存放在磁盤上,表的大小不受文件,磁盤大小的限制。數據和文件放在一起方便管理。

缺點:多個表及索引在表空間中混合存儲,當一個表做了大量刪除操作后表空間中將會有大量的空隙。共享表空間大小不會收縮。

 

獨立表空間:每個表都有自已獨立的表空間。每個表的數據和索引都會存在自已的表空間中。

其它信息如,回滾(undo)信息、仍放在默認表空間。默認表空間不會收縮空間。

優點:可以實現單表在不同的數據庫中移動。 對於使用獨立表空間的表,不管怎么刪除,表空間的碎片不會太嚴重的影響性能,而且還有機會處理。獨立表空間大小可以收縮。

缺點:單表增加過大,如超過100個G。

總結:相比較之下,使用獨占表空間的效率以及性能會更高一點。共享表空間以及獨占表空間之間的轉化可以通過在配置文件中設置innodb_file_per_table參數實現。為OFF說明所使用的是獨占表空間。


(18) 分布式事務

一次大的操作由不同的小操作組成,這些小的操作分布在不同的服務器上,且屬於不同的應用,分布式事務需要保證這些小操作要么全部成功,要么全部失敗。本質上來說,分布式事務就是為了保證不同數據庫的數據一致性。

(21) 視圖的作用與使用方法(如何刪除等)

視圖是虛擬的表,對視圖的操作和對普通表的操作一樣。但視圖本身不包含數據,也就不能對其進行索引操作。視圖具有如下好處:1.通過只給用戶訪問視圖的權限,保證數據的安全性;2.簡化復雜的 SQL 操作,比如復雜的連接;3. 更改數據格式和表示;4. 只使用實際表的一部分數據;

CREATE VIEW myview AS

SELECT Concat(col1, col2) AS concat_col, col3*col4 AS compute_col

FROM mytable

WHERE col5 = val;

總結:視圖包含的不是表的數據,是對select查詢的封裝。可以簡化數據處理,重新格式化基礎數據。

(22) 分庫分表,主從復制,讀寫分離。(我不會,也沒碰到過)

分庫分表:

水平切分:又稱為 Sharding,它是將同一個表中的記錄拆分到多個結構相同的表中。當一個表的數據不斷增多時,Sharding 是必然的選擇,它可以將數據分布到集群的不同節點上,從而緩存單個數據庫的壓力。事務:使用分布式事務來解決事務問題。JOIN:可以將原來的 JOIN 查詢分解成多個單表查詢,然后在用戶程序中進行 JOIN。

 

memcache中的數據結構是如何實現的

memcache是分布式緩存服務器,通過在內存中緩存數據和對象來減少讀取數據庫的次數,從而提高動態、數據庫驅動網站的速度。memcache中保存的數據都存儲在memcache內置的內存存儲空間中。重啟memcache、操作系統都會導致全部數據消失。當memcache內容容量達到指定值之后,memcache就基於LRU算法淘汰淘汰緩存。memcache本身是為緩存而設計的服務器,因此沒有過多考慮數據永久性的問題。

memcache,redis內部存儲數據原理

https://blog.csdn.net/session_time/article/details/52618215

redis與memcached一樣,為了保證效率,數據都是緩存在內存中。區別的是Redis會周期性的把更新的數據寫入磁盤或者把修改操作寫入追加的記錄文件,並且在此基礎上實現了master-slave(主從)同步。


(23) 項目中哪里用到了數據庫,怎么用的


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM