python_面試題_DB相關問題

1.mysql部分

問題mysql

問題1:mysql的存儲引擎redis

問題2:mysql的索引機制sql

問題3:mysql的事務以及事務隔離級別數據庫

問題4:mvcc/GAP lock是作什麼的緩存

問題5:mysql的悲觀鎖與樂觀鎖安全


回答session

問題1:mysql的存儲引擎

mysql的存儲引擎多線程

  • 在mysql中的查詢語句爲:mysql> show engines,
  • 查看當前mysql的默認存儲引擎爲:mysql> show variables like '%storage_engine%',
  • 查看某個表用了什麼引擎則是:mysql> show create table 表名;

mysql的經常使用存儲引擎架構

  • MyISAM:不支持事務,不支持外鍵,訪問速度快,對事務完整性沒有要求,設計之初主要爲了查詢操做。使用場景有:非事務型應用,只讀類應用,空間類應用
  • InnoDB(MySQL 5.5後默認引擎):支持完整事務,支持外鍵約束,行級鎖,設計之初處理大容量數據庫操做,容易有IO瓶頸。使用場景:適用絕大多數場景
  • MEMORY:只存儲表,數據放在內存中,掉電後數據不保留,訪問速度快。使用場景:內容變化不頻繁的代碼表,或者是做爲統計


問題2:mysql的索引機制

mysql的索引機制有以下幾種併發

  • 彙集索引:就是按照每張表的主鍵構造一顆B+樹,葉子節點村完整的行記錄數據,未定義主鍵,則取第一個惟一索引,每張表只能擁有一個彙集索引。在多數狀況下,查詢優化器傾向於採用彙集索引。由於彙集索引可以在B+樹索引的葉子節點上直接找到數據,而且能夠快速查找數據。
  • 非彙集索引:是對彙集索引的一種補充,每張表能夠有多個輔助索引,輔助索引與彙集索引區別爲葉子節點不包含行記錄的所有數據,除此以外還包含一個書籤,能夠指向對應的行數據。
  • 普通索引:普通的索引,index只是爲了加速查找
  • 惟一索引:主鍵索引:加速查找+約束(不爲空,不能重複) 惟一索引:加速查找+約束(不能重複)
  • 組合索引:多個索引聯合查找,查找順序從左到右查詢。

備註:舉例說明索引機制的使用場景(商城的會員卡系統,會員編號做爲主鍵,會員編號就是惟一索引,用來建立B+樹;會員姓名若是要建立索引,則就是普通索引;會員身份證信息若是要建立索引,則就是惟一索引)

補充知識:B+樹與B樹

(1.)B樹

所謂的B樹就是多路搜索樹,任意一個非葉子節點最多有M個兒子,關鍵字分佈在整顆樹中,任何一個關鍵字出現且只出現一個節點中,搜索有可能在非葉子節點中結束,性能等價於二分查找,時間複雜度爲O(lgN)

如:(M=3)

image

(2.)B+樹

所謂的B+樹,就是B樹的變體,也是多路搜索樹,非葉子節點的字數指針與關鍵字個數相同,非葉子節點子樹指針指向子樹,全部的葉子節點都增長一個鏈指針,全部的關鍵字都在葉子節點中出現,不可能在非葉子結點命中,非葉子結點至關因而葉子結點的索引(稀疏索引),葉子結點至關因而存儲(關鍵字)數據的數據層,比較適合文件索引系統

如:(M=3)

image


問題3:mysql的事務以及事務隔離級別

mysql的事務遵循4個條件(ACID),有原子性:不可分割性;一致性;隔離性;持久性;在實際使用中,使用事務保證一個事務中的操做,要麼所有完成,要麼所有不完成,保證數據的安全性

其中事務隔離級別分爲如下幾種

  • RU:既未提交讀,容易出現髒讀狀況,既事務A讀到了事務B沒有提交的數據;
  • RC:既提交讀,爲解決髒讀問題,容易出現提交重複的狀況,既事務A在執行的過程當中,有可能事務B提交了數據,事務讀取的數據和以前不一致;
  • RR:既可重複讀,爲解決上一級的數據不一致問題,該級別採用MVCC(多版本併發操做)解決重複讀,通常RR級別會產生幻讀的問題,既同一個事務屢次執行同一個select,讀取到的數據行發生了改變,這是由於數據行發生了行數減小或者新增;所謂幻讀就是同一個事務裏,查詢的結果都是事務開始時的狀態(一致性)。可是,若是另外一個事務同時提交了新數據,本事務再更新時,就會「驚奇的」發現了這些新數據,貌似以前讀到的數據是「鬼影」同樣的幻覺。搞笑的比喻就是,假如,中午去食堂打飯吃,看到一個座位是空的,便屁顛屁顛的去打飯,回來後,發現這些座位都仍是空的(重複讀),竊喜。走到跟前剛準備坐下時,卻驚現一個恐龍妹,嚴重影響食慾。彷彿以前看到的空座位是「幻影」同樣。可是mySQL中RR級別引入了GAP LOCK(間隙鎖)的概念,可在RR級別便可解決幻讀的問題;另一個特性是mysql裏的MVCC只解決讀-寫的阻塞問題,寫-寫依然仍是阻塞的。
  • SE:既可序列化,事務至關於串行操做,解決了髒讀、不可重複讀、幻讀等問題,但對性能和效率的影響很大


