資料庫雜記

hatch發表於2018-04-24

正規化

資料庫正規化有

一正規化:欄位不可以再分
二正規化:要有主鍵,其他欄位都依賴於主鍵
三正規化:消除傳遞性依賴,消除冗餘
複製程式碼

三正規化是用來學習參考的,設計時候根據實際情況,不一定要遵守

資料庫事務和隔離級別

資料庫事務,在一個事務中所有操作要麼都執行失敗,要麼執行失敗回滾。

事務有ACID特性

A:原子性,即一個事務是不可分割的一個原子單位
C:一致性。資料庫的資料總能從一個一致性狀態轉到另一個一致性狀態。比如你給小明轉了200塊,你和小明在銀行的總的錢是一致的
I:隔離性:一般來說,一個事務裡的操作對其他事務是不可見的
D:永續性:一旦事務已提交,對資料庫的修改是持久的
複製程式碼

隔離級別: 事務隔離級別規定了一個事務的修改,對事務內和事務間哪些是可見的,哪些是不可見的。級別越低的隔離級別,其併發性更高,系統開銷更低

未提交的讀:一個事務可以讀到另一個事務沒有提交的資料,可能產生髒讀
提交的讀:一個事務只能讀到另一個事務已經提交的資料,可能產生不可重複讀,大多數資料庫系統的預設隔離級別是提交讀
可重複讀:同一個事務中多次讀得資料時一致的,但是如果當事務查詢一個範圍內的資料,而其他事務又插入了新行,則就可能產生幻讀,MVCC來解決這個問題。MySQL預設隔離級別是可重複讀
序列:事務排隊一個一個的執行
複製程式碼

為什麼需要鎖,鎖的分類,鎖的粒度

多個執行緒對於同一資源的操作,併發操作可能會導致資料的不一致,所以需要通過加鎖來保證資料的正確性。

資料庫是多使用者使用的共享資源。多個使用者併發的存取資料庫時,資料庫中就會產生多個事務同時存取同一資料的請求,若不加以併發控制,或導致資料的一致性。

資料庫使用鎖是為了共享資料的併發訪問控制,提供資料的完整性和一致性

鎖分類

共享鎖  S Lock,允許事務讀一行的資料
排他鎖 X Lock,允許事務刪除或更新一行資料
複製程式碼

鎖的粒度

行級鎖
表鎖
複製程式碼

樂觀鎖,悲觀鎖的概念及實現方式

樂觀鎖

比較樂觀,總是認為不會發生併發問題。每次去取資料時總是認為其他執行緒不會對資料進行修改。所以不會上鎖,但是在更新時會去判斷其他執行緒在這之前是否對其進行了修改。

version方式:

資料庫表中加上一個版本號,表示資料被修改的版本,資料被修改時,版本號會增加。當執行緒讀取資料時,也會讀取版本,更新會判斷版本號是否為讀時的版本號,若不等,則說明被其他執行緒修改過,這時可以可以放棄修改或者重試更新直至成功

update table set x=x+1,version = version+1 where id =1 and version = #{version}
複製程式碼

CAS方式:

compare and swap或compare and set。更新新值時判斷舊值和資料庫裡的現有值是否相等,相等則更新,不等則自旋直至成功
複製程式碼

悲觀鎖

總是悲觀的,每次拿資料時,總是認為別人會修改資料,所以在拿資料的時候就會加上鎖。當其他執行緒想要訪問資料時,則會阻塞掛起。

select ... for update

mysql如何實現分頁

資料量比較少的時候,我們可以使用

select * from table where xx limit offset,size
複製程式碼

其實limit offset, size 是取前面的offset+size的資料,然後丟掉前面offset的記錄,取Size大小的資料返回,如果offset越來越大,併發查詢,每次查詢掃描的資料越來越多,效能會越來越差

select * from table where  id>10 order by asc limit size
複製程式碼

這類查詢每次只會掃size。雖然掃描的資料量少了,但是在某些需要跳轉到多少也得時候就無法實現

mysql引擎

mysql的核心就是儲存引擎。

資料庫管理系統利用資料引擎進行建立、查詢、更新和刪除資料。

不同的儲存引擎提供不同的儲存機制、索引技巧和鎖的功能。

SHOW ENGINES

InnoDB引擎

innodb引擎提供對資料庫ACID事務的支援,提供了行鎖和外來鍵的約束,設計目標就是處理大資料量容量的資料庫系統。不支援全文搜尋。

當使用事務時,該引擎就是首選的。鎖的粒度比較小。寫操作是不會鎖表的。在併發比較高的場景下會提升效率

innodb引擎是預設的Mysql引擎。

儲存引擎是基於表,不是基於資料庫的

Innodb支援事務、目標面向線上事務處理的應用,特點行級鎖、支援外來鍵,支援非鎖定讀,即預設讀取操作不會產生鎖。從mysql5.5.8開始,innodb引擎就是預設的儲存引擎

innodb通過多版本併發控制mvcc獲得高併發性,並且實現了sql的4個隔離級別,預設是可重複讀級別。同時使用 next-key-locking的celve避免幻讀

