概念
是一個開源的關系型數據庫。
數據庫事務及其特性
事務:是一系列的數據庫操作,是數據庫應用的基本邏輯單位。
事務特性:
(1)原子性:即不可分割性,事務要么全部被執行,要么就全部不被執行。
(2)一致性。事務的執行使得數據庫從一種正確狀態轉換成另一種正確狀態
(3)隔離性。在事務正確提交之前,不允許把該事務對數據的任何改變提供給任何其他事務,
(4) 持久性。事務正確提交后,其結果將永久保存在數據庫中,即使在事務提交后有了其他故障,事務的處理結果也會得到保存。
數據庫三范式
第一范式(1NF)無重復的列(原子性)
第二范式(2NF)屬性完全依賴于主鍵
第三范式(3NF)屬性不依賴于其它非主屬性
sql語句在mysql中的執行過程
客戶端發起sql請求,與MySQL服務器建立連接,如果是select會先查詢緩存(mysql8刪除),沒有命中緩存進入分析器,解析處理,更新前記錄下log,用于事務回滾。然后判斷記錄是否存在緩沖池中,查詢存在直接返回,更新存在判斷存在沖突。最后提交事務。
常見優化方式
a. 設計良好的數據庫結構,允許部分數據冗余,盡量避免join查詢,提高效率。
b. 選擇合適的表字段數據類型和存儲引擎,適當的添加索引。
c. mysql庫主從讀寫分離。
d. 找規律分表,減少單表中的數據量提高查詢速度。
e. 添加緩存機制,比如memcached,apc等。
f. 不經常改動的頁面,生成靜態頁面。
g. 書寫高效率的SQL。比如 SELECT * FROM TABEL 改為 SELECT field_1, field_2, field_3 FROM TABLE.
mysql事務隔離級別
1、串行讀 (Serializable)
2、可重復讀 (RR默認)
確保同一事務的多個實例并發讀取數據時,會看到同樣的數據行,解決了不可重復讀的問題。
3、讀已提交 (RC)
一個事務只能看見已經提交事務所做的改變。可避免臟讀的發生。
4、讀未提交 (Read uncommitted)
所有事務都可以看到其他未提交事務的執行結果。
臟讀:讀到了臟數據,即無效數據。
不可重復讀:是指在數據庫訪問中,一個事務內的多次相同查詢卻返回了不同數據。
幻讀:指同一個事務內多次查詢返回的結果集不一樣,比如增加了行記錄。
- 臟讀是指在一個事務處理過程里讀取了另一個未提交的事務中的數據。
- 不可重復讀是指在對于數據庫中的某行記錄,一個事務范圍內多次查詢卻返回了不同的數據值,這是由于在查詢間隔,另一個事務修改了數據并提交了。
- 幻讀是當某個事務在讀取某個范圍內的記錄時,另外一個事務又在該范圍內插入了新的記錄。對幻讀的正確理解是一個事務內的讀取操作的結論不能支撐之后業務的執行。假設事務要新增一條記錄,主鍵為id,在新增之前執行了select,沒有發現id為xxx的記錄,但插入時出現主鍵沖突,這就屬于幻讀,讀取不到記錄卻發現主鍵沖突是因為記錄實際上已經被其他的事務插入了,但當前事務不可見。
- 不可重復讀和臟讀的區別是,臟讀是某一事務讀取了另一個事務未提交的臟數據,而不可重復讀則是讀取了前一事務提交的數據。
innodb和myisam的區別?
InnoDB支持行鎖、事務處理、外鍵、安全恢復,MyISAM不支持
InnoDB必須有主鍵,MyISAM可以沒有
建立索引需要考慮什么?
1、選擇合適的字段建立索引
根據查詢頻率(如姓名、日期),設置索引。字段大量重復、為空不適合建立索引。
盡量找那種占用空間小的類型字段做索引,長字符串可以使用前綴索引,減少索引大小,提高查詢速度。
2、多個經常查詢列可以建立聯合索引
遵循向左原則。
3、避免過度索引和頻繁更新索引字段
占用磁盤空間、需要頻繁維護字段,浪費性能。
4、SQL優化慢查詢
//使用 show processlist
//觀察是否有大量線程處于不正常的狀態或者特征//使用 explain(desc) 分析單條SQL語句
一般做到range,極好做到ref,ALL全表掃描不推薦
如何MySQL和ES一致性?
1、操作MYSQL時同步操作ES,這種不推薦,因為重試邏輯嵌在業務代碼中,服務宕機,寫入失敗會一直重試。
2、通過binlog進行同步,客戶端從canal拉取消息進行消費,再由客戶端主動插入或者更新ES中的數據。也可以cannal發送binlog消息到消息隊列,client異步消費kafka中的消息。
b+樹是如何實現的 優勢在哪
B樹也稱B-樹,它是一顆多路平衡查找樹,B樹和后面講到的B+樹也是從最簡單的二叉樹變換而來的,并沒有什么神秘的地方,下面我們來看看B樹的定義。
- 每個節點中的關鍵字都按照從小到大的順序排列,每個關鍵字的左子樹中的所有關鍵字都小于它,而右子樹中的所有關鍵字都大于它。
- 所有葉子節點都位于同一層,或者說根節點到每個葉子節點的長度都相同。
- 每個節點都存有索引和數據,也就是對應的key和value。
B樹和B+樹的區別在于,B+樹的非葉子結點只包含導航信息,不包含實際的值,每個葉子結點都存有相鄰葉子結點的指針,葉子結點本身依關鍵字的大小自小而大順序鏈接,便于區間查找和遍歷。
- 由于B+樹在內部節點上不包含數據信息,因此在內存頁中能夠存放更多的key。 數據存放的更加緊密,具有更好的空間局部性。因此訪問葉子節點上關聯的數據也具有更好的緩存命中率。
- B+樹的葉子結點都是相鏈的,因此對整棵樹的便利只需要一次線性遍歷葉子結點即可。而且由于數據順序排列并且相連,所以便于區間查找和搜索。而B樹則需要進行每一層的遞歸遍歷。相鄰的元素可能在內存中不相鄰,所以緩存命中性沒有B+樹好。
MySQL悲觀鎖
在查詢庫存時加排它鎖,阻止其他事務對這條數據進行加鎖或者修改
優點:MySQL事物鎖準確度高。缺點:耗性能,對MySQL壓力較大。
DB::beginTransaction();try {$stock = Skill::query()->where('id', $id)->lockForUpdate()->value('stock');if ($stock > 0) {Skill::query()->where('id', $id)->decrement('stock');echo '搶購成功';} else {echo '庫存不足,搶購失敗';}DB::commit();} catch (\Exception $e) {echo $e->getMessage();DB::rollBack();}
MySQL樂觀鎖
不加鎖實現鎖效果,MySQL樂觀鎖就是MVCC機制,借助version版本號進行控制
優點:因為不涉及鎖數據,并發量比悲觀鎖。缺點:MySQL抗壓瓶頸。
$info = Skill::query()->where('id', $id)->first(['stock', 'version']);
if ($info->stock > 0) {$skill = Skill::query()->where(['id' => $id, 'version' => $info->version])->update(['stock' => $info->stock -1, 'version' => $info->version + 1]);echo '搶購成功';
} else {echo '庫存不足,搶購失敗';
}
MVCC:多版本并發控制。在MySQL InnoDB 中的實現主要是為了提高數據庫并發性能,用更好的方式去處理讀-寫沖突,做到即使有讀寫沖突時,也能做到不加鎖,非阻塞并發讀。
當前讀:讀取的是記錄的最新版本,讀取時會保證其他并發事務不能修改當前記錄,會對讀取的記錄進行加鎖。
快照讀:不加鎖的非阻塞讀。
持續更新,未完待續~