JavaRush /Java Blog /Random-TW /開發者面試:資料庫問題分析

開發者面試:資料庫問題分析

在 Random-TW 群組發布
大家好!我們都在這裡為一個目標而努力——成為Java 開發人員。也許成為專業人士道路上最重要的階段是技術面試。通常,面試官會瀏覽主要話題,並提出幾個問題。在這篇文章中,我們將討論這樣一個關鍵主題—資料庫。讓我們看看最常見的問題,並嘗試在不深入研究材料的情況下回答它們,因為在這種情況下,這本書的體積對我們來說是不夠的!那麼,我們走吧。開發者面試:資料庫問題分析 - 1

1.什麼是資料庫?它們又分為哪些類型呢?

DBMS 是什麼意思?

開發者面試:資料庫問題分析—2資料庫 (DB)是一種有組織的結構,設計用於儲存、變更和處理相關資訊(主要是大容量資訊)。換句話說,資料庫是結構化資料儲存。例如,電話簿。

資料庫類型

  1. 關係資料庫是資料的集合,它們之間具有預先定義的關係。資料儲存為一組由列和行組成的表。表格儲存有關資料庫中表示的物件的資訊。每個表格列儲存特定的資料類型,每個儲存格儲存一個屬性值。
  2. 非關係系統(NoSQL)是為具有靈活模式的特定資料模型而設計的系統。換句話說,這些資料庫不是以表格方案、行和列的形式儲存數據,而是以其他格式儲存數據。
您可以在本文中閱讀更多有關非關聯式資料庫的資訊:NoSQL 開發人員指南資料庫管理系統(DBMS)是一套軟體,使用者可以使用它來建立資料庫(DB)並對其執行各種操作:補充、更新、刪除、選擇等。DBMS保證資料的安全性、完整性、安全性存儲並允許您授予對資料庫管理的存取權限。例如,MySql 是一種 DBMS,它提供對關聯式資料庫或非關聯式資料庫的 MongoDB 的存取。

2.什麼是標準化?標準化形式?標準化有多少種形式?說出前三個的名稱。

規範化是在資料庫中組織和建構資料的過程,它透過消除依賴關係的冗餘和不一致來提供更大的資料庫靈活性。 範式是表的一個屬性,在規範化的背景下考慮,它在結構的簡單性和正確性方面表徵了表。範式被定義為表必須滿足的一組要求。總共有六種範式,但在實務上只使用前三種:
  1. 第一範式:
    • 所有屬性都是簡單的(即原子且不可分割);
    • 所有數據都是標量(即正數);
    • 沒有重複的行(為此,為每行建立一個主鍵)。
  2. 第二範式:
    • 滿足第一範式的條件;
    • 每個非鍵屬性都引用一個主鍵。
  3. 第三範式:
    • 滿足第二正常組的條件;
    • 非鍵字段獨立於其他非鍵字段:它們只能與主鍵關聯。

3. 非規範化

非規範化是故意減少或違反資料庫規範化的形式,通常是透過添加冗餘資料來加快從資料庫的讀取速度。一般來說,這是一個與標準化相反的過程。發生這種情況是因為範式理論並不總是適用於實踐。例如,非原子值並不總是“邪惡的”:有時甚至相反。在某些情況下,執行查詢時,特別是處理大量資訊時,需要額外的聯結。這最終可以提高性能。用於分析的資料庫通常會被非規範化,以加快查詢執行速度。例如,您經常會對報表中的一些資料進行取樣,其中非關鍵列彼此相關。您有意刪除第三種形式的標準化,並將所有內容合併到一個表中以便於採樣 - 這樣您就不必對其他表進行額外的查詢。

4. 索引

