資料庫基礎面試第二彈

来源:https://www.cnblogs.com/beyond-tester/archive/2023/09/05/17681223.html
-Advertisement-
Play Games

1. 樂觀鎖和悲觀鎖的理解及使用 樂觀鎖和悲觀鎖是在併發編程中使用的兩種併發控制機制,用於解決多線程或多進程環境下的數據一致性問題。 1. 悲觀鎖(Pessimistic Locking): 悲觀鎖的思想是假設併發訪問會導致衝突,因此在訪問共用資源之前,悲觀鎖會將資源鎖定,確保其他線程無法修改資源。 ...


1. 樂觀鎖和悲觀鎖的理解及使用

樂觀鎖和悲觀鎖是在併發編程中使用的兩種併發控制機制,用於解決多線程或多進程環境下的數據一致性問題。

1. 悲觀鎖(Pessimistic Locking):
  悲觀鎖的思想是假設併發訪問會導致衝突,因此在訪問共用資源之前,悲觀鎖會將資源鎖定,確保其他線程無法修改資源。悲觀鎖的典型應用是資料庫中的行級鎖,使用SELECT...FOR

UPDATE語句鎖定查詢結果。

使用悲觀鎖的過程如下:

  • 當一個線程要訪問共用資源時,它會先嘗試獲取鎖。
  • 如果鎖已經被其他線程獲取,則當前線程會被阻塞,直到鎖被釋放。
  • 當線程獲得了鎖之後,它可以安全地訪問共用資源,其他線程無法修改該資源。
  • 當線程完成操作後,釋放鎖,其他線程可以獲取到鎖並訪問資源。

悲觀鎖的優點是保證了數據的一致性,但是它的缺點是在高併發環境下,鎖的競爭會導致性能下降。

2. 樂觀鎖(Optimistic Locking):
樂觀鎖的思想是假設併發訪問不會導致衝突,因此線上程訪問共用資源之前,不會加鎖。相反,樂觀鎖會在更新資源時,檢查在此期間是否有其他線程修改了資源。

使用樂觀鎖的過程如下:

  • 當一個線程要更新共用資源時,它首先會讀取資源的版本號或標識。
  • 在進行更新之前,線程會檢查資源的版本號是否發生了變化。
  • 如果資源的版本號沒有變化,線程會更新資源,並更新版本號。
  • 如果資源的版本號發生了變化,表示有其他線程已經修改過資源,當前線程的操作可能會產生衝突。
  • 在發生衝突時,可以選擇進行回滾操作或者重試整個過程。

  樂觀鎖的優點是在無衝突的情況下,不需要進行加鎖操作,從而提高了併發性能。然而,如果衝突頻繁發生,會導致大量的回滾和重試操作,降低性能。

總的來說,悲觀鎖適合對於衝突頻繁發生的場景,可以保證數據的一致性;而樂觀鎖適合對於衝突較少發生的場景,可以提高併發性能。選擇使用哪種鎖要根據具體的應用場景和性能需求進行

權衡。

樂觀鎖與悲觀鎖例子:

SELECT stock FROM inventory WHERE product_id = <product_id> FOR UPDATE;
```

在上述代碼中,使用 `FOR UPDATE` 子句來鎖定庫存行,確保其他併發操作無法修改庫存數量。

START TRANSACTION;  -- 開啟事務
SELECT stock FROM inventory WHERE product_id = <product_id> FOR UPDATE;  -- 獲取並鎖定庫存行
-- 檢查庫存是否足夠
IF stock >= <quantity> THEN
    UPDATE inventory SET stock = stock - <quantity> WHERE product_id = <product_id>;  -- 更新庫存
    COMMIT;  -- 提交事務
    -- 庫存更新成功,繼續後續操作
ELSE
    ROLLBACK;  -- 回滾事務
    -- 庫存不足,處理相應邏輯,如提示用戶庫存不足
END IF;
```

2. 聚集索引和非聚集索引的區別:

聚集索引(Clustered Index)和非聚集索引(Non-clustered Index)是資料庫中常用的索引類型,它們在索引的組織方式和數據訪問方式上存在一些區別。

