1. 程式人生 > 資料庫 >Java基礎知識整理:資料庫

Java基礎知識整理:資料庫

十七、MySql

164. 資料庫的三正規化是什麼?

  • 第一正規化:強調的是列的原子性,即資料庫表的每一列都是不可分割的原子資料項。

  • 第二正規化:要求實體的屬性完全依賴於主關鍵字。所謂完全依賴是指不能存在僅依賴主關鍵字一部分的屬性。

  • 第三正規化:任何非主屬性不依賴於其它非主屬性。

165. 一張自增表裡面總共有 7 條資料,刪除了最後 2 條資料,重啟 mysql 資料庫,又插入了一條資料,此時 id 是幾?

  • 表型別如果是 MyISAM ,那 id 就是 18。

  • 表型別如果是 InnoDB,那 id 就是 15。

 

InnoDB 表只會把自增主鍵的最大 id 記錄在記憶體中,所以重啟之後會導致最大 id 丟失。

166. 如何獲取當前資料庫版本?

使用 select version() 獲取當前 MySQL 資料庫版本。

167. 說一下 ACID 是什麼?

  • Atomicity(原子性):一個事務(transaction)中的所有操作,或者全部完成,或者全部不完成,不會結束在中間某個環節。事務在執行過程中發生錯誤,會被恢復(Rollback)到事務開始前的狀態,就像這個事務從來沒有執行過一樣。即,事務不可分割、不可約簡。

  • Consistency(一致性):在事務開始之前和事務結束以後,資料庫的完整性沒有被破壞。這表示寫入的資料必須完全符合所有的預設約束、觸發器、級聯回滾等。

  • Isolation(隔離性):資料庫允許多個併發事務同時對其資料進行讀寫和修改的能力,隔離性可以防止多個事務併發執行時由於交叉執行而導致資料的不一致。事務隔離分為不同級別,包括讀未提交(Read uncommitted)、讀提交(read committed)、可重複讀(repeatable read)和序列化(Serializable)。

  • Durability(永續性):事務處理結束後,對資料的修改就是永久的,即便系統故障也不會丟失。

168. char 和 varchar 的區別是什麼?

char(n) :固定長度型別,比如訂閱 char(10),當你輸入"abc"三個字元的時候,它們佔的空間還是 10 個位元組,其他 7 個是空位元組。

chat 優點:效率高;缺點:佔用空間;適用場景:儲存密碼的 md5 值,固定長度的,使用 char 非常合適。

varchar(n) :可變長度,儲存的值是每個值佔用的位元組再加上一個用來記錄其長度的位元組的長度。

所以,從空間上考慮 varcahr 比較合適;從效率上考慮 char 比較合適,二者使用需要權衡。

169. float 和 double 的區別是什麼?

  • float 最多可以儲存 8 位的十進位制數,並在記憶體中佔 4 位元組。

  • double 最可可以儲存 16 位的十進位制數,並在記憶體中佔 8 位元組。

170. mysql 的內連線、左連線、右連線有什麼區別?

內連線關鍵字:inner join;左連線:left join;右連線:right join。

 

內連線是把匹配的關聯資料顯示出來;左連線是左邊的表全部顯示出來,右邊的表顯示出符合條件的資料;右連線正好相反。

171. mysql 索引是怎麼實現的?

索引是滿足某種特定查詢演算法的資料結構,而這些資料結構會以某種方式指向資料,從而實現高效查詢資料。

 

具體來說 MySQL 中的索引,不同的資料引擎實現有所不同,但目前主流的資料庫引擎的索引都是 B+ 樹實現的,B+ 樹的搜尋效率,可以到達二分法的效能,找到資料區域之後就找到了完整的資料結構了,所有索引的效能也是更好的。

172. 怎麼驗證 mysql 的索引是否滿足需求?

使用 explain 檢視 SQL 是如何執行查詢語句的,從而分析你的索引是否滿足需求。

 

explain 語法:explain select * from table where type=1。

173. 說一下資料庫的事務隔離?

MySQL 的事務隔離是在 MySQL. ini 配置檔案裡新增的,在檔案的最後新增:transaction-isolation = REPEATABLE-READ

 