索引是與具有特定列的表或視圖關聯的一組排序值,可加速資料檢索。也就是說,這是一種索引:就像電話簿中的字母一樣,可以幫助我們按姓氏進行搜尋。如果使用得當,此功能可以大大提高處理大型資料庫時的效能。或者你可以降低很多。為了加快搜尋速度,這些關鍵字儲存在平衡樹結構中,並透過該結構執行搜尋。通常,需要在最常搜尋的欄位上輸入索引。當您擁有至少 10,000 筆記錄時,您應該考慮建立索引。否則,您將看不到明顯的結果,因為過早的優化是邪惡的。您可能會問,索引如何影響系統效能?當插入新資料或刪除舊資料時,平衡樹結構將重新計算。實際上,資料和索引越多,需要統計的樹就越多。想像一下這種情況:這張表上有大約 20,000 筆記錄和 7 個索引。即插入資料時,需要重新計算7棵樹,每棵樹有20000筆記錄。嚴格來說,對於經常增刪資料的表,完全不建議使用索引。最後,我想指出的是,經常在其中找到值的列的索引null不會那麼有效,因此不值得將它們添加到此類列中。

SQL中聚集索引和非聚集索引有什麼不同?

聚類:

  • 提供所選欄位的物理順序;
  • 如果一個表有聚集索引,則稱為聚集索引;
  • 每個表不需要超過一個索引;
  • 在MySQL中,聚集索引不是由使用者明確指定的,因為如果你沒有在表上定義主鍵,MySQL會找到UNIQUE所有鍵列所在的第一個索引NOT NULL,而InnoDB將其用作聚集索引。

非集群:

  • 單一表上最多可以有 999 個非聚集索引;
  • 包含指向表中包含實際資料的行的指標;
  • 不提供實體訂單;
  • 對於非聚集索引來說,資料是有序的,有單獨的表,即索引所在的一列一張表,因此,當請求不屬於給定欄位的資料時,會首先在該欄位上進行查詢。該表中的字段,然後才針對原始表中的行進行附加查詢。
建立非聚集索引:
CREATE INDEX index_name ON table_name(column_name)

6. 什麼是綜合指數?

複合索引- 透過同時傳送到多個列來建構。換句話說,它是一個由多個列組成的複雜索引。當一個查詢中出現多於一列時,將使用此類索引。建立複合索引:
CREATE INDEX index_name ON table_name(first_column_name, second_column_name, third_column_name)
通常,當多列中的資料在邏輯上相關時使用這些索引。

7. 什麼是覆蓋索引?唯一索引?

覆蓋索引是一種足以回答查詢而無需存取表本身的索引。使用這個索引,你可以得到整行數據,但實際上這是根本不必要的。因為您不必直接存取來源表並且可以僅使用索引來回答,所以使用覆蓋索引會稍微快一些。同時,不要忘記列越多,索引本身就會變得越麻煩、越慢。所以你不應該濫用這個。上面我們講了聚集索引和非聚集索引,它們可以是唯一的。這意味著沒有兩個欄位具有相同的索引鍵值。否則,索引將不是唯一的,因為多行可能包含相同的值。建立唯一非聚集索引的範例:
CREATE UNIQUE INDEX index_name ON table_name(column_name)

8.什麼是主鍵

主鍵是表中的一個字段,用於標識資料庫表中的每一行。一張表中只能有一個這樣的字段,而且所有值必須是唯一的。沒有提醒你什麼嗎?開發者面試:資料庫問題分析 - 3畢竟,主鍵只不過是一個唯一的聚集索引。通常,主鍵是在建立表格時建立的:
CREATE TABLE table_name(
column_name int PRIMARY KEY,..)
限制將自動新增至此列 - NOT NULL。您也可以為已建立的表設定鍵:
ALTER TABLE table_name ADD PRIMARY KEY (column_name);
如果按照上述方式新增主鍵,則會檢查指定為主鍵 ( column_name) 的欄位的值,以確保它們不包含空值(也會新增約束 - NOT NULL)。

什麼是外鍵?

外鍵是為提供表之間的關係而建立的屬性。通常,外鍵設定在子表中的列上,並指向主表中的其中一個欄位。可以在建立表格時指定為:
CREATE TABLE table_name{
column_name int,..
FOREIGN KEY(column_name) REFERENCES another_table_name(another_table_column_name) }
所以創建表後:
ALTER TABLE table_name
ADD FOREIGN KEY(column_name) REFERENCES another_table_name(another_table_column_name));
您可以在操作外鍵引用的欄位時設定外鍵的行為。操作可以有以下ON DELETE類型ON UPDATE:可能的行為選項:
  • CASCADE— 使用此屬性,當主表中刪除或變更相關行時,從屬表中的行將自動刪除或變更;
  • SET NULL— 使用此屬性,當從主表中刪除或更新相關行時,NULL將設定外鍵列的值;
  • NO ACTION— 如果從屬表中存在相關行,則拒絕嘗試刪除或更改主表中的行;
  • RESTRICT- 相當於NO ACTION;
  • SET DEFAULT- 使用此屬性,當從主表中刪除或更新相關行時,將設定外鍵列的預設值(如果有)。