聚集索引:

  • 聚集索引定義了數據表的物理排序方式。每個表只能有一個聚集索引,它決定了表中數據行的物理存儲順序。如果一個表有聚集索引,那麼數據行將按照聚集索引的排序順序存儲在磁碟上。
  • 聚集索引的葉子節點包含了整個數據行的信息,因此當使用聚集索引進行數據查詢時,可以直接通過索引找到所需的數據行。
  • 由於每個表只能有一個聚集索引,一般情況下,聚集索引會選擇主鍵作為索引鍵。

非聚集索引:

  • 非聚集索引是基於表中的列創建的索引,它存儲了索引鍵和指向對應數據行的指針。一個表可以有多個非聚集索引。
  • 非聚集索引的葉子節點不包含完整的數據行,而是包含了索引鍵和指向對應數據行的指針。當使用非聚集索引進行數據查詢時,首先通過索引找到對應的數據行的指針,然後再通過指針獲取完整的數據行。
  • 非聚集索引可以加快數據的查找速度,尤其是在涉及到過濾和排序的查詢操作中。

區別總結:

  • 聚集索引決定了數據行的物理存儲順序,而非聚集索引只是提供了數據行的邏輯順序。
  • 聚集索引的葉子節點包含完整的數據行,而非聚集索引的葉子節點只包含索引鍵和指向數據行的指針。
  • 一個表只能有一個聚集索引,但可以有多個非聚集索引。

在實際使用中,根據具體的查詢需求和數據特點,可以根據需要選擇適當的索引類型,以提高資料庫的查詢性能和數據訪問效率。

創建聚集索引和非聚集索引的示例:

CREATE CLUSTERED INDEX idx_Orders_OrderID ON Orders (OrderID);

上述語句創建了一個名為 "idx_Orders_OrderID" 的聚集索引,它基於 "Orders" 表的 "OrderID" 列。


CREATE NONCLUSTERED INDEX idx_Customers_Email ON Customers (Email);

上述語句創建了一個名為 "idx_Customers_Email" 的非聚集索引,它基於 "Customers" 表的 "Email" 列。

3.  為什麼索引用B+樹,而不用普通的二叉樹

  1. 磁碟訪問效率: B+樹是一種多叉樹,它具有分支因數(即子節點的最大數量)更高的特點。相比之下,二叉樹每個節點只有兩個子節點。在磁碟上,每次讀取或寫入的開銷是非常昂貴的操作,因此減少磁碟訪問次數可以提高索引的性能。B+樹的高分支因數意味著在相同高度的情況下,它可以存儲更多的鍵值對,減少了磁碟I/O次數。而二叉樹的分支因數較低,可能需要更多的磁碟訪問來定位目標數據。

  2. 順序訪問性能: B+樹的葉子節點使用鏈表連接起來,形成一個有序的鏈表結構。這使得範圍查詢和順序訪問非常高效。例如,在資料庫中,如果需要查詢某個範圍內的數據(如按時間排序的記錄),B+樹可以利用有序的葉子節點鏈表進行快速定位和遍歷。而在二叉樹中,由於沒有有序鏈表結構,需要進行中序遍歷才能獲取有序數據,這會增加額外的開銷。

  3. 索引的穩定性: B+樹作為一種自平衡樹結構,對於插入和刪除操作具有較好的穩定性。當在B+樹中進行插入或刪除操作時,只需要對樹的部分節點進行修改,而不需要像二叉樹那樣進行全局的重新平衡。這種特性使得B+樹更適合於高效地維護索引結構。

  4. 緩存利用: 現代電腦系統通常都有層次化的緩存結構,其中記憶體緩存(如CPU緩存)的訪問速度遠高於磁碟。B+樹由於具有高的分支因數,可以存儲更多的鍵值對在每個節點中,因此在搜索過程中可以利用更好地利用緩存,減少記憶體訪問的次數。而二叉樹由於分支因數較低,可能需要更多的記憶體訪問來獲取相同數量的鍵值對。

綜上所述,B+樹相對於普通的二叉樹具有更好的磁碟訪問效率、順序訪問性能、穩定性和緩存利用,使其成為了廣泛應用於索引結構的一種理想選擇。

4. Hash索引和B+樹索引區別:

Hash索引和B+樹索引是兩種常見的索引結構,它們在實現原理、適用場景和性能方面存在一些區別。

