寫在前面: 我是「揚帆向海」,這個暱稱來源於我的名字以及女朋友的名字。我熱愛技術、熱愛開源、熱愛編程。
技術是開源的、知識是共享的
。
這博客是對自己學習的一點點總結及記錄,如果您對 Java、算法 感興趣,可以關注我的動態,我們一起學習。
用知識改變命運,讓我們的家人過上更好的生活
。
相關文章:
文章目錄
一、事務
1. 什麼是事務
MySQL事務是一組sql語句或一個獨立運行的工作單元。這個工作單元要麼全部執行,要麼全部不執行。
2. 事務的四大特性
原子性
:一個事務不可再分割,事務中的所有操作,要麼全部完成,要麼全部不完成。
一致性
:一個事務執行會使數據從一個一致狀態切換到另外一個一致狀態。也就是說,在事務開始之前和事務結束以後,數據庫的完整性沒有被破壞。
隔離性
:一個事務所做的修改在最終提交之前,對其它事務是不可見的。也就是說一個事務的執行不會受到其它事務的干擾。
持久性
:一個事務一旦提交以後,對數據的修改就會永久的保存到數據庫中,即便系統故障也不會丟失。
3. 事務的併發問題
① 事務併發問題什麼時候發生?
當多個事務同時操作同一個數據庫的相同數據時,就會發生併發問題。
② 事務的併發問題有哪些?
髒讀
:對於兩個事務T1、T2, T1 讀取了已經被T2 更新但還沒有被提交的數據。如果事務T2進行了回滾, T1讀取到的數據就是臨時且無效的。
不可重複讀
:對於兩個事務T1、T2, T1 讀取了一個數據, 然後 T2 更新了該數據。如果T1再次讀取同一個數據, 值就不相同了。
幻讀
:對於兩個事務T1、T2, T1 從一個表中讀取了一個數據, 然後T2 在該表中插入了一些新的行。如果T1 再次讀取同一個表, 就會多出幾行。
③ 如何避免事務的併發問題?
通過設置事務的隔離級別進行避免事務的併發問題。事務有以下四個隔離級別:
讀未提交
(read-uncommitted)
讀已提交
(read-committed) 可以避免髒讀
可重複讀
(repeatable-read) 可以避免髒讀、不可重複讀和一部分幻讀
串行化
(serializable) 可以避免髒讀、不可重複讀和幻讀
事務隔離級別 | 髒讀 | 不可重複讀 | 幻讀 |
---|---|---|---|
讀未提交(read-uncommitted) | 是 | 是 | 是 |
讀已提交(read-committed) | 否 | 是 | 是 |
可重複讀(repeatable-read) | 否 | 否 | 是 |
串行化(serializable) | 否 | 否 | 否 |
MySQL數據庫(InnoDB引擎)默認使用的隔離級別是:可重複讀( Repeatable read );
隔離級別越高,越能保證數據的完整性和一致性,但是對併發性能的影響也越大。
二、索引
1. 什麼是索引
索引
是對數據庫表中一列或多列的值進行排序的一種結構,使用索引可以提高數據庫中特定數據的查詢速度
2. 索引的優缺點
優點
① 使用索引可以大大加快數據的查詢速度
② 通過創建唯一索引,可以保證數據庫表中每一行數據的唯一性。
③ 在使用分組和排序子句進行數據查詢時,使用索引可以減少在查詢中分組和排序的時間。
缺點
① 創建索引和維護索引需要時間,隨着數據量的增加所需要時間也會增加。
② 當對錶中的數據進行增加、刪除和修改的時候,索引也要動態地維護,這樣就降低了數據的維護速度。
③ 索引需要佔磁盤空間,除了數據表佔數據空間之外,每一個索引還要佔定的物理空間,如果有大量的索引,索引文件可能比數據文件更快達到最大文件尺寸
2. 索引的設計原則
索引設計不合理或者缺少索引都會對數據庫和應用程序的性能造成障礙。高效的索引對於獲得良好的性能非常重要。設計索引時,應該考慮以下準則:
① 索引並非越多越好,一個表中如有大量的索引,不僅佔用磁盤空間,而且會影響 NSERT、 DELETE、UPDATES等語句的性能,因爲當表中的數據更改的同時索引也會進行調整和更新。
② 避免對經常更新的表進行過多的索引,並且索引中的列儘可能少。而對經常用於查詢的字段應該創建索引,但要避免添加不必要的字段。
③ 數據量小的表最好不要使用索引,由於數據較少,查詢花費的時間可能比遍歷索引的時間還要短,索引可能不會產生優化效果。
④ 在條件表達式中經常用到的不同值較多的列上建立索引,在不同值很少的列上不要建立索引。比如在學生表的“性別”字段上只有“男”與“女”兩個不同值,因此就無須建立索引。如果建立索引不但不會提高查詢效率,反而會嚴重降低數據更新速度。
⑤ 當唯一性是某種數據本身的特徵時,指定唯一索引。使用唯一索引副需能確保定義的列的數據完整性,以提高查詢速度。
⑥ 在頻繁進行排序或分組(即進行group by或 order by操作)的列上建立索引,如果待排序的列有多個,可以在這些列上建立組合索引。
三、數據庫設計三大範式
1. 第一範式
確保每列保持原子性
第一範式是最基本的範式。要求數據庫表的每一列都是不可分割的原子數據項。
學號 | 姓名 | 課程號 | 課程名 | 學分 | 成績 |
---|---|---|---|---|---|
001 | 揚帆向海 | 101 | Java | 4 | 80 |
002 | 起帆朝陽 | 102 | 數據結構 | 6 | 90 |
2. 第二範式
確保表中的每列都和主鍵相關
第二範式在第一範式的基礎上,第二範式需要確保數據庫表中的每一列都和主鍵相關,而不能只與主鍵的某一部分相關(主要針對聯合主鍵而言)。也就是說在一個數據庫表中,一個表中只能保存一種數據,不可以把多種數據保存在同一張數據庫表中。
學號 | 姓名 | 課程號 | 成績 |
---|---|---|---|
001 | 揚帆向海 | 101 | 80 |
002 | 起帆朝陽 | 102 | 90 |
課程號 | 課程名 | 學分 |
---|---|---|
101 | Java | 4 |
102 | 數據結構 | 6 |
3. 第三範式
確保每列都和主鍵列直接相關,而不是間接相關
第三範式是在第二範式的基礎上,需要確保數據表中的每一列數據都和主鍵直接相關,而不是間接相關。
學生表:
學號 | 姓名 |
---|---|
001 | 揚帆向海 |
002 | 起帆朝陽 |
課程表:
課程號 | 課程名 | 學分 |
---|---|---|
101 | Java | 4 |
102 | 數據結構 | 6 |
成績表:
學號 | 課程號 | 成績 |
---|---|---|
001 | 101 | 80 |
002 | 102 | 90 |
四、MySQL的主從複製
1. 概念
MySQL 主從複製
是指數據可以從一個MySQL數據庫服務器主節點複製到一個或多個從節點。
2. 原理
從庫生成兩個線程,一個I/O線程,一個SQL線程。
I/O線程
去請求主庫 的binlog,並將得到的binlog日誌寫到relay log(中繼日誌) 文件中;
主庫會生成一個 log dump 線程,用來給從庫 I/O線程傳binlog。
SQL線程
會讀取relay log文件中的日誌,並解析成具體操作,來實現主從的操作一致,而最終數據一致。
3. 主從複製用途
①
讀寫分離
,在開發工作中,有時候會遇見某個sql
語句需要鎖表,導致暫時不能使用讀的服務,這樣就會影響現有業務,使用主從複製,讓主庫負責寫,從庫負責讀,這樣即使主庫出現了鎖表的情景,通過讀從庫也可以保證業務的正常運作。
②
數據實時備份
,當系統中某個節點發生故障時,可以方便的故障切換。
五、MySQL中的鎖
1. 爲什麼要加鎖
數據庫的鎖是爲了支持對共享資源進行併發訪問,提供數據的完整性和一致性。在數據庫中加鎖是保證在高併發的情況下,訪問數據庫的時候,數據不會出現問題。
2. 鎖的分類
按操作分:
① 讀鎖(共享鎖):針對同一份數據,多個讀取操作可以同時進行而不互相影響。
② 寫鎖(排它鎖):當前寫操作沒有完成前,會阻斷其他寫鎖和讀鎖。
按粒度分:
① 表鎖:開銷小,加鎖快;不會出現死鎖;鎖定粒度大,發生鎖衝突的概率最高,併發度最低。
② 行鎖:開銷大,加鎖慢;會出現死鎖;鎖定粒度最小,發生鎖衝突的概率最低,併發度也最高。
③ 頁鎖:開銷和加鎖時間界於表鎖和行鎖之間;會出現死鎖;鎖定粒度界於表鎖和行鎖之間,併發度一般。
六、如何做 MySQL的性能優化
① 當只需要一條數據的時候,使用 limit 1
② 儘量避免使用 select * ,在查詢的時候列出需要查詢的字段。
③ 使用 join 代替子查詢。
④ 減少使用 or,使用 in 或者 union(union all) 代替。
⑤ 爲搜索字段創建索引。但是不要過度索引,索引越多,佔用空間越大,反而性能變慢。
⑥ 避免進行類型轉換,不然會導致索引失效。
⑦ 對查詢語句使用explain 。 使用explain ,可以幫助瞭解MySQL是如何處理sql語句的, 可以查看到sql的執行計劃,這樣就能更好的去了解的sql語句的不足,然後優化語句。
⑧ 垂直分割,將常用和有關係的字段放在相同的表中,把一張表的數據分成幾張表 這樣可以降低表的複雜度和字段的數目,從而達到優化的目的
由於水平有限,本博客難免有不足,懇請各位大佬不吝賜教!