另外還提供了插入快取、二次寫、自適應雜湊索引、預讀

innodb採用可聚集方式儲存資料,因此每張表的儲存都是按主鍵順序存放。若沒有顯示的在表定義時指定主鍵,inndb會為每行生成一個6位元組的rowid,並以此為主鍵。
複製程式碼

myisam引擎

不支援事務、表鎖設計、支援全文索引、面向olap資料庫應用【聯機分析處理】

快取池只快取索引檔案,而不是快取資料檔案
複製程式碼

memroy引擎

預設使用雜湊索引,只支援表鎖、併發性差,不支援Text和blob型別
複製程式碼

InnoDB引擎對FULLTEXT索引的支援是MySQL5.6新引入的特性,之前只有MyISAM引擎支援FULLTEXT索引

MySQL語句優化

mysql提供了一個explain命令,可以對select語句進行分析,並輸出select執行的詳細資訊,供開發人員針對性優化

id

select查詢的識別符號,每個select都會自動分配一個唯一的標識
複製程式碼

select_type

select查詢的型別

SIMPLE:表示此查詢不包含UNION查詢或子查詢
PRIMARY,表示此查詢是最外層的查詢
UNION:表示此查詢時UNION的第二或隨後的查詢
SUBQUERY:子查詢的第一個select

最常見的查詢型別就是simple
複製程式碼

table

查詢的哪張表
複製程式碼

partitions:

匹配的分割槽
複製程式碼

possible_keys

此次查詢可能用到的索引
複製程式碼

type

join型別

這個欄位比較重要,提供了判斷查詢是否高效的依據,通過type,可以判斷此次查詢時全表掃描還是索引掃描

常用型別

system:表中只有一條資料,這個型別是特殊的const型別

const:針對主鍵或唯一索引的等值查詢,最多隻返回一行資料。查詢速度非常快,僅讀一次即可

eq_ref:此類查詢通常出現在多表join查詢,表示對於前表的每一個結果,都只能匹配到後表的最後一行。並且查詢的比較操作通常是=,查詢效率高

ref:  此型別通常出現子啊多表的join查詢,針對非唯一索引或非主鍵索引,或者使用了最左字首規則的索引查詢

range:表示使用索引範圍查詢,通過索引欄位範圍獲取表中部分資料記錄,通常出現在=、<>、>、>=、<、<=、is null、between、in()操作中

index:表示全索引掃描,和ALL型別類似,只不過ALL型別是全表掃描,index是掃描所有的索引,而不是資料。index經常出現在所要查詢的資料直接在索引樹中就可以獲取到,而不需要掃描資料。這種情況時。Extra會顯示Using index

ALL:全表掃描,這個型別的查詢時效能最差的查詢之一。這種查詢在資料量大的情況下,對資料庫的效能是巨大的災難。

type效能比較:ALL<index<range-index~index_merge<ref<eq_ref<const<system
複製程式碼

key

此次查詢用到的索引
複製程式碼

key_len

表示查詢優化器使用了索引的位元組數,這個欄位可以評估組合索引是否被完全使用,或只有最左部分被適應
複製程式碼

ref

哪個欄位和常數與key一起被使用
複製程式碼

rows

顯示此查詢一共掃描了多少行,估計值,原則上rows越少越好
複製程式碼

filtered

顯示此查詢條件所過濾資料的百分比
複製程式碼

extra

額外的資訊。常見的有Using filesort,表示MySQL需要額外的排序操作,不能通過索引順序達到排序結果。一般有Using filesort,都建議優化去掉,這樣的查詢CPU消耗大;

Using index 覆蓋索引掃描,表示查詢在索引樹中就可以查到所需的資料,不用掃描表資料檔案,通常效能不錯

Using temporary 查詢有使用臨時表,一般出現於排序,分組合奪標join的情況,查詢效率不高,建議優化。
複製程式碼

內連線,左連線,右連線作用及區別

左連線:

左邊有的,右邊沒有的為null,以左邊的為準
複製程式碼

右連線:

左邊沒有的,右邊有的為null,以右邊的為準
複製程式碼

內連線:

顯示左邊右邊共有的
複製程式碼

資料庫連線池

資料庫連線池是程式啟動時建立足夠的資料庫連線,並將這些連線組成一個連線池,有程式動態的對池中連線進行申請、使用、釋放

傳統連線資料庫的方式:

1、裝載資料庫驅動
2、通過jdbc建立資料庫連線
3、訪問資料庫、執行sql語句
4、斷開連線
複製程式碼

使用資料庫連線池連線資料庫

1、程式初始化時建立連線池
2、使用時向連線池申請可用的連線
3、使用完畢,歸還連線到池中
4、程式退出,斷開所有連線,並釋放資源
複製程式碼

為何使用資料庫連線池

訪問量大,資料庫伺服器為每次連線都建立一次資料庫連線,極大浪費資料庫資源,並容易造成資料庫服務記憶體溢位,當機等

資料庫連線時一種昂貴的資源
複製程式碼

相關文章