數據庫-2020

一、MySQL

1、char和varchar的區別?

  • char的長度是不可變的,而varchar的長度是可變的。char[10]和varchar[10]存入‘abc’,char[10]長度爲10,‘abc’後跟空格補齊。varchar[10]長度爲3;
  • char存儲方式是,對英文字符(ASII)佔用1個字節,對一個漢字佔用兩個字節。而varchar的存儲方式是對每個英文字符佔用2個字節,漢字也佔用2個字節;
  • char的長度範圍是1到255;

2、事物四大特性

  • 原子性:不可分割的操作單元,事務中所有操作,要麼全部成功,要麼撤回到執行事務之前的狀態;
  • 一致性:事務需要從一個一致性狀態轉變成另一個一致性狀態。比如銀行轉賬,A賬戶轉到B賬戶,不管轉幾次,A和B賬戶的總金額不能變;
  • 隔離性:事務操作之間彼此獨立和透明互不影響。事務獨立運行,這通常使用鎖實現。一個事務處理後的結果,影響了其他事務,那麼其他事務會撤回,事務的100%隔離,需要犧牲速度;
  • 持久性:事務一旦提交,其結果就是永久的,即使發生系統故障,也能恢復;

3、事務的隔離級別

  • 讀未提交:最低級別,任何情況下都無法保證;
  • 讀已提交:可避免髒讀;
  • 可重複讀:可避免髒讀、不可重複讀,不可避免幻讀,是MySQL默認隔離級別;
  • 串行化:可避免髒讀、不可重複讀、幻讀的發生;

4、數據庫三範式

  • 第一範式:是對屬性的原子性約束,要求字段具有原子性,不可再分解。只要是關係型數據庫都滿足第一範式;
  • 第二範式:在滿足第一範式的前提下,非主鍵字段不能出現部分依賴主鍵;
  • 第三範式:在滿足第二範式的前提下,非主鍵字段不能出現傳遞依賴;

5、髒讀 & 不可重複讀 & 幻讀

  • 髒讀:是指在事務T1將某一值修改,然後事務T2讀取該值,此後T1因爲某種原因撤銷對該值的修改,這就導致了T2所讀取到的數據是無效的;
  • 不可重複讀:是指在數據庫訪問時,一個事務範圍內的兩次相同查詢卻返回了不同的數據。在一個事務內多次讀同一個數據,在這個事務還沒結束時,另外一個事務也訪問該數據,並做了修改操作。那麼在第一個事務中的兩次讀數據之間,由於第二個事務的修改,第一個事務兩次讀到的數據是不一樣的;
  • 幻讀:是指當事務不是獨立執行時發生的一種現象,比如第一個事務對一個表中的數據進行了修改,這種修改涉及到表中的全部數據執行。同時,第二個事務也修改這個表中的數據,這種修改是向表中插入一行新數據。那麼就會發生,操作第一個事務的用戶發現表中還有沒有修改的數據行,就好像發生了幻覺一樣;

6、不可重複讀 & 幻讀的區別

  • 如果使用鎖機制來實現這兩種隔離級別,在可重複讀中,該sql第一次讀取數據後,就將這些數據加鎖,其他事務無法修改這些數據,就可以實現重複讀了。但這種方法卻無法鎖住insert的數據,所以當事務A先前讀取了數據,或者修改了全部數據,事務B還是可以insert數據提交,這時事務A就會發現莫名其妙多了一條之前沒有的數據,這就是幻讀,不能通過行鎖來避免。需要設置串行化的隔離級別,讀用讀鎖,寫用寫鎖,讀鎖和寫鎖互斥,這麼做可以有效地避免幻讀、不可重複讀、髒讀等問題,但會極大地降低數據庫的併發能力。
  • 不可重複讀的重點在於update和delete,而幻讀的重點在於insert。

7、MyISAM和InnoDB的區別

  • InnoDB支持事務,MyISAM不支持;
  • MyISAM適合查詢及插入爲主的應用,InnoDB適合頻繁修改以及涉及到安全性較高的應用;
  • InnoDB支持外鍵,MyISAM不支持;
  • 從MySQL5.5以後,InnoDB是默認的搜索引擎;
  • MyISAM支持全文類型索引,而InnoDB不支持全文索引;
  • InnoDB中不保存表的總行數,select count() from table 查詢時,InnoDB需要掃描整個表計算有多少行,但MyISAM只需要簡單讀出保存好的總行數即可。注:當count() 語句包含where條件時,MyISAM也需要掃描整個表;
  • 對於自增長的字段,InnoDB中必須包含只有該字段的索引,但是在MyISAM表中可以和其他字段一起建立聯合索引;
  • 清空整個表時,InnoDB是一行行地刪除,效率慢。MyISAM則會重新建表,MyISAM使用delete語句刪除後,並不會立刻清理磁盤空間,需要定時清理;
  • InnoDB支持行鎖,不走索引的情況下會走表鎖;

8、什麼是索引

  • 索引是一種數據結構,可以幫助我們快速地進行數據的查找。

9、組合索引

  • 假設index(a,b,c)
  • 最左前綴匹配:模糊查詢時,使用%匹配,‘a%’會使用索引,‘%a’不會使用索引;
  • 條件中有or,索引不會生效;
  • ‘a and c’,a生效,c不生效;
  • ‘b and c’,都不生效;
  • ‘a and b>5 and c’,a和b生效,c不生效;