實現原理:

  • Hash索引: Hash索引使用散列函數將索引鍵轉換為存儲位置的散列碼。散列碼經過映射後直接指向存儲數據的位置,因此在訪問數據時具有固定的時間複雜度(O(1))。
  • B+樹索引: B+樹索引是一種多叉樹結構,具有根節點、內部節點和葉子節點。每個節點包含多個鍵值對,通過比較鍵值來導航到下一個節點。B+樹索引通過在樹中進行有序查找來定位數據,因此訪問時間的複雜度與樹的高度相關(通常為O(log n))。

適用場景:

  • Hash索引: Hash索引適用於等值查詢,即根據精確的索引鍵值查找數據。它對於相等比較非常快速,但不適用於範圍查詢或排序操作。
  • B+樹索引: B+樹索引適用於範圍查詢、排序操作和模糊查詢。由於B+樹的有序性,它可以支持按順序遍曆數據和快速定位範圍內的數據。

數據訪問性能:

  • Hash索引: Hash索引具有固定的訪問時間複雜度(O(1)),因此在等值查詢方面非常高效。但是,由於散列函數的散列衝突可能導致鏈表的形成,這可能會影響性能,尤其是在高負載情況下。
  • B+樹索引: B+樹索引的訪問時間複雜度與樹的高度相關,通常為O(log n)。儘管每次訪問可能需要多次磁碟I/O,但B+樹索引在範圍查詢和順序訪問方面具有良好的性能。

存儲空間利用:

  • Hash索引: Hash索引通常需要預先分配足夠的散列槽位,以防止散列衝突。這可能會導致存儲空間的浪費,尤其是在數據分佈不均勻的情況下。
  • B+樹索引: B+樹索引在內部節點上存儲鍵值對和子節點指針,而葉子節點上存儲鍵值對和指向數據的指針。相比之下,B+樹索引通常可以更好地利用存儲空間。

綜上所述,Hash索引適用於等值查詢,具有固定的訪問時間,但不支持範圍查詢和排序操作。B+樹索引適用於範圍查詢、排序操作和模糊查詢,具有較好的順序訪問性能和穩定性,但訪問時間複雜度與樹的高度相關。選擇使用哪種索引結構取決於具體的應用需求和數據訪問模式。

5. 索引不適合哪些場景以及有哪些優缺點:

索引在大多數情況下可以顯著提高資料庫查詢的性能,但並不適合所有場景。以下是索引不適合的一些場景以及索引的一些優點和缺點:

索引不適合的場景:

  1. 低基數列: 當列中的唯一值較少時,例如性別列只有兩個可能的取值(男或女),建立索引可能不會帶來明顯的性能提升。在這種情況下,掃描整個表的代價可能比使用索引更低。
  2. 頻繁更新的列: 如果一個列經常被更新,索引的維護成本會很高。每次更新列的值時,可能需要更新索引數據結構,這會增加寫操作的開銷。頻繁更新的列可能會導致索引失去效益,甚至降低性能。
  3. 小表: 對於非常小的表,建立索引可能沒有太大意義。在小表中,全表掃描的代價可能相對較低,而使用索引進行查找可能會增加額外的開銷。

索引的優點:

  1. 加速查詢: 索引可以大大加速查詢操作,特別是在大型表中。通過使用索引,資料庫引擎可以快速定位滿足查詢條件的數據行,減少了全表掃描的需要。
  2. 支持排序和聚合操作: 索引可以使排序和聚合操作更高效。通過使用有序索引,資料庫引擎可以避免對整個表進行排序,從而提高操作的性能。
  3. 優化連接操作: 對於連接操作(如JOIN),索引可以幫助加速數據的查找和匹配,減少連接操作的成本。

索引的缺點:

  1. 占用存儲空間: 索引需要占用額外的存儲空間。對於大型表和多個索引的情況,索引可能占據相當大的存儲空間。
  2. 增加寫操作的開銷: 當插入、更新或刪除數據時,索引需要進行相應的維護操作,這會增加寫操作的開銷。如果頻繁進行寫操作,索引的維護成本可能會成為性能瓶頸。
  3. 索引選擇和調優困難: 在設計索引時,需要根據實際查詢模式和數據訪問模式進行權衡和選擇。選擇不當的索引或過多的索引可能會導致性能下降,而調優索引可能需要經驗和測試。

