天天看點

MySQL相關知識點整理

文章目錄

文章目錄

        • 一、資料庫的三範式
        • 二、一張自增表裡面總共有 7 條資料,删除了最後 2 條資料,重新開機 mysql 資料庫,又插入了一條資料,此時 id 是幾?
        • 三、如何擷取目前資料庫版本
        • 四、事務的四大特性(ACID) 是什麼?
        • 五、并發事務帶來的問題
        • 六、事務隔離等級,MySQL的預設隔離等級
        • 七、索引相關
          • 1> 索引是幹嘛用的?
          • 2> 資料庫的索引有哪些?
          • 3> 哪些不走索引?
          • 4> 索引具體采用的哪種資料結構
          • 5> B+ Tree索引和Hash索引差別
          • 6> MySQL的索引實作方式​

一、資料庫的三範式

  1. 第一範式:強調的是原子性,即資料庫表的每一列都是不可分割的原子資料項
  2. 第二範式:要求實體的屬性完全依賴于主關鍵字。
  3. 第三範式:任何非主屬性不依賴于其它非主屬性。

二、一張自增表裡面總共有 7 條資料,删除了最後 2 條資料,重新開機 mysql 資料庫,又插入了一條資料,此時 id 是幾?

  • 表類型如果是

    MyISAM

    ,那 id 就是 8。
  • 表類型如果是

    InnoDB

    ,那 id 就是 6。

    InnoDB

    表隻會把自增主鍵的最大 id 記錄在記憶體中,是以重新開機之後會導緻最大 id 丢失。

三、如何擷取目前資料庫版本

使用

select version()

擷取目前 MySQL 資料庫版本。

四、事務的四大特性(ACID) 是什麼?

  • Atomicity(原子性):一個事務(transaction)中的所有操作,或者全部完成,或者全部不完成,不會結束在中間某個環節。事務在執行過程中發生錯誤,會被恢複(Rollback)到事務開始前的狀态,就像這個事務從來沒有執行過一樣。即,事務不可分割、不可約簡。
  • Consistency(一緻性):在事務開始之前和事務結束以後,資料庫的完整性沒有被破壞。這表示寫入的資料必須完全符合所有的預設限制、觸發器、級聯復原等。
  • Isolation(隔離性):資料庫允許多個并發事務同時對其資料進行讀寫和修改的能力,隔離性可以防止多個事務并發執行時由于交叉執行而導緻資料的不一緻。事務隔離分為不同級别,包括讀未送出(Read uncommitted)、讀送出(read committed)、可重複讀(repeatable read)和串行化(Serializable)。
  • Durability(持久性):事務處理結束後,對資料的修改就是永久的,即便系統故障也不會丢失。

五、并發事務帶來的問題

​ 在實際項目中,多個事務操作相同的資料來完成各自的任務,因為并發會造成以下問題:

  • 髒讀: 當一個事務正在通路一個資料,并對這個資料進行修改,但是這個修改的事務還未送出,此時另外以一個事務通路該資料,然後使用該資料,由于這個資料是未送出的資料,那麼第二個事務通路的該資料就是

    髒資料

    ,對髒資料的操作可能是不正确的。
  • 丢失修改: 第一個事務在讀取一個資料,第二個事務也在讀取這個資料,那麼第一個事務在修改這個資料後,第二個事務也修改了這個資料,那麼第一個事務修改結果就會被丢失。例如:事務1 讀取表中資料A = 20 ,事務2 也讀取表中資料A = 20,事務1 做出修改 A = A - 10,之後事務2 做出修改 A = A - 1,最終結果A = 19,事務1的修改就丢失了。
  • 不可重複讀: 一個事務内多次查詢同一條資料,這個事務還結束前,第二個事務修改了這條資料,導緻第一個事務兩次讀取同一條資料,但讀取資料的結果可能不一緻,這種現象被稱為“不可重複讀”
  • 幻讀: 幻讀和不可重複讀相似,第一個事務讀取了幾行資料,事務尚未結束前,第二個事務插入幾行資料,在第一事務随後的查詢中,會發現多了幾行資料,就好像幻覺一樣,被稱為“幻讀”

注意:

​ 不可重複讀和幻讀的差別: 不可重複讀的重點是

修改

,幻讀的重點是

新增或删除

六、事務隔離等級,MySQL的預設隔離等級

  • READ-UNCOMMITTED

    (讀取未送出): 最低的隔離級别,允許讀取尚未送出的資料變更,可能會導緻髒讀、幻讀或不可重複讀;
  • READ-COMMITTED

    (讀取已送出): 允許讀取并發事務已經送出的資料,可以阻止髒讀,但是幻讀或不可重複讀仍有可能發生;
  • REPEATABLE-READ

    (可重複讀): 對同一字段的多次讀取結果都是一緻的,除非資料是被本身事務自己所修改,可以阻止髒讀和不可重複讀,但幻讀仍有可能發生;
  • SERIALIZABLE

    (可串行化): 最高的隔離級别,完全服從ACID的隔離級别。所有的事務依次逐個執行,這樣事務之間就完全不可能産生幹擾,也就是說,該級别可以防止髒讀、不可重複讀以及幻讀;
