MySQL知識點小結

2021-10-24 22:32:10 字數 4561 閱讀 4359

3.mysql事務

4.日誌

5.索引

6.大表優化

大多網際網路公司都在用mysql而不是oracle,所以就想將自己掌握的一點小知識做一下記錄。理解過於淺顯,簡稱入門級八股文。

mysql是一種開放源**的關係型資料庫管理系統(rdbms),使用最常用的資料庫管理語言–結構化查詢語言(sql)進行資料庫管理。

常見的儲存引擎包括innodb和myisam。

a)innodb儲存引擎

innodb是事務型資料庫的首選引擎,mysql5.5以後預設使用innodb儲存引擎。

innodb特點: 支援事務處理,支援外來鍵,支援崩潰修復能力和併發控制。如果需要對事務的完整性要求比較高(比如銀行),要求實現併發控制(比如售票),那選擇innodb有很大的優勢。

如果需要頻繁的更新、刪除操作的資料庫,也可以選擇innodb,因為支援事務的提交(commit)和回滾(rollback)。

b)myisam儲存引擎

myisam是在web、資料倉儲和其他應用環境下最常使用的儲存引擎之一。myisam擁有較高的插入、查詢速度,但不支援事務,不支援外來鍵。

myisam特點: 插入資料快,空間和記憶體使用比較低。如果表主要是用於插入新記錄和讀出記錄,那麼選擇myisam能實現處理高效率。如果應用的完整性、併發性要求比較低,也可以使用

1)innodb支援事務,myisam不支援事務;

2)innodb支援外來鍵,myisam不支援外來鍵;

3)innodb支援行鎖和表鎖,myisam僅支援表鎖;

4)innodb不儲存表的具體行數,myisam用乙個變數儲存了整個表的行數;

5)innodb儲存檔案有frm(表定義檔案)、ibd(資料檔案),而myisam是frm(表定義檔案)、myd(資料檔案)、myi(索引檔案);

6)innodb是聚簇索引,使用b+tree作為索引結構,資料和(主鍵)索引都存在葉子節點上,必須要有主鍵,通過主鍵索引效率很高。

myisam是非聚集索引但是輔助索引需要兩次查詢,先查找到主鍵,然後再通過主鍵查詢到資料(回表)。

mysql事務是為了保證一組資料庫操作,要麼全部成功,要麼全部失敗(事務是在引擎層實現的)

mysql預設開啟事務;

開啟事務:

set autocommit = 0; (0關閉自動提交 1自動提交)

begin; 或者 start transaction; 手動開啟事務,需commit;手動提交後才不可rollback回滾。

a:原子性 = 事務是最小的工作單位,不可再分;

c:一致性 = 同一事務中的sql,要麼全成功,要麼全失敗;

i:隔離性 = 事務之間互相隔離;

d:永續性 = 事務一旦提交,影響是持久的;

事務的隔離級別越高,效能越差。

未提交讀read uncommitted :當前事物可以讀取其他事物未提交的資料,容易導致髒讀;

讀已提交read committed :當前事物可以讀取其他事物已提交的資料,導致不可重複讀現象;

可重複讀(預設)repeaableread :同一事務內的select語句,多次讀取的結果是一致的,容易導致幻讀;

序列化讀serializable :多個事務操作同乙個表時,各事務按順序執行,其他事物堵塞,會鎖表,消耗資源,影響效率。

髒讀:事務a讀取了事務b更新的資料,然後b回滾操作,那麼a讀取到的資料是髒資料。

不可重複讀:事務 a 多次讀取同一資料,事務 b 在事務a多次讀取的過程中,對資料作了更新並提交,導致事務a多次讀取同一資料時,結果不一致。

解決辦法:mvvc(多版本併發控制),每一行資料都有多個版本,每個版本的記錄除了有資料本身外,還有乙個表示版本的事務id,根據時間先後順序遞增。

幻讀:幻讀是針對資料插入(insert)操作來說的。假設事務a對某些行的內容作了更改,但是還未提交,此時事務b插入了與事務a更改前的記錄相同的記錄行,並且在事務a提交之前先提交了,而這時,在事務a中查詢,會發現好像剛剛的更改對於某些資料未起作用,但其實是事務b剛插入進來的,讓使用者感覺出現了幻覺,這就叫幻讀。

解決辦法:間隙鎖,mysql 把行鎖和間隙鎖合併在一起,解決了併發寫和幻讀的問題,這個鎖叫做 next-key鎖。有索引的情況,如果不是索引列,那麼資料庫會為整個表加上間隙鎖。

redo log(重做日誌):在事務開始之後就會產生redo log,假如發生故障,導致尚有髒頁未寫入磁碟,那麼在重啟mysql服務的時候,根據redo log進行重做,從而達到事務的永續性這一特性。當對應事務的髒頁寫入到磁碟之後,redo log占用的空間就可以重用(被覆蓋)。

undo log(回滾日誌):undo是在事務開始之前儲存的被修改資料的乙個版本,產生undo日誌的時候,同樣會伴隨類似於保護事務持久化機制的redolog的產生。