10、Hash索引和B+樹有什麼區別?

  • Hash索引進行等值查詢更快(一般情況下),但是無法進行範圍查詢。因爲hash索引中經過hash函數建立索引後,索引的順序與原順序無法保持一致。而B+樹的所有節點皆遵循左節點小於父節點,右節點大於父節點,多叉樹也是,天然支持範圍查詢;
  • hash索引不支持使用索引進行排序;
  • hash索引不支持模糊查詢以及多列索引的最左前綴匹配;
  • hash索引任何時候都避免不了回表查詢數據,而B+樹在某些條件下可以只通過索引來完成;
  • hash索引雖然在等值查詢上較快,但是查詢不穩定,性能不可預測,當某個鍵值存在大量重複的時候,發生hash碰撞,此時效率可能極差。而B+樹的查詢效率比較穩定,對於所有的查詢都是從根節點到葉子節點,且樹的高度較低;

11、MySQL有哪些鎖

  • 從鎖的類別上講,有共享鎖和排他鎖;
  • 從鎖的粒度上講,有行鎖、表鎖;
  • 樂觀鎖、悲觀鎖。

12、字段爲什麼要定義爲非null

  • null值會佔用更多的字節,且會在程序中造成很多與預期不符的情況。

13、索引優化

  • 只要列中含有null值,就最好不要在此設置索引,複合索引如果有Null值,此列在使用時也不會使用索引。
  • 儘量使用短索引,如果可以,應該制定一個前綴長度。
  • 對於經常在where子句使用的列,最好設置索引,這樣會加快查找速度。
  • 對於有多個列where或者order by子句的,應該建立複合索引。
  • 對於like語句,以%或者‘_’開頭的不會使用索引,以%結尾會使用索引。
  • 儘量不要在列上進行運算(函數操作和表達式操作)。
  • 儘量不要使用使用not in和 > < 操作。
  • 隱式升級的字段加引號。

14、慢查詢優化

  • explain 語句查看執行計劃
  • 業務場景上優化
  • 適當加索引
  • 查詢時,能不用 * 就不用,儘量寫全字段名
  • 多表連接時,儘量小表驅動大表,即小表join大表
  • 對於經常使用的查詢,可以開啓緩存

15、數據庫表優化

  • 表的字段儘可能用not null
  • 字段長度固定的表查詢會更快
  • 把數據庫的大表按時間或一些標誌分成小表
  • 將表拆分
  • 讀寫分離

16、explain查詢出的列

  • id:選擇標識符
  • select_type:查詢的類型
  • table:輸出結果集的表
  • partitions:匹配的分區
  • type:表示表的連接類型
  • possible_keys:表示查詢時,可能使用的索引
  • key:表示實際使用的索引
  • key_len:索引字段的長度
  • ref:列與索引的比較
  • rows:掃描出的行數,估算的行數
  • fitered:按表條件過濾的行百分比
  • extra:執行情況的描述和說明

17、type字段種類

all、index、range、ref、eq_ref、const、system、null

二、Redis

1、Redis爲什麼這麼快?

  • 完全基於內存
  • 數據結構簡單
  • 採用單線程,避免了不必要的上下文切換條件
  • 使用多路複用模型非阻塞IO

2、I/O多路複用模型

  • “多路”指的是多個網絡連接,“複用”指的是複用同一個線程
  • 採用多路複用技術可以讓單個線程高效地處理多個連接請求(儘量減少網絡IO的時間消耗),且Redis在內存中操作數據的速度非常快,也就是說內存內的操作不會成爲影響Redis的瓶頸

3、Redis的持久化方式

  • RDB:默認的持久化方式,按照一定的時間週期策略把內存的數據以快照的形式保存到硬盤的二進制文件中
  • AOF:Redis會將每一個收到的寫命令都通過write函數追加到文件最後,類似MySQL的binlog。當Redis重啓,會通過重新執行文件中保存的寫命令在內存中重建整個數據庫的內容
  • 當兩種方式同時開啓時,數據恢復Redis會優先選擇AOF方式恢復

4、Redis的三種集羣方式

  • 主從複製
    基於RDB文件進行同步
    優點:
    支持主從複製,主機會自動將數據同步到從機,可以進行讀寫分離。
    爲了分載主機的操作壓力,從服務器可以爲客戶端提供只讀操作的服務,寫服務仍然由主機來完成
    主機是以非阻塞的方式爲從機提供服務,所以在主從同步期間,客戶端仍然可以提交查詢或修改請求
    缺點:
    Redis不具備自動容錯和恢復功能,主機從機的宕機都會導致前端部分讀寫請求失敗,需要等待機器重啓或者手動切換前端的IP才能恢復
    主機宕機,宕機前有部分數據未能及時同步到從機,切換IP後還會引入數據不一致的問題,降低了系統的可用性
    Redis較難支持在線擴容,在集羣容量達到上限時,擴容會變得很複雜
  • 哨兵模式
    優點:
    哨兵模式是基於主從模式的,所有的主從的優點,哨兵模式都具有
    主從可以自動切換,系統更健壯,可用性更高
    缺點:
    Redis較難支持在線擴容,在集羣容量達到上限時,在線擴容會變得很複雜
  • Cluster集羣模式
    Redis的哨兵模式基本上已經可以實現高可用、讀寫分離,但是在這種模式下每臺Redis服務器都會存儲相同的數據,很浪費內存,所以在Redis 3.0上新加入Cluster模式,實現Redis的分佈式存儲,也就是說每臺Redis節點上存儲不同的內容
    特點:
    採用無中心結構
    所有的Redis節點彼此互聯,內部使用二進制協議優化傳輸速度和帶寬
    節點中的環節是通過集羣中超過半數的節點檢測失效時才生效
    客戶端與Redis節點直連,不需要中間代理層,客戶端不需要連接集羣所有節點,連接集羣中任何一個可用節點即可
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章