JAVA知識點梳理-Mysql
五、MySQL 篇
\49. 簡單說說在 MySQL 中執行依據查詢 SQL 是如何執行的?
sql語句->聯結器->快取查詢->解析器->優化器->執行器->搜尋引擎。
\50. MySQL 有哪些儲存引擎?
MyISAM: 優勢 – 查詢速度快 – 資料和索引壓縮問題 – 表級鎖 – 資料丟失
InnoDB: 優勢 – 行級鎖 – 事務支援 – 資料安全問題 – 資料檔案龐大 – 啟動慢 – 不支援FULLTEXT索引
**MEMORY **儲存引擎將表中的資料儲存在記憶體中,表級鎖、只支援固定大小的行、不支援TEXT、BLOB欄位、伺服器重啟後資料會丟失、記憶體資源成本昂貴
\51. MySQL 中 varchar 與 char 的區別?varchar(30) 中的 30 代表的涵義?
char 與varchar都是用來儲存字串的,只是他們的儲存方式不一樣,char有固定的長度,而varchar屬於可變長的字元型別。
varchar(30)中30的涵義:最大儲存30個字元
\52. int(11) 中的 11 代表什麼涵義?
int(20)中20的涵義: 20表示最大顯示寬度為20
\53. 為什麼 SELECT COUNT(*) FROM table 在 InnoDB 比 MyISAM 慢?
InnoDB 中 count(*) 語句是在執行的時候,全表掃描統計總數量,所以當資料越來越大時,語句就越來越耗時了
innoDB是行級鎖,MyISAM是表級鎖
\54. 說說資料庫的三正規化和反模式
第一正規化(1NF):資料庫表的每一列都是不可分割的原子項
第二正規化(2NF):每個表必須有且僅有一個數據元素為主鍵(Primary key),其他屬性需完全依賴於主鍵
第二正規化需建立在滿足第一正規化的基礎之上
第三正規化(3NF):資料表中的每一列都和主鍵直接相關,而不能間接相關
同樣,第三正規化也需要建立在第二正規化的基礎之上
使用反三大正規化的目的是為了,實現效率的提高,在欄位型別中使用json的方式存貯多條資料,實現對資料的處理。
\55. 在設計資料庫表的時候,欄位用於儲存金額、餘額時,選擇什麼型別比較好?
Decimal為專門為財務相關問題設計的資料型別。
DECIMAL從MySQL 5.1引入,列的宣告語法是DECIMAL(M,D)。在MySQL 5.1中,參量的取值範圍如下:
·M是數字的最大數(精度)。其範圍為1~65(在較舊的MySQL版本中,允許的範圍是1~254),M 的預設 值是10。
·D是小數點右側數字的數目(標度)。其範圍是0~30,但不得超過M。
\56. 大概說說 InnoDB 與 MyISAM 有什麼區別?
\1. 事務安全(MyISAM不支援事務,INNODB支援事務)
\2. 外來鍵 MyISAM 不支援外來鍵, INNODB支援外來鍵.
\3. 鎖機制(MyISAM時表鎖,innodb是行鎖)
\4. 查詢和新增速度(MyISAM批量插入速度快)
\5. 支援全文索引(MyISAM支援全文索引,INNODB不支援全文索引)
6.MyISAM記憶體空間使用率比InnoDB低
\57. 什麼是索引?
索引就類似書本的目錄,作用就是方便我們更加快速的查詢到想要的資料。
\58. 索引有什麼優缺點?
使用索引的優點:
- 提高資料的搜尋速度
- 加快表與表之間的連線速度
- 在資訊檢索過程中,若使用分組及排序子句進行時,通過建立索引能有效的減少檢索過程中所需的分組及排序時間,提高檢索效率。
使用索引的缺點:
- 在我們建立資料庫的時候,需要花費的時間去建立和維護索引,而且隨著資料量的增加,需要維護它的時間也會增加。
- 在建立索引的時候會佔用儲存空間。
- 在我們需要修改表中的資料時,索引還需要進行動態的維護,所以對資料庫的維護帶來了一定的麻煩。
\59. MySQL 索引型別有哪些?
FULLTEXT,HASH,BTREE,RTREE。
\60. 什麼時候不要使用索引?
不需要建立索引的情況:
1.如果需要取到表中所有記錄,則沒必要建立索引
2.對非唯一有大量重複值的欄位,沒必要建立索引,如性別
3.經常進行修改、刪除等操作的欄位,沒必要建立索引
4.記錄比較少的表,沒必要建立索引\
61. 使用 MySQL 的索引應該注意些什麼?
儘量避免這些不走索引的sql:
-- 正則表示式不使用索引,這應該很好理解,所以為什麼在SQL中很難看到regexp關鍵字的原因
-- 字串與數字比較不使用索引;
-- 如果mysql估計使用全表掃描要比使用索引快,則不使用索引
1.索引不會包含有NULL的列
只要列中包含有NULL值,都將不會被包含在索引中,複合索引中只要有一列含有NULL值,那麼這一列對於此符合索引就是無效的。
2.使用短索引
對串列進行索引,如果可以就應該指定一個字首長度。例如,如果有一個char(255)的列,如果在前10個或20個字元內,多數值是唯一的,那麼就不要對整個列進行索引。短索引不僅可以提高查詢速度而且可以節省磁碟空間和I/O操作。
3.索引列排序
mysql一張表查詢只能用到一個索引。因此如果where子句中已經使用了索引的話,那麼order by中的列是不會使用索引的。因此資料庫預設排序可以符合要求的情況下不要使用排序操作,儘量不要包含多個列的排序,如果需要最好給這些列建複合索引。這一點是很多程式猿容易忽略的,如where子句的欄位建了索引,排序的欄位建了索引,但是分開建的,以為會走索引,其實這樣的話排序的欄位不會使用索引的,除非建複合索引,切記。
4.like語句操作
一般情況下不鼓勵使用like操作,如果非使用不可,注意正確的使用方式。like ‘%aaa%’不會使用索引,而like ‘aaa%’可以使用索引。
5.不要在列上進行運算
6.不使用NOT IN 、<>、!=操作,但<,<=,=,>,>=,BETWEEN,IN是可以用到索引的
7.索引要建立在經常進行select操作的欄位上。
這是因為,如果這些列很少用到,那麼有無索引並不能明顯改變查詢速度。相反,由於增加了索引,反而降低了系統的維護速度和增大了空間需求。
8.索引要建立在值比較唯一的欄位上。
9.對於那些定義為text、image和bit資料型別的列不應該增加索引。因為這些列的資料量要麼相當大,要麼取值很少。
10.在where和join中出現的列需要建立索引。
11.where的查詢條件裡有不等號(where column != …),mysql將無法使用索引。
12.如果where字句的查詢條件裡使用了函式(如:where DAY(column)=…),mysql將無法使用索引。
13.在join操作中(需要從多個數據表提取資料時),mysql只有在主鍵和外來鍵的資料型別相同時才能使用索引,否則即使建立了索引也不會使用。
14.在進行聯表查詢時,建立關聯的表的欄位型別最好一樣且長度一致,這樣能更好的發揮索引的作用。
15.組合索引時切記此條約束:組合索引中有多個欄位,其中一個欄位是有範圍判斷,則需將此欄位在最後面。如
ALTER TABLE USER_DEMO ADD INDEX name_age (NAME,AGE); 因為age會有範圍判斷,則建組合索引時將AGE欄位放在後面。
16.字符集欄位比較,UTF8與UTF-BIN聯合查詢是不能走索引的。
如某張表的order_no欄位型別為varchar(50),另一張表的order_no欄位型別為varchar(50) COLLATE utf8_BIN。則此時聯合查詢時不能走索引的,切記。
18.給表建立主鍵,對於沒有主鍵的表,在查詢和索引定義上有一定的影響。
19.避免表字段為null,建議設定預設值(如int型別設定預設值為0),這樣在索引查詢上,效率會高很多。
\62. 怎麼知道一條查詢語句是否用到了索引,用了什麼型別的索引?
前加explain
explain SELECT * from ....
\63. 說說什麼是 MVCC?
MVCC(Mutil-Version Concurrency Control),就是多版本併發控制。MVCC 是一種併發控制的方法,一般在資料庫管理系統中,實現對資料庫的併發訪問。
\64. MVCC 可以為資料庫解決什麼問題?
併發訪問(讀或寫)資料庫時,對正在事務內處理的資料做多版本的管理。以達到用來避免寫操作的堵塞,從而引發讀操作的併發問題。
大家都應該知道,鎖機制可以控制併發操作,但是其系統開銷較大,而MVCC可以在大多數情況下代替行級鎖,使用MVCC,能降低其系統開銷。
\65. 說說 MVCC 的實現原理
MVCC是通過儲存資料在某個時間點的快照來實現的。不同儲存引擎的MVCC實現是不同的,典型的有樂觀併發控制和悲觀併發控制。當我們建立表完成後,mysql會自動為每個表新增 資料版本號(最後更新資料的事務id)db_trx_id 刪除版本號 db_roll_pt (資料刪除的事務id) 事務id由mysql資料庫自動生成,且遞增。
\66. 什麼是死鎖?
死鎖是指兩個或兩個以上的程序在執行過程中,由於競爭資源或者由於彼此通訊而造成的一種阻塞的現象,若無外力作用,它們都將無法推進下去
\67. MySQL 事務隔離級別?
讀未提交
讀已提交
可重複讀
可序列化
\69. 請說說 MySQL 資料庫的鎖?
行鎖:
共享鎖(S):SELECT * FROM table_name WHERE ... LOCK IN SHARE MODE
排他鎖(X):SELECT * FROM table_name WHERE ... FOR UPDATE
表鎖:
\70. 說說什麼是鎖升級?
鎖升級,就是將眾多細粒度鎖轉換為較少的粗粒度的鎖以削減系統開銷的程序。
假如行鎖是有開銷的,那對1行加鎖可能沒問題,但對1萬行加鎖。那對系統開銷就非常大了,此時。資料庫就會將其升級為表鎖,以降低開銷。
\71. 說說悲觀鎖和樂觀鎖
悲觀鎖
總是假設最壞的情況,每次去拿資料的時候都認為別人會修改,所以每次在拿資料的時候都會上鎖,這樣別人想拿這個資料就會阻塞直到它拿到鎖(共享資源每次只給一個執行緒使用,其它執行緒阻塞,用完後再把資源轉讓給其它執行緒)。傳統的關係型資料庫裡邊就用到了很多這種鎖機制,比如行鎖,表鎖等,讀鎖,寫鎖等,都是在做操作之前先上鎖。Java中synchronized
和ReentrantLock
等獨佔鎖就是悲觀鎖思想的實現。
樂觀鎖
總是假設最好的情況,每次去拿資料的時候都認為別人不會修改,所以不會上鎖,但是在更新的時候會判斷一下在此期間別人有沒有去更新這個資料,可以使用版本號機制和CAS演算法實現。樂觀鎖適用於多讀的應用型別,這樣可以提高吞吐量,像資料庫提供的類似於write_condition機制,其實都是提供的樂觀鎖。在Java中java.util.concurrent.atomic
包下面的原子變數類就是使用了樂觀鎖的一種實現方式CAS實現的。
樂觀鎖常見的兩種實現方式
樂觀鎖一般會使用版本號機制或CAS演算法實現。
1.版本號機制(MVCC?)
一般是在資料表中加上一個資料版本號version欄位,表示資料被修改的次數,當資料被修改時,version值會加一。當執行緒A要更新資料值時,在讀取資料的同時也會讀取version值,在提交更新時,若剛才讀取到的version值為當前資料庫中的version值相等時才更新,否則重試更新操作,直到更新成功。
2. CAS演算法
即compare and swap(比較與交換),是一種有名的無鎖演算法。無鎖程式設計,即不使用鎖的情況下實現多執行緒之間的變數同步,也就是在沒有執行緒被阻塞的情況下實現變數的同步,所以也叫非阻塞同步(Non-blocking Synchronization)。CAS演算法涉及到三個運算元
需要讀寫的記憶體值 V
進行比較的值 A
擬寫入的新值 B
\72. 怎樣儘量避免死鎖的出現?
- 加鎖順序(執行緒按照一定的順序加鎖)
- 加鎖時限(執行緒嘗試獲取鎖的時候加上一定的時限,超過時限則放棄對該鎖的請求,並釋放自己佔有的鎖)
- 死鎖檢測