隔離級别 髒讀 不可重複讀 幻影讀
READ-UNCOMMITTED
READ-COMMITTED ×
REPEATABLE-READ × ×
SERIALIZABLE × × ×

MySQL可以通過以下指令查詢目前資料庫的隔離等級:

SELECT @@transaction_isolation;
           

注意:

InnoDB

存儲引擎的預設支援的隔離級别是 REPEATABLE-READ(可重讀) 已經可以完全保證事務的隔離性要求,即達到了 SQL标準的 SERIALIZABLE(可串行化) 隔離級别。

​ 因為隔離級别越低,事務請求的鎖越少,是以大部分資料庫系統的隔離級别都是READ-COMMITTED(讀取送出内容) ,但是你要知道的是

InnoDB

存儲引擎預設使用 REPEATABLE-READ(可重讀) 并不會有任何性能損失。

InnoDB

存儲引擎在 分布式事務 的情況下一般會用到SERIALIZABLE(可串行化) 隔離級别

七、索引相關

1> 索引是幹嘛用的?

​ 主要為了提高查詢效率。

2> 資料庫的索引有哪些?

​ 1、 聚集索引(主鍵索引):在資料庫裡,是以行數都會按照主鍵索引進行排序

​ 2、 非聚集索引:普通字段加上索引

​ 3、 聯合索引: 幾個字段聯合組成的索引

​ 主要解釋一下聯合索引:

-- 添加索引
ALTER TABLE `student` 
ADD UNIQUE INDEX `idx_age_name_sex`(`age`, `name`, `sex`) USING BTREE;
           

​ 聯合索引遵從最左字首原則

A:select * from student where age = 16 and name = '小張'
B:select * from student where name = '小張' and sex = '男'
C:select * from student where name = '小張' and sex = '男' and age = 18
D:select * from student where age > 20 and name = '小張'
E:select * from student where age != 15 and name = '小張'
F:select * from student where age = 15 and name != '小張'
           

​ A:遵從最左比對原則,age在最左邊,是以A走索引;

​ B:直接從name開始,沒有遵從最左比對原則,是以B不走索引;

​ C:雖然從name開始,但是檢索條件中存在有最左邊索引的age,MySQL内部會自動轉成

where age = 18 and sex = '男' and name = '小張'

,遵從了最左比對原則,是以C走索引;

​ D:因為age > 20 是範圍,範圍字段會結束索引對範圍後面索引字段的使用,是以隻對age 走索引;

​ E:因為 != 不走索引,是以E不走索引;

​ F:隻有age 走索引,原因同上;

3> 哪些不走索引?
-- 添加索引
ALTER TABLE `student` 
ADD UNIQUE INDEX `idx_age`(`age`) USING BTREE,
ADD UNIQUE INDEX `idx_name`(`name`) USING BTREE;
           

​ 1、Like這種就是%在前面的走索引,在後面的不走索引

A:select * from student where 'name' like '王%'		-- 不走索引
B:select * from student where 'name' like '%小'		-- 走索引
           

​ 2、用索引列進行計算的,不走索引

A:select * from student where age = 10+8			-- 走索引
B:select * from student where age + 8 = 18			-- 不走索引
           

​ 3、對索引列用函數的,不走索引

A:select * from student where  concat('name','哈') ='王哈哈';		-- 不走索引
B:select * from student where name = concat('王哈','哈');			-- 走索引
           

​ 4、索引列用了

!=

不走索引

select * from student where age != 18		-- 不走索引
           
4> 索引具體采用的哪種資料結構

​ MySQL常用資料結構為 hash索引 和 B+樹索引

5> B+ Tree索引和Hash索引差別
  • 哈希索引适合等值查詢,但是無法進行範圍查詢
  • 哈希索引沒辦法利用索引完成排序
  • 聯合索引中,Hash索引不能利用部分索引鍵查詢
  • 如果有大量重複鍵值的情況下,哈希索引的效率會很低,因為存在哈希碰撞問題
6> MySQL的索引實作方式​

​ 1、

MyISAM

索引實作( B+Tree )-非聚集索引

​ 主索引:主鍵唯一

​ 表要求:表可以沒有主鍵

​ 2、

InnoDB

索引實作 ( B+Tree ) -聚集索引

​ 主索引:主鍵唯一

​ 表要求:表必須有主鍵