可以用於回滾,同時可以提供多版本併發控制下的讀(mvcc),也即非鎖定讀,保證資料的原子性。

當事務提交之後,undo log並不能立馬被刪除,而是放入待清理的鍊錶,由purge執行緒判斷是否由其他事務在使用undo段中表的上乙個事務之前的版本資訊,決定是否可以清理undo log的日誌空間。

bin log(二進位制日誌):事務提交的時候,一次性將事務中的sql語句(乙個事物可能對應多個sql語句)按照一定的格式記錄到binlog中。

在主從複製中,從庫利用主庫上的binlog進行重播,實現主從同步。也可以用於資料庫的基於時間點的還原。

關於事務提交時,redo log和binlog的寫入順序,為了保證主從複製時候的主從一致(當然也包括使用binlog進行基於時間點還原的情況),是要嚴格一致的,mysql通過兩階段提交過程來完成事務的一致性的,也即redo log和binlog的一致性的,理論上是先寫redo log,再寫binlog,兩個日誌都提交成功(刷入磁碟),事務才算真正的完成。

在關聯式資料庫中,索引是一種單獨的、物理的對資料庫表中一列或多列的值進行排序的一種儲存結構,它是某個表中一列或若干列值的集合和相應的指向表中物理標識這些值的資料頁的邏輯指標清單。索引的作用相當於圖書的目錄,可以根據目錄中的頁碼快速找到所需的內容。

聯合索引:在乙個表的多列上建立索引,sql條件遵循最左字首原則走索引。

聚簇索引:聚簇索引的資料結構是b+樹,葉子結點儲存了索引和資料。每個表只能有乙個聚集索引。

非聚簇索引:非聚簇索引的資料結構是b+樹,將資料與索引分開儲存,葉子節點指向了資料對應的位置。

當通過非聚簇索引查詢資料時,需要兩個步驟:第一步在非聚簇索引b+樹中檢索,到達其葉子節點獲取對應的主鍵。

第二步使用主鍵在主索引b+樹種再執行一次b+樹檢索操作,最終到達葉子節點即可獲取整行資料。

回表:回表就是先通過索引掃瞄出資料所在的行,再通過行主鍵id取出索引中未提供的資料,即基於非主鍵索引的查詢需要多掃瞄一棵索引樹。

最左字首原則是針對聯合索引來說的,舉個栗子:

在a b c 三列建立聯合索引,相當於建立了 a、ab、ac、abc 索引,當條件為 a=?、a=? and b=?、a=? and c=?、a=? and b=? and c=?、c=? and b=? and a=? (sql優化器)時,都會走索引,但是當條件為 b=? and c=? 時,是不走該索引的。

當mysql單錶記錄數過大時,資料庫的crud效能會明顯下降,一些常見的優化措施如下:

6.1. 限定資料的範圍

禁止不帶任何限制資料範圍條件的查詢語句。

6.2. 讀/寫分離

經典的資料庫拆分方案,主庫負責寫,從庫負責讀;

6.3. 垂直分割槽

根據資料庫裡面資料表的相關性進行拆分。 例如,使用者表中既有使用者的登入資訊又有使用者的基本資訊,可以將使用者表拆分成兩個單獨的表,甚至放到單獨的庫做分庫。

垂直拆分的優點: 可以使得列資料變小,在查詢時減少i/o次數。此外,垂直分割槽可以簡化表的結構,易於維護。

垂直拆分的缺點: 主鍵會出現冗餘,需要管理冗餘列,並會引起join操作,可以通過在應用層進行join來解決。此外,垂直分割槽會讓事務變得更加複雜;

6.4. 水平分割槽

水平拆分是指保持資料表結構不變,將資料表行的拆分,就是把一張的表的資料拆成多張表來存放。舉個例子:我們可以將使用者資訊表拆分成多個使用者資訊表,這樣就可以避免單一表資料量過大對效能造成影響。

水平拆分可以支援非常大的資料量。需要注意的一點是:分表僅僅是解決了單一表資料過大的問題,但由於表的資料還是在同一臺機器上,其實對於提公升mysql併發能力沒有什麼意義,所以 水平拆分最好分庫 。

水平拆分能夠 支援非常大的資料量儲存,應用端改造也少,但 分片事務難以解決 ,跨節點join效能較差,邏輯複雜。

知識點小結

華為 1.c與c 哪個效能比較好?從語言特性角度上來看,c 是c的超集。在 c c的這部分語言特性中有很多會降低執行效率。乙個例子是dynamic cast,執行乙個dynamic cast要消耗100 300個cpu cycles,因為機器要跳到一段特別的snippet 一小段程式 去檢查type...

知識點小結

一 mysql計算日期 timestampdiff day,t3.payment due date,now 二 字段轉換 case when t1.status in d01 a01 a00 then 三 mybatis在插入資料時,返回id usegeneratedkeys true keypro...

unity知識點小結

1 通過gameobject.find 玩家物體 getcomponent 獲取玩家的player指令碼 2 quaternion.identity就是指quaternion 0,0,0,0 就是每旋轉前的初始角度,是乙個確切的值,而transform.rotation是指本物體的角度,值是不確定的...