使用範例:
CREATE TABLE table_name{
column_name int,..
FOREIGN KEY(column_name) REFERENCES another_table_name(another_table_column_name) ON UPDATE CASCADE ON DELETE CASCADE }
ON DELETE如果和的行為 未明確設置ON UPDATE,則行為將設置為RESTRICT

10.表格之間的連接類型(Join)

表之間的連接是基於公共資料(欄位)提供的。這是使用 運算子 來實現的JOIN,該運算子將一個表中的行與另一個表中的行進行配對。完成映射後,兩個表的列是相鄰的,儘管它們可以從單獨的表中取得。如果我們有三個表的公共字段,我們可以將它們的資料顯示為一張公共表。但是,值得考慮的是,連線的表越少,查詢運行的速度就越快。所以,類型JOIN
  • INNER JOIN- 僅顯示第一個表中與第二個表中的某些資料對應的那些資料的連接。其餘的都下降。開發者面試:資料庫問題分析—4
  • LEFT JOIN- 顯示第一個表中的所有資料以及第二個表中的相應資料(如果有)的連接。如果沒有對應的數據,則第二個表的資料欄位將為空。開發者訪談:資料庫問題分析 - 5
  • RIGHT JOIN- 顯示第二個表中的所有資料以及第一個表中的相應資料(如果有)的連接。如果沒有對應的數據,則第一個表中的資料欄位將為空。開發者面試:資料庫問題分析——6
  • FULL JOIN- 顯示第一個和第二個表中的所有資料的連接。如果另一個表中沒有相關數據,則該數據的欄位將為空。開發者訪談:資料庫問題分析 - 7
  • CROSS JOIN- 交叉聯接,其中第一個表的每一行都聯接到第二個表的每一行(每個到每個)。也就是說,如果兩個表各有 3 行,那麼在這次連接之後我們將得到 9 行的結果。開發者面試:資料庫問題分析 - 8
例子Join(inner)
SELECT *
FROM first_table
INNER JOIN second_table ON first_table.some_column = second_table.some_column

11.什麼是資料庫中的 ACID 屬性?

A - 原子性,確保沒有事務部分提交給系統。要么執行其所有子操作,要么不執行。例如,將錢從銀行轉移到另一個帳戶涉及兩個操作:
  1. 將錢轉入銀行帳戶。
  2. 將資金從銀行帳戶轉移到特定帳戶。
但任何事情都有可能發生。例如,他們會去銀行,然後會發生一些錯誤,第二個操作將無法完成。反之亦然:僅執行第二個操作。因此,這些操作是在一筆交易中執行的,其結果要么全部,要么全無。 C - 一致性:每筆成功的交易總是只記錄可解析的結果。這可確保滿足所有限制(例如NOT NULL),否則交易將回滾。 和 - 隔離:在事務執行期間,並行事務不應影響其結果。這使我們能夠向所有人隱藏非最終資料狀態。實際上,這就是為什麼不成功的交易不會破壞任何東西。稍微低一點我們就會熟悉事務隔離等級。 D - 持久性:如果交易完成,那麼您可以確定它所做的更改不會因為某些故障而被取消。

12. 事務隔離級別

每個隔離等級允許/禁止某些操作(機會):
  • 幻讀- 在同一事務內,相同的資料請求給出不同的結果,這是由於另一個(並行)事務添加資料而發生的。
  • 非重複讀取- 在同一事務內,相同的資料請求給出不同的結果,這是由於另一個(並行)事務更改或刪除資料而發生的。
  • 「髒」讀取-讀取由事務添加或更改的數據,隨後不會回滾;
  • 遺失更新- 當不同事務同時更改相同資料區塊時,除了最後一個之外的所有變更都會遺失(類似於多執行緒中的「競爭條件」)。