問題4:mvcc/GAP lock是作什麼的

MVCC:既多版本併發操做,基本原理就是某個時間點的快照,每行數據都存在一個版本,每次數據更新時都更新該版本,修改是copy出當前版本隨意修改,各個事務之間無干擾,保存時則比較版本號,若是成功,則覆蓋原紀錄,失敗則放棄並回滾。須要注意的是mysql裏的MVCC只解決讀-寫的阻塞問題,寫-寫依然仍是阻塞的

GAP lock:間隙鎖,用於解決mySQL中RR級別的幻讀問題,若是一個事務操做的是一個區間的數據,會鎖住這個區間全部的記錄,即便這個記錄不存在,這個時候另外一個會話去插入這個區間的數據,就必須等待上一個結束。須要注意的是在此有可能會產生GAP死鎖,例以下圖


問題5:mysql的悲觀鎖與樂觀鎖

不管悲觀鎖和樂觀鎖都是併發控制主要採用的技術手段,都是爲了保證數據庫中的數據的完整性與一致性

悲觀鎖:對數據被外界修改持保守態度 (悲觀),所以,在整個數據處理過程當中,將數據處於鎖定狀態。 悲觀鎖的實現,每每依靠數據庫提供的鎖機制,而悲觀鎖通常流程以下

  1. 在對任意記錄進行修改前,先嚐試爲該記錄加上排他鎖(exclusive locking)
  2. 若是加鎖失敗,說明該記錄正在被修改,那麼當前查詢可能要等待或者拋出異常。 具體響應方式由開發者根據實際須要決定。
  3. 若是成功加鎖,那麼就能夠對記錄作修改,事務完成後就會解鎖了。

悲觀鎖主要用於數據爭用激烈的環境,以及發生併發衝突時使用鎖保護數據的成本要低於回滾事務的成本的環境中。在效率方面,處理加鎖的機制會讓數據庫產生額外的開銷,還有增長產生死鎖的機會;另外,在只讀型事務處理中因爲不會產生衝突,也不必使用鎖,這樣作只能增長系統負載,還有會下降了並行性。

悲觀鎖的應用

樂觀鎖:假設認爲數據通常狀況下不會形成衝突,因此在數據進行提交更新的時候,纔會正式對數據的衝突與否進行檢測,若是發現衝突了,則讓返回用戶錯誤的信息,讓用戶決定如何去作。在對數據庫進行處理的時候,樂觀鎖並不會使用數據庫提供的鎖機制。通常的實現樂觀鎖的方式就是記錄數據版本。

  1. 當讀取數據時,將版本標識的值一同讀出,數據每更新一次,同時對版本標識進行更新。
  2. 當咱們提交更新的時候,判斷數據庫表對應記錄的當前版本信息與第一次取出來的版本標識進行比對
  3. 若是數據庫表當前版本號與第一次取出來的版本標識值相等,則予以更新,不然認爲是過時數據。

樂觀鎖的應用


2.MongoDB部分

問題:

問題1:MongoDB的存儲引擎以及底層存儲機制

問題2:MongoDB的版本變遷既特性


回答:

問題1:

存儲引擎以下:

  • MMAP:
  • WiredTiger:3.2版本默認存儲引擎都改成了wiredtiger,特性爲:文檔級別鎖,解決了鎖粒度過大的問題,磁盤數據壓縮,刪除數據時,數據會當即刪除,MongoDB3.0在多線程、批量插入場景下較之於MongoDB2.6有大約4-7倍的增加
  • RocksDB:特性:順序寫入:LSM Tree結構,隨機寫入轉換爲順序寫入;速度穩定:和WiredTiger相比,寫速度穩定
  • Memory

底層存儲機制:空間局部性原理,B樹


問題2:

MongoDB 3.0特性(2015年):順序寫入:LSM Tree結構,隨機寫入轉換爲順序寫入,速度穩定:和WiredTiger相比,寫速度穩定

MongoDB 4.0特性(2018年6月):多文檔事務支持,4.2版本開始支持分片集羣分佈式事務


3.Redis部分

問題:

問題1:redis支持的數據類型經常使用使用場景

問題2:redis的存儲機制以及經常使用集羣


回答

問題1:

redis支持的數據類型主要有string,list,set,zset,hash

redis的經常使用使用場景

  • 做爲熱數據的緩存數據庫,緩存高頻次訪問的數據,下降數據庫的IO
  • 分佈式架構,作session共享
  • 利用zset類型能夠作存儲排行榜
  • 利用list作簡易MQ或存儲最新的n個數據


問題2:

redis的存儲機制有

  • list鍵:雙向鏈表
  • hash鍵:字典dict
  • zset鍵:跳躍表zskiplist
  • ziplist:節省內存空間

經常使用集羣方式有

  • Twitter開發的twemproxy
  • 豌豆莢開發的codis
  • redis官方的redis-cluster

ok

相關文章
相關標籤/搜索