事務:
ACDI:
原子性(atomicity):指事務是一個不可分割的工作單位,事務中的操作要麼都發生,要麼都不發生。
一致性(consistency):事務必須使數據庫從一個一致性狀態變換到另外一個一致性狀態,數據一致(如 轉賬總數不變)。
持久性(durability):一個事務一旦被提交,所做的修改就會永久保存到數據庫中,無法回滾。
隔離性(isolation):一個事務所做的修改在最終提交之前,對其他事務是不可見的。
隔離級別:
讀未提及(READ-UNCOMMITTED):從一個事務讀取另一個未提交的事務,會存在髒讀現象
讀已提交(READ-COMMITTED):在一個事務A中新增或修改記錄時,提交之前,在另一個事務B中是查詢不到改動記錄的,當事務A提交後,事務B中查詢得到變化,存在不可重複讀(兩次讀不一致,可通過鎖行解決)和幻讀問題
可重複讀(REPEATABLE-READ,mysql默認):從一個事務A中修改一條數據,另一個事務B中查詢,在事務A提交之前讀取的都是修改之前的記錄,重複讀取得到的記錄是一樣的,解決了不可重讀。當從一個事務A中新增一條數據並提交,在另一個事務B查詢看不到新增記錄,當update表時(條件要能包含新增的記錄),在查詢,可以看到記錄,稱之爲幻讀(可通過鎖表解決)。
串行化(SERIALIZABLE):不支持併發,事務串行化順序執行,可以避免髒讀、不可重複讀、幻讀,但是性能很低
事務傳播行爲:
PROPAGATION_REQUIRED:如果存在一個事務則支持當前事務,否則開啓一個新的事務。spring默認事務傳播特性
PROPAGATION_SUPPORTS:如果存在一個事務則支持當前事務,否則不開啓事務
PROPAGATION_MANDATORY:如果存在一個事務則支持當前事務,否則拋異常
PROPAGETION_REQUIRES_NEW:總是開啓一個新的事務,將舊事務掛起
PROPAGETION_NOT_SUPPORTED:總是非事務的執行,並掛起任何存在的事務
PROPAGATION_NEVER:總是非事務的執行,如果存在活動事務則拋出異常
PROPAGATION_NESTED:如果一個活動事務存在,則運行在一個嵌套的事務中,如果沒有活動事務,則按照PROPAGETION_REQUIRED屬性執行
索引:
索引類型:
普通索引:查詢效率高
唯一索引:查詢效率高且列值唯一(可以有null)
主鍵索引:查詢效率高且列值唯一(不能有null)且一張表只有一個主鍵索引
組合索引:多列值組成一個索引,專門用於組合搜索,其效率大於索引合併(使用多個單列索引組合搜索)
全文索引:對文本的內容進行分詞,進行搜索
索引分類:
HASH:
僅能滿足 等於 和 in 操作,不能使用範圍查詢
無法處理排序運算
對於組合索引,無法使用部分索引,是根據全量組合索引算出的hash值
hash索引不能避免表的掃描,查找後還要通過訪問表中的實際數據進行比較纔得到結果
hash碰撞比較大的時候性能會降低,可能會比B-Tree索引效率低
BTREE:
是B+樹(所有數據都存放在子節點)
在INNODB中有兩種形態,如果是主鍵的話,子節點存放的數據包含索引鍵的數據以及其他字段數據,否則只存放主鍵的值
MyISAM裏,子節點存放的是指向數據文件裏的對應數據行信息
FULLTEXT:
全文索引,目前只有MyISAM引擎支持,且只有CHAR、VARCHAR、TEXT上可以創建全文索引
RTREE:
僅支持geometry(幾何對象)數據類型,優勢在於範圍查找
mysql引擎:
常用四種,在5.6版本支持的有八種 ,可以用show engines查看支持的引擎
MyISAM:
擁有較高的查詢、插入速度,有單獨變量記錄整表的行數,支持全文索引,可以索引blob和text列,但不支持事務,不支持外鍵、不支持行鎖
InnoDB:
支持事務、行鎖、外鍵,查詢整表記錄時需要掃描全表,不支持全文索引、不支持blob和text列,存儲大小是MyISAM(256TB)的四分之一(64TB)
聚簇索引(主鍵的索引):一個表只能有一個聚簇索引,葉子結點記錄的是行數據。耗費空間但查詢的快
非聚簇索引(二級索引):葉子結點保存的數據是主鍵的值,在通過主鍵的值去聚簇索引中查找數據
Memory:
將表中的數據存儲到內存中,支持包含null列的索引,通常只存放臨時數據,數據量不大且不需要較高的安全性
Archive:
如果只有INSERT和SELECT操作,可以使用Archive,支持高併發的插入操作,單本身不是事務安全的,適用於存儲歸檔數據,比如記錄日誌信息
主鍵:
如果定義主鍵,InnoDB會選擇主鍵作爲聚集索引
如果沒顯示定義主鍵,InnoDB會選擇第一個不包含null值的唯一索引作爲主鍵
如果沒有上面的索引,InnoDB會選擇內置的6字節長的rowID作爲隱含的聚集索引
如果使用自增主鍵,每次插入新的記錄,B+Tree會順序在後面添加,如果使用非自增主鍵,插入則是隨機的,會頻繁移動節點位置
視圖:
也被稱作虛表,是一組數據的邏輯表示形式,本質是一條select語句,本身不包含任何數據,只展現映射到基表的數據
可以通過視圖限制數據訪問,以及簡化複雜操作查詢,create view as select * ...,使用視圖如表一樣,對於增刪改有如下限制:
如果基表中有非空列,且對視圖不可見,無法insert;
如果視圖中包含函數、表達式、分組、distinct、rownum等,不允許DML操作;
通過join的無法刪除或新增(親測)
存儲過程、觸發器、函數:
存儲過程:在創建時進行編譯,提高執行速度;可以將複雜邏輯進行封裝。在不同數據庫中移植性差且會使業務邏輯更復雜,增加系統維護難度
函數:提高重用性|可讀性以及sql的可移植性,無需修改sql即只保證函數正確即可。可以提高執行速度減少網絡流量。
觸發器:包含DML(insert update delete)觸發器和DDL(create alter drop)觸發器;而且包含DML完成後觸發以及替代DML操作。DDL沒有替代操作
union\union all:
必須保證各個select的結果有相同個數的列且類型相同
union: 對兩個結果集進行並集操作,會去重,同時進行默認規則的排序
union all:對兩個結果集進行並集操作,不會去重,不進行排序
char\varchar:
varvhar\char裏面的數字在4.0版本以下指的是字節(每個漢字3字節),5.0版本以上指的是字符,varchar最大是65532字節(兩個字節存長度)
如果字符類型爲gbk,每個字符最多佔兩個字節,如果是utf8則每個字符最多佔三個字節。
行長度限制是65535,即一條記錄所有字段加起來的總和。
char:定長,效率高。範圍是0-255。保存char值時,會將小於長度的右側進行空格填充,比較佔用空間
varchar:不定長,效率偏低。最長是64K,包含其他列,是可變字符串,多餘一兩個字節記錄長度
blob:需要1-4個字節記錄值的長度,超大會被截斷,可以存儲二進制大對象,比如圖片。排序大小寫敏感
text:需要1-4個字節記錄值的長度,排序大小寫不敏感。
分頁:
mysql:
使用limit,如limit 0,20 從第一條開始,查詢20條記錄。第一個參數是起始索引,第二個參數是查詢的記錄數。如果只有一個的話,則代表查詢前多少條。
oracle:
使用rownum,在無order by時需要兩層嵌套,有order by時需要三層嵌套。ID從1開始,且使用 > 或 between..and.. 。
不允許大於比較的原因是:
rownum是對結果集加的一個僞列,是符合條件的結果的序號。當使用> 時,先查出來結果集,然後判斷條件> n時,第一行的rownum是1 不符合,然後第二行地rownum設置1 不符合,以此類
推,所以大於的就得不到記錄,只有>=1 這種情況應該是沒問題的(推測),但是下次換頁就有問題了。
不使用order by則需要兩層,使用order by則需要三層。示例如下:
select tab.* from (select rownum as rowid, u.* from user u where rownum<=20) tab where tab.rowid >=11
select tab.* from (select rownum as rowid, u.* from (select * from user order by id) u where rownum<=20) tab where tab.rowid >=11
排序:
多個排序字段逗號分隔
asc: 升序,從小到大,默認排序方式
desc: 降序,從大到小
連接:
內連接:只匹配連接的行 A join B on
左外連接:包含左邊的全部行及右表中匹配的行 A left (outer) join B on
右外連接:包含右邊的全部行及左表中匹配的行 A right (outer) join B on
全外連接:包含左右兩表的全部行 A full (outer) join B on
交叉連接:生成笛卡爾積,沒有條件 A join B
範式:
第一範式:
確保每列保持原子性,即所有字段都是不可分解的原子值,比如要把地址拆成省份、城市、詳細地址等。
第二範式:
確保表中的每列都和主鍵相關,即一個表中只能保存一種數據,比如訂單和商品聯合主鍵,保存的信息不能包含訂單和商品的信息,需要拆分出來一個商品表和關係表
第三範式:
確保每列都和主鍵列直接相關,而不是間接相關,比如訂單表裏要包含用戶的信息,通過用戶ID進行外鍵關聯,不能再包含用戶名的信息
sql優化:
where的執行順序是從右到左的,應再最右側使用能過濾掉大部分記錄的條件
from後的表管理是從右向左解析的,大表放在右邊
select 查詢條件使用具體的值來代替*,減少多餘字段網絡傳輸
避免頻繁創建和刪除臨時表,減少系統資源的消耗
刪除臨時表時可以先truncate table 後drop table,避免表鎖定時間長
避免大事務操作,可以提高系統併發能力
適當建立索引,可以在頻繁頻繁查詢但修改較少的地方增加索引
索引失效的原因:
對索引列判null,會放棄使用索引進行全表掃描
類型不匹配會放棄使用索引進行全表掃描
使用!= <> 會放棄使用索引進行全表掃描,主鍵索引應該還會使用
使用or連接條件會放棄使用索引進行全表掃描,可以用union all替換,or 兩側都是使用索引應該是會使用索引的
使用in\not in 需要注意,需要in裏的類型和字段類型一致,不一致的話普通索引會失效,普通索引對not in不生效
like在左側不使用%還會用到索引
在=號左側使用函數、表達式、算術運算會放棄使用索引進行全表掃描
複合索引匹配最左邊,遇到範圍查詢列之後索引失效(a=2 and b between 1 and 2 and c=3 複合索引abc c 不會使用索引)排序也會使用索引,與where後順序無關
臨時表:
創建時增加 TEMPORARY 關鍵字,當斷開連接時自定刪除表並釋放空間
注意點:
like使用的通配符 %代表匹配任意多 _ 代表匹配一個字符
count(列) 不計算包含null值的
使用B+tree不是Btree因爲B+樹的深度一定,查詢更穩定,且磁盤讀寫代價更低(內部節點沒有存放數據信息,節點更小,在單位範圍內存儲的節點數量更多,樹深度更低)
主從複製:
複製方式:同步複製(效率低下,基本沒用)、異步複製(效率高,msql默認配置)、半同步複製(保證有一個slaves操作成功即返回)
主節點掛掉:可以通過在應用程序內配置數據庫的域名,當主掛掉將子節點升級爲master,並將原master域名指向新的master, 重新建立連接。
讀寫分離:主寫從讀,配置多數據源
分庫分表:垂直分庫(按業務模塊按表拆分出來),水平分表(依據數據關係,把同一個表的數據拆分到各個庫,比如按ID取餘)
oracle有分區表,按時間或數量進行分區,不要和分表搞混
事務一致性:
CAP(帽子)理論:
C(Consistency):一致性。多個副本能保證數據一致的特性
A(Availability):可用性。服務一致處於可用狀態,不會中斷,必須在有限的時間內返回結果
P(Partition tolerance):分區容錯性。分佈式系統在遇到任何網絡分區故障的時候仍然可以對外提供服務,比如數據庫分區,某一個區
的網絡被隔離,仍然可以提供其他分區的服務。(一般來說是必須的)
一個分佈式系統不可能同時滿足這三個特性,最多隻能同時滿足兩個
CA : 當數據庫只有一個時,可以保證數據一致性可可用性,當網絡把數據庫隔離時,滿足不了分區容錯
CP:即保證數據強一致,當出現阻塞時會導致可用性不滿足
AP:即不保證數據強一致時,不會出現阻塞狀態,可以保證系統的可用性
BASE理論:
BA (Basically Available 基本可用):出現不可預知的錯誤後還是能用,比如時間變長或降級等
S (Soft state 軟狀態):允許存在中間狀態的數
E (Eventually consistent 最終一致性):不能一直處於軟狀態,最終要達到數據一致
XA:
是一個兩階段提交的協議,大部分商業數據庫都實現了XA的接口
第一階段:事務協調器要求每個涉及到事務的數據庫預提交(procommit)此操作,並反映是否可以提交
第二階段:事務協調器要求每一個數據庫提交數據
2PC:
犧牲了一些性能儘量保證數據是一致的
準備階段:事務協調者向所有參與者詢問是否可以提交事務,等待參與者答覆,如果參與者超時,則認爲是NO
提交階段:當所有參與者均反饋YES,則向所有參與者發起提交請求,參與者提交事務並反饋結果。當存在參與者反饋NO時,向所有
參與者發起回滾請求,參與者回滾到undo狀態,並反饋結果,等待反饋結果會存在阻塞狀態
3PC:
CanCommit: 與2PC的準備階段相似,詢問參與者是否可以提交事務,等待回覆,超時則認爲NO
PreCommit: 當所有參與者反饋YES,則發起預提交,參與者執行事務請求並記錄到undo和redo中但不提交,反饋結果,參與者阻塞等待協調者請求,等待超時則認爲是commit
DoCommit: 當所有參與者都PreCommit都反饋成功,下發DoCommit(commit\rollback),等待結果,超時則認爲成功,參與者接收到請求執行commit或rollback
解決了2PC中提交階段的阻塞問題,以及協調者單點故障的問題
TCC:
Try: 主要做業務的檢查以及資源預留
Confirm: 做確認提交的邏輯,Try執行成功後開始執行Confirm,默認Confirm階段不會出錯的
Cancel:業務執行錯誤時,需要回滾執行業務的取消,Try中的預留資源的釋放
屬於應用層的一種補償方式,需要寫好多補償代碼
本地消息表:
分佈式時,在各個數據庫中維護一張本地的消息表,通過各個本地事務保證局部一致,在通過消息隊列進行發送消息異步通知,保證最終一致性