綜上所述,索引在大多數情況下是資料庫性能優化的重要工具,但在某些場景下可能不適用或需要謹慎使用。正確的索引設計和調優可以提高查詢性能,而錯誤的使用可能會導致額外的開銷和性能下降。

6.最左首碼匹配原則是什麼

最左首碼匹配原則是資料庫索引設計中的一個重要原則,它指出在使用複合索引(Composite Index)時,索引將按照索引鍵的順序進行匹配和檢索,並且只能利用索引的最左首碼來進行匹配。

具體來說,如果一個複合索引包含多個列(例如(A, B, C)),那麼在查詢時,最左首碼匹配原則要求查詢條件必須從索引的最左側開始,並且連續地匹配到索引的某個位置為止。也就是說,查詢條件可以是(A)、(A, B)或者(A, B, C),但不能是(B)、(C)或者(B, C)。

遵循最左首碼匹配原則的好處是可以最大程度地利用索引的有序性,提高查詢的效率。由於索引按照鍵的順序存儲,因此在查詢時只需定位到滿足最左首碼條件的索引位置,而不需要掃描整個索引。

舉個例子,假設有一個複合索引 (A, B, C),如果查詢條件是(A = 1),那麼索引可以用於加速查詢,因為最左首碼 (A) 匹配成功。但如果查詢條件是(B = 2),即使索引中包含了列 B,也無法利用索引進行加速,因為最左首碼不匹配。

需要註意的是,最左首碼匹配原則並不意味著只有最左側的列可以使用索引,而是強調索引的有序性和連續性。在某些情況下,可以通過創建單列索引或調整索引順序來更好地利用索引。

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 上篇文章講述了[C#委托和事件知識點](http://mp.weixin.qq.com/s?__biz=MzI2NDE1MDE1MQ==&mid=2650851553&idx=1&sn=b1c601eaf4bb4f2898cbd418fa0ae426&chksm=f1456509c632ec1f8f ...
  • 基本屬性: 屬性 說明 描述 Color 設置陰影效果背景色 Color="Red" ShadowDepth 設置陰影的偏移度 ShadowDepth="5" Direction 設置陰影的角度 Direction="-45" BlurRadius 設置陰影模糊程度 BlurRadius="20" ...
  • [toc] # Linux運維工程師面試題(7) > 祝各位小伙伴們早日找到自己心儀的工作。 > 持續學習才不會被淘汰。 > 地球不爆炸,我們不放假。 > 機會總是留給有有準備的人的。 > 加油,打工人! ## 1 常用的 ansible 模塊有哪些 - Ping - Command - Shell ...
  • 1.禁用swap分區 swapoff -a && sysctl -w vm.swappiness=0 sed -ri '/^[^#]*swap/s@^@#@' /etc/fstab grep swap /etc/fstab 2. 禁用防火牆和selinux 2.1禁用防火牆,網路管理,郵箱 1 sy ...
  • 《Linux內核設計與實現(第三版)》中所用的內核版本為2.6.34,這個版本太舊了,在高版本系統中編譯各種不支持,所以選了Ubuntu 14.04進行編譯。 編譯準備 編譯環境:Ubuntu 14.04 GCC版本:4.8.4 編譯的內核版本:Linux 2.6.34 內核源碼下載:https:/ ...
  • 最近在進行免殺的學習,在《黑客免殺攻防》這本書中找到了非常好的關於PE文件的描述,雖然書比較古老的,但是裡面的內容是非常精細和優秀的。它的附頁中有非常清晰的PE文件結構圖,可是翻看比較麻煩,撕下來又可惜,於是我今天對著附頁的圖用excel重新畫了一個。這些工作我平時做的比較少,所以消耗了比較久的時間 ...
  • 本文主要討論了操作系統中文件系統的實現和分配方式。首先介紹了虛擬文件系統(VFS)作為中間層,統一了不同文件系統的介面。然後介紹了文件的物理結構,包括文件塊和邏輯塊之間的映射關係。接著詳細討論了連續分配方式的特點和優缺點,包括順序訪問和隨機訪問的效率,以及磁碟空間碎片和文件長度擴展不方便的問題。最後... ...
  • ![](https://img2023.cnblogs.com/blog/3076680/202309/3076680-20230904205926819-1818911722.png) # 1. 時區 ## 1.1. 大航海時代伊始就在和時差打交道,而電腦時代的到來加劇了這一問題 ## 1.2. ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...