可用的配置值:READ-UNCOMMITTED、READ-COMMITTED、REPEATABLE-READ、SERIALIZABLE。

 

  • READ-UNCOMMITTED:未提交讀,最低隔離級別、事務未提交前,就可被其他事務讀取(會出現幻讀、髒讀、不可重複讀)。

  • READ-COMMITTED:提交讀,一個事務提交後才能被其他事務讀取到(會造成幻讀、不可重複讀)。

  • REPEATABLE-READ:可重複讀,預設級別,保證多次讀取同一個資料時,其值都和事務開始時候的內容是一致,禁止讀取到別的事務未提交的資料(會造成幻讀)。

  • SERIALIZABLE:序列化,代價最高最可靠的隔離級別,該隔離級別能防止髒讀、不可重複讀、幻讀。

 

髒讀 :表示一個事務能夠讀取另一個事務中還未提交的資料。比如,某個事務嘗試插入記錄 A,此時該事務還未提交,然後另一個事務嘗試讀取到了記錄 A。

 

不可重複讀 :是指在一個事務內,多次讀同一資料。

 

幻讀 :指同一個事務內多次查詢返回的結果集不一樣。比如同一個事務 A 第一次查詢時候有 n 條記錄,但是第二次同等條件下查詢卻有 n+1 條記錄,這就好像產生了幻覺。發生幻讀的原因也是另外一個事務新增或者刪除或者修改了第一個事務結果集裡面的資料,同一個記錄的資料內容被修改了,所有資料行的記錄就變多或者變少了。

174. 說一下 mysql 常用的引擎?

InnoDB 引擎:InnoDB 引擎提供了對資料庫 acid 事務的支援,並且還提供了行級鎖和外來鍵的約束,它的設計的目標就是處理大資料容量的資料庫系統。MySQL 執行的時候,InnoDB 會在記憶體中建立緩衝池,用於緩衝資料和索引。但是該引擎是不支援全文搜尋,同時啟動也比較的慢,它是不會儲存表的行數的,所以當進行 select count(*) from table 指令的時候,需要進行掃描全表。由於鎖的粒度小,寫操作是不會鎖定全表的,所以在併發度較高的場景下使用會提升效率的。

 

MyIASM 引擎:MySQL 的預設引擎,但不提供事務的支援,也不支援行級鎖和外來鍵。因此當執行插入和更新語句時,即執行寫操作的時候需要鎖定這個表,所以會導致效率會降低。不過和 InnoDB 不同的是,MyIASM 引擎是儲存了表的行數,於是當進行 select count(*) from table 語句時,可以直接的讀取已經儲存的值而不需要進行掃描全表。所以,如果表的讀操作遠遠多於寫操作時,並且不需要事務的支援的,可以將 MyIASM 作為資料庫引擎的首選。

175. 說一下 mysql 的行鎖和表鎖?

MyISAM 只支援表鎖,InnoDB 支援表鎖和行鎖,預設為行鎖。

 

  • 表級鎖:開銷小,加鎖快,不會出現死鎖。鎖定粒度大,發生鎖衝突的概率最高,併發量最低。

  • 行級鎖:開銷大,加鎖慢,會出現死鎖。鎖力度小,發生鎖衝突的概率小,併發度最高。

176. 說一下樂觀鎖和悲觀鎖?

  • 樂觀鎖:每次去拿資料的時候都認為別人不會修改,所以不會上鎖,但是在提交更新的時候會判斷一下在此期間別人有沒有去更新這個資料。

  • 悲觀鎖:每次去拿資料的時候都認為別人會修改,所以每次在拿資料的時候都會上鎖,這樣別人想拿這個資料就會阻止,直到這個鎖被釋放。

 

資料庫的樂觀鎖需要自己實現,在表裡面新增一個 version 欄位,每次修改成功值加 1,這樣每次修改的時候先對比一下,自己擁有的 version 和資料庫現在的 version 是否一致,如果不一致就不修改,這樣就實現了樂觀鎖。

177. mysql 問題排查都有哪些手段?

  • 使用 show processlist 命令檢視當前所有連線資訊。

  • 使用 explain 命令查詢 SQL 語句執行計劃。

  • 開啟慢查詢日誌,檢視慢查詢的 SQL。

178. 如何做 mysql 的效能優化?

  • 為搜尋欄位建立索引。

  • 避免使用 select *,列出需要查詢的欄位。

  • 垂直分割分表。

  • 選擇正確的儲存引擎。