為了方便起見,我們在表中考慮隔離等級及其功能:
絕緣等級 幻讀 不重複閱讀 「髒」讀 遺失更新
可串列化 + + + +
可重複讀取 - + + +
已提交讀 - - + +
READ_UNCOMMITTED - - - +

13.什麼是SQL注入?

SQL注入GET是駭客攻擊網站的方法之一,其本質是透過查詢或Cookies將一些SQL程式碼注入到資料中POST。如果網站執行此類注入,則有可能獲得對資料庫的存取權並破解應用程式。例如,我們知道某個變數的名稱。讓我們column_name用 type來說boolean。如果系統容易受到注入,我們可以新增OR column_name=true然後寫入資料庫中我們需要的所有內容。OR將創建一個 OR 條件,並且它後面的表達式將始終是true,這將帶我們走得更遠。由於對 SQL 查詢中使用的傳入資料處理不當,可能會出現 SQL 注入等網站攻擊。使用JDBC連接到資料庫時,您可以使用各種Statements. 為了提高安全性,有必要使用PreparedStatement而不是通常的Statement,因為使用時,Statement查詢字串和值只是簡單地添加在一起,使得注入成為可能。反過來,有PreparedStatement一個特定的請求模板,資料插入其中,並反映引號。因此,SQL 注入將僅被視為某個欄位的字串表示形式。為了防止 SQL 注入,您可以使用基於正規表示式的檢查(您可以在本文中閱讀有關正規表示式的更多資訊)。Собеседование разработчика: разбор вопросов по базам данных - 9另一種選擇是對傳入參數的字元數設定限制:例如,如果您應該接收不超過 9999 的數字,則限制為四個傳入字元即可。它將降低使用 SQL 注入進行駭客攻擊的風險。您可以從文章《Java 安全性:最佳實踐》中了解有關 Java 安全性的更多資訊。

14.什麼是預存程序?存儲函數?扳機?

SQL中的預存程序是資料庫中的一個實體,是一組一次性編譯並儲存在伺服器上的SQL指令。簡而言之,這類似於 Java 中的方法。預存程序可以對資料執行操作,包括普通查詢和一些普通查詢無法執行的操作。過程是一個 SQL 實體,創建一次,然後透過傳遞參數進行呼叫。這種方法的優點是這些指令可以重複使用多次。預存程序可提高效能、增強程式設計能力並支援資料安全功能。讓我們考慮創建一個過程:
CREATE PROCEDURE procedure_name (first_param some_type, second_param some_type..)
 begin
……...
 end
調用過程:
CALL procedure_name (first_param, second_param…..);
儲存函數是預存程序的一種。函數之間的差異在於它始終僅傳回單一值,而過程會傳回一組值。預存程序不能與常規 SQL 混合,但儲存函數可以 - 這就是它的優點。另一方面,儲存函數比過程有更多的限制。建立儲存函數:
CREATE FUNCTION function_name (first_param, second_param…..)
RETURNS some_type
 begin
……...
RETURN some_value;
end
呼叫存儲的函數:
SELECT function_name(first_param, second_param…..);
觸發器是另一種類型的預存過程,它不是由使用者直接調用,而是在資料修改時啟動。也就是說,當滿足某些條件時,例如 、INSERTDELETE、 或UPDATE給定表的某一列中的數據,該過程被啟動。使用關鍵字BEFORE(觸發器在關聯事件之前觸發)或AFTER(事件之後)確定何時觸發觸發器。
CREATE TRIGGER trigger_name
ON table_name
AFTER INSERT
 begin
……...
 end

15. 練習

儘管如此,面試中最常見的 SQL 問題是練習 - 解決問題。試著猜測你會遇到哪些任務是沒有意義的,因為一切都取決於對方想像的複雜程度。因此,唯一可行的選擇是更好地處理不同複雜度的 SQL 查詢。sql-ex.ru可以作為練習各種任務的資源。在完成前 20 個任務之後,對話者就很難用任何 SQL 任務來嚇唬您了。Собеседование разработчика: разбор вопросов по базам данных - 11今天就到這裡了:希望讀完這篇文章後,有關資料庫的問題不會造成任何困難或問題。感謝您的關注,再次見到您!
留言
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION