「Python 面試」第五次更新

圖片描述

閱讀本文大約須要 8 分鐘。

寫在前面

數據庫打算只寫 MySQL,Redis 兩部分,不會很細,主要以面試題爲主。此次寫的是 MySQL 篇。面試

1.說一下 char、varchar 、text 的區別

這裏先介紹一下數據庫的概念,數據庫是一種數據結構,內含多種算法,幫助咱們將數據以最優化的方式存儲在計算機中,也能夠幫助咱們快速找到存儲的數據。算法

數據最終存儲在計算機中都是以「二進制」的方式存儲。好比 4,存儲在計算機中實際上是以 0100 的方式存儲。好比 A,存儲在計算中是以 0100 0001 的方式存儲。數據庫

char:定長字符型,最大可存儲 255 (2 的 8 次方)個字節長度,能夠理解成最大能夠存儲 255 個字符。在計算機中以 8 位二進制的方式存儲。安全

使用char類型存儲數據時,假設存儲的數據是 4,4 在計算機中存儲的結果是 0000 0100,意味着使用定長字符型char,無論你存儲的值是多少位,最終在計算機裏都是以 8 位二進制的方式存儲,不滿 8 位,前面補 0。超過 8 位,超出的部分會被去除。服務器

也就是說當使用char字符型存儲數據後,該數據轉換爲二進制時的長度超過了 8 位,那麼該數據將不會完整存儲,會「丟失」一部分數據。數據結構

varchar:不定長字符型,最大可存儲 65535(2 的 16 次方) 個字節長度,在計算機中以 16位 二進制的方式存儲。併發

它與char不一樣的地方在於,當字符長度在 0-255 之內時,會在後面添加一個字節,超過 255 時,添加兩個字節。一樣的,當超過最大存儲長度後,也會丟失一部分數據。函數

text:長文本數據類型,最大可存儲 65555 個字節長度,不能指定長度,也就是說不支持text(num)高併發

可是該類型儘可能不要使用,由於text類型數據在檢索中,不會使用索引,而是使用全局搜索,這會產生臨時表,使得檢索時間變長,不推薦使用。性能

因爲charvarchar的特性,在實際使用當中,若是該數據是常常會發生變化、常用的,那麼推薦使用char類型,由於 MySQL 在對數據進行排序時,會根據該數據的長度來排,固定長度的char類型會提供更高的性能。可是因爲固定長度的特性,在存儲短數據時,必定程度上也會形成資源浪費,算是一個雙刃劍。

2. varchar(100)中的 100 有什麼意義

100 只是在呈現角度上定義的,好比該數據有 120 個字符,那麼你在查詢該數據時,看到的只有 100 個。可是若是在定義時,添加了UNSIGNED ZEROFILL屬性,那麼這將改變該類型的最大存儲長度。

一樣的,在實際使用當中,varchar(num)裏的值不須要定義的特別長,只要夠用就行,具體緣由上面有提,這裏再也不贅述。

3. 說一說 DROP、DELETE、TRUNCATE 的區別

DORP:非事務操做,完全刪除一張表,沒法反悔恢復。

DELETE:事務操做,刪除表裏的一行或多行數據,若是反悔或是誤刪,能夠經過「事務回滾」恢復該表。不會影響該表下的view或索引。

TRUNCATE:非事務操做,刪除表裏的某行數據,或是刪除整張表的數據(表依然存在,只是成了一張空表)。沒法反悔恢復,而且會將該表下的view或索引重置。

執行速度:DROP > TRUNCATE > DELETE。

4. 說一說 MySQL 三範式

第一範式:表中的字段只能表達一種意思,不能模棱兩可。

第二範式:表必須含有一個惟一主鍵來標識這張表。

第三範式:表中的字段不能互相依賴。

5. 說一說 MySQL 中如何分區、分表

Scale Out(垂直切分)

Scale Up(橫向拆分)

這裏有篇文章值得看一看。MySQL 分區、分表

6. 瞭解索引嗎

若是把數據庫當作一本書的話, 那麼索引就是書的「目錄頁」,經過目錄,咱們能夠快速定位查找內容,一樣的,目錄頁在書中也佔了一頁紙,因此索引是一個數據結構,也要佔據數據庫物理內存。

索引分爲 4 種類型:普通索引、惟一索引、主鍵索引和全文索引(MyISAM 專有)。

索引的建立規則:常用的字段名,和出如今 where 後面的字段名,建議爲它們建立索引,索引要遵循最左前綴原則(最能體現該索引特徵,也就是經常使用的字段放最左邊)。

索引的原理:能夠看看這篇文章。索引

索引的使用場景:中等、大量數據時,使用索引效率會很是高,小型數據不建議使用索引,沒有全局搜索來的快。

索引的做用:索引能夠提升查詢速度。可是索引會增長數據庫存儲額外開銷。索引會將數據庫查詢時的隨機 I/O 變成順序 I/O,減小服務器排序操做,和臨時表的開銷。

7. 說一下經常使用的 MySQL 優化手段

  • 使用EXPLAIN查看 SQL 執行計劃,幫助本身查看哪些地方能夠優化。
  • 杜絕使用 SELECT * FROM xxx 這種查詢語句,須要什麼就查什麼。
  • 儘可能不要使用text這種類型,這會使得數據查詢該字段時,建立臨時表。
  • 明確知道查詢數據結果大概有幾行時,使用LIMIT,爲查詢結果限制顯示頁數。
  • 避免使用 MySQL 的內置函數。
  • 儘可能使用 EXISTSBETWEEN代替IN
  • 避免在 WHERE中使用表達式操做,這會使得 MySQL 放棄使用索引查詢。
  • 儘可能使用小表驅動大表(從小的表中,查找跟大表中有關係的數據),能夠減小 CPU 運算次數,以及 I/O 總量。
  • 儘可能使用INNER JOIN而不是LEFT JOIN,由於前者默認使用小表驅動大表。
  • 索引要遵循最左前綴法則。
  • 避免使用模糊查詢LIKE
  • 避免設置字段NULL屬性,在對NULL進行判斷時,會使得 MySQL 放棄使用索引。

8. InnoDB 和 MyISAM 的區別

  • InnoDB 支持外鍵,MyISAM 不支持。
  • MyISAM 擁有全文索引,InnoDB 沒有。
  • 數據庫崩潰後,InnoDB 能夠安全恢復,而 MyISAM 不能夠。
  • InnoDB 擁有事務,而 MyISAM 沒有。
  • InnoDB 擁有行鎖,而 MyISAM 擁有表鎖。
  • MyISAM 計算 COUNT(*)時,速度遠高於 InnoDB。

9.什麼是事務

InnoDB 引擎下,MySQL 支持事務操做,事務擁有如下幾個特色:

  • 原子性
  • 可靠性
  • 穩定性
  • 隔離性

使用事務的操做,要麼執行,要麼不執行,只有一個結果,可是事務能夠回滾,也就是撤回操做。

10.說一下悲觀鎖、樂觀鎖

InnoDB 引擎下的 MySQL 在處理高併發時,會對 MySQL 數據庫添加鎖機制,以此完成併發的要求,並保證數據的完整性,可靠性。

悲觀鎖是 MySQL 爲數據庫添加行鎖,強行爲多個事務排序,阻塞事務運行,解決事務之間的衝突問題,可是事務之間有可能出現長時間等待,且開鎖、解鎖須要額外的數據庫資源消耗。因此要謹慎使用。

樂觀鎖沒有鎖機制,可是引入了版本號控制,在高併發時,數據庫在事務提交以前會進行版本號校驗,若是版本後先後不一致,說明此刻有其餘事務正在操做,那麼本次事務從新操做。

版本號的好處在於沒有鎖的開銷,而且只在事務最後提交更改時進行判斷,可是也要考慮從新執行的代價是否過大。

總的來講,高併發下,讀操做多的時候,使用樂觀鎖,寫的操做時,使用悲觀鎖。

未更完,下次更新補上。

相關文章
相關標籤/搜索