数据库面试题---原理
1、觸發(fā)器的作用?
觸發(fā)器是一中特殊的存儲過程,主要是通過事件來觸發(fā)而被執(zhí)行的。它可以強化約束,來維護數(shù)據(jù)的完整性和一致性,可以跟蹤數(shù)據(jù)庫內(nèi)的操作從而不允許未經(jīng)許可的更新和變化。可以聯(lián)級運算。如,某表上的觸發(fā)器上包含對另一個表的數(shù)據(jù)操作,而該操作又會導(dǎo)致該表觸發(fā)器被觸發(fā)。
2、什么是存儲過程?用什么來調(diào)用?
存儲過程是一個預(yù)編譯的SQL語句,優(yōu)點是允許模塊化的設(shè)計,就是說只需創(chuàng)建一次,以后在該程序中就可以調(diào)用多次。如果某次操作需要執(zhí)行多次SQL,使用存儲過程比單純SQL語句執(zhí)行要快。可以用一個命令對象來調(diào)用存儲過程。
3、索引的作用?和它的優(yōu)點缺點是什么?
索引就一種特殊的查詢表,數(shù)據(jù)庫的搜索引擎可以利用它加速對數(shù)據(jù)的檢索。它很類似與現(xiàn)實生活中書的目錄,不需要查詢整本書內(nèi)容就可以找到想要的數(shù)據(jù)。索引可以是唯一的,創(chuàng)建索引允許指定單個列或者是多個列。缺點是它減慢了數(shù)據(jù)錄入的速度,同時也增加了數(shù)據(jù)庫的尺寸大小。
4、什么是內(nèi)存泄漏?
一般我們所說的內(nèi)存泄漏指的是堆內(nèi)存的泄漏。堆內(nèi)存是程序從堆中為其分配的,大小任意的,使用完后要顯示釋放內(nèi)存。當(dāng)應(yīng)用程序用關(guān)鍵字new等創(chuàng)建對象時,就從堆中為它分配一塊內(nèi)存,使用完后程序調(diào)用free或者delete釋放該內(nèi)存,否則就說該內(nèi)存就不能被使用,我們就說該內(nèi)存被泄漏了。
5、維護數(shù)據(jù)庫的完整性和一致性,你喜歡用觸發(fā)器還是自寫業(yè)務(wù)邏輯?為什么?
我是這樣做的,盡可能使用約束,如check,主鍵,外鍵,非空字段等來約束,這樣做效率最高,也最方便。其次是使用觸發(fā)器,這種方法可以保證,無論什么業(yè)務(wù)系統(tǒng)訪問數(shù)據(jù)庫都可以保證數(shù)據(jù)的完整新和一致性。最后考慮的是自寫業(yè)務(wù)邏輯,但這樣做麻煩,編程復(fù)雜,效率低下。
6、什么是事務(wù)?什么是鎖?
事務(wù)就是被綁定在一起作為一個邏輯工作單元的SQL語句分組,如果任何一個語句操作失敗那么整個操作就被失敗,以后操作就會回滾到操作前狀態(tài),或者是上有個節(jié)點。為了確保要么執(zhí)行,要么不執(zhí)行,就可以使用事務(wù)。要將有組語句作為事務(wù)考慮,就需要通過ACID測試,即原子性,一致性,隔離性和持久性。
鎖:在所以的DBMS中,鎖是實現(xiàn)事務(wù)的關(guān)鍵,鎖可以保證事務(wù)的完整性和并發(fā)性。與現(xiàn)實生活中鎖一樣,它可以使某些數(shù)據(jù)的擁有者,在某段時間內(nèi)不能使用某些數(shù)據(jù)或數(shù)據(jù)結(jié)構(gòu)。當(dāng)然鎖還分級別的。
7、什么叫視圖?游標是什么?
答:視圖是一種虛擬的表,具有和物理表相同的功能。可以對視圖進行增,改,查,操作,試圖通常是有一個表或者多個表的行或列的子集。對視圖的修改不影響基本表。它使得我們獲取數(shù)據(jù)更容易,相比多表查詢。
游標:是對查詢出來的結(jié)果集作為一個單元來有效的處理。游標可以定在該單元中的特定行,從結(jié)果集的當(dāng)前行檢索一行或多行。可以對結(jié)果集當(dāng)前行做修改。一般不使用游標,但是需要逐條處理數(shù)據(jù)的時候,游標顯得十分重要。
8、你能向我簡要敘述一下SQL Server 中使用的一些數(shù)據(jù)庫對象嗎?
表、索引、視圖、存儲過程、觸發(fā)器、用戶定義函數(shù)、數(shù)據(jù)庫關(guān)系圖、全文索引。
9、NULL是什么意思?
NULL(空)這個值表示UNKNOWN(未知):它不表示“”(空字符串)。假設(shè)您的SQL Server數(shù)據(jù)庫里有ANSI_NULLS,當(dāng)然在默認情況下會有,對NULL這個值的任何比較都會生產(chǎn)一個NULL值。您不能把任何值與一個 UNKNOWN值進行比較,并在邏輯上希望獲得一個答案。您必須使用IS NULL操作符。
10、什么是索引?SQL Server 里有什么類型的索引?
?簡單地說,索引是一個數(shù)據(jù)結(jié)構(gòu),用來快速訪問數(shù)據(jù)庫表格或者視圖里的數(shù)據(jù)。在SQL Server里,它們有兩種形式:聚集索引和非聚集索引。聚集索引在索引的葉級保存數(shù)據(jù)。這意味著不論聚集索引里有表格的哪個(或哪些)字段,這些字段都會按順序被保存在表格。由于存在這種排序,所以每個表格只會有一個聚集索引。非聚集索引在索引的葉級有一個行標識符。這個行標識符是一個指向磁盤上數(shù)據(jù)的指針。它允許每個表格有多個非聚集索引。
11、什么是主鍵?什么是外鍵?
主鍵是表格里的(一個或多個)字段,只用來定義表格里的行;主鍵里的值總是唯一的。外鍵是一個用來建立兩個表格之間關(guān)系的約束。這種關(guān)系一般都涉及一個表格里的主鍵字段與另外一個表格(盡管可能是同一個表格)里的一系列相連的字段。那么這些相連的字段就是外鍵。
12、什么是觸發(fā)器?SQL Server 有什么不同類型的觸發(fā)器?
觸發(fā)器是一種專用類型的存儲過程,它被捆綁到SQL Server 的表格或者視圖上。在SQL Server 2000里,有INSTEAD-OF和AFTER兩種觸發(fā)器。INSTEAD-OF觸發(fā)器是替代數(shù)據(jù)操控語言(Data Manipulation?Language,DML)語句對表格執(zhí)行語句的存儲過程。例如,如果我有一個用于TableA的INSTEAD-OF-UPDATE觸發(fā)器,同時對這個表格執(zhí)行一個更新語句,那么INSTEAD-OF-UPDATE觸發(fā)器里的代碼會執(zhí)行,而不是我執(zhí)行的更新語句則不會執(zhí)行操作。AFTER觸發(fā)器要在DML語句在數(shù)據(jù)庫里使用之后才執(zhí)行。這些類型的觸發(fā)器對于監(jiān)視發(fā)生在數(shù)據(jù)庫表格里的數(shù)據(jù)變化十分好用。
13、您如何確保一個帶有名為Fld1字段的TableB表格里只具有Fld1字段里的那些值,而這些值同時在名為TableA的表格的Fld1字段里?
這個與關(guān)系相關(guān)的問題有兩個可能的答案。
第一個答案是使用外鍵限制。外鍵限制用來維護引用的完整性。它被用來確保表格里的字段只保存有已經(jīng)在不同的(或者相同的)表格里的另一個字段里定義了的值。這個字段就是候選鍵(通常是另外一個表格的主鍵)。
另外一種答案是觸發(fā)器。觸發(fā)器可以被用來保證以另外一種方式實現(xiàn)與限制相同的作用,但是它非常難設(shè)置與維護,而且性能一般都很糟糕。由于這個原因,微軟建議開發(fā)人員使用外鍵限制而不是觸發(fā)器來維護引用的完整性。
14、對一個投入使用的在線事務(wù)處理表格有過多索引需要有什么樣的性能考慮?
?對一個表格的索引越多,數(shù)據(jù)庫引擎用來更新、插入或者刪除數(shù)據(jù)所需要的時間就越多,因為在數(shù)據(jù)操控發(fā)生的時候索引也必須要維護。
15、你可以用什么來確保表格里的字段只接受特定范圍里的值?
這個問題可以用多種方式來回答,但是只有一個答案是“好”答案是Check限制,它在數(shù)據(jù)庫表格里被定義,用來限制輸入該列的值。
觸發(fā)器也可以被用來限制數(shù)據(jù)庫表格里的字段能夠接受的值,但是這種辦法要求觸發(fā)器在表格里被定義,這可能會在某些情況下影響到性能。因此,微軟建議使用Check限制而不是其他的方式來限制域的完整性。
16、使用存儲過程的經(jīng)驗。
返回參數(shù)總是由存儲過程返回,它用來表示存儲過程是成功還是失敗。返回參數(shù)總是INT數(shù)據(jù)類型。
OUTPUT參數(shù)明確要求由開發(fā)人員來指定,它可以返回其他類型的數(shù)據(jù),例如字符型和數(shù)值型的值。(可以用作輸出參數(shù)的數(shù)據(jù)類型是有一些限制的。)您可以在一個存儲過程里使用多個OUTPUT參數(shù),而您只能夠使用一個返回參數(shù)。
17、什么是相關(guān)子查詢?如何使用這些查詢?
相關(guān)子查詢是一種包含子查詢的特殊類型的查詢。查詢里包含的子查詢會真正請求外部查詢的值,從而形成一個類似于循環(huán)的狀況。
18、什么是SQL注入式攻擊?
所謂SQL注入式攻擊,就是攻擊者把SQL命令插入到Web表單的輸入域或頁面請求的查詢字符串,欺騙服務(wù)器執(zhí)行惡意的SQL命令。在某些表單中,用戶輸入的內(nèi)容直接用來構(gòu)造(或者影響)動態(tài)SQL命令,或作為存儲過程的輸入?yún)?shù),這類表單特別容易受到SQL注入式攻擊。常見的SQL注入式攻擊過程類如:
⑴ 某個ASP.NET Web應(yīng)用有一個登錄頁面,這個登錄頁面控制著用戶是否有權(quán)訪問應(yīng)用,它要求用戶輸入一個名稱和密碼。
⑵ 登錄頁面中輸入的內(nèi)容將直接用來構(gòu)造動態(tài)的SQL命令,或者直接用作存儲過程的參數(shù)。下面是ASP.NET應(yīng)用構(gòu)造查詢的一個例子:
System.Text.StringBuilder query = new System.Text.StringBuilder(
"SELECT * from Users WHERE login = '")
.Append(txtLogin.Text).Append("' AND password='")
.Append(txtPassword.Text).Append("'");
⑶ 攻擊者在用戶名字和密碼輸入框中輸入"'或'1'='1"之類的內(nèi)容。
⑷ 用戶輸入的內(nèi)容提交給服務(wù)器之后,服務(wù)器運行上面的ASP.NET代碼構(gòu)造出查詢用戶的SQL命令,但由于攻擊者輸入的內(nèi)容非常特殊,所以最后得到的SQL命令變成:SELECT * from Users WHERE login = '' or '1'='1' AND password = '' or '1'='1'。
⑸ 服務(wù)器執(zhí)行查詢或存儲過程,將用戶輸入的身份信息和服務(wù)器中保存的身份信息進行對比。
⑹ 由于SQL命令實際上已被注入式攻擊修改,已經(jīng)不能真正驗證用戶身份,所以系統(tǒng)會錯誤地授權(quán)給攻擊者。
如果攻擊者知道應(yīng)用會將表單中輸入的內(nèi)容直接用于驗證身份的查詢,他就會嘗試輸入某些特殊的SQL字符串篡改查詢改變其原來的功能,欺騙系統(tǒng)授予訪問權(quán)限。
系統(tǒng)環(huán)境不同,攻擊者可能造成的損害也不同,這主要由應(yīng)用訪問數(shù)據(jù)庫的安全權(quán)限決定。如果用戶的帳戶具有管理員或其他比較高級的權(quán)限,攻擊者就可能對數(shù)據(jù)庫的表執(zhí)行各種他想要做的操作,包括添加、刪除或更新數(shù)據(jù),甚至可能直接刪除表。
19、如何防范SQL注入式攻擊?
好在要防止ASP.NET應(yīng)用被SQL注入式攻擊闖入并不是一件特別困難的事情,只要在利用表單輸入的內(nèi)容構(gòu)造SQL命令之前,把所有輸入內(nèi)容過濾一番就可以了。過濾輸入內(nèi)容可以按多種方式進行。
⑴ 對于動態(tài)構(gòu)造SQL查詢的場合,可以使用下面的技術(shù):
第一:替換單引號,即把所有單獨出現(xiàn)的單引號改成兩個單引號,防止攻擊者修改SQL命令的含義。再來看前面的例子,"SELECT * from Users WHERE login = ''' or ''1''=''1' AND password = ''' or ''1''=''1'"顯然會得到與"SELECT * from Users WHERE login = '' or '1'='1' AND password = '' or '1'='1'"不同的結(jié)果。
第二:刪除用戶輸入內(nèi)容中的所有連字符,防止攻擊者構(gòu)造出類如"SELECT * from Users WHERE login = 'mas' -- AND password =''"之類的查詢,因為這類查詢的后半部分已經(jīng)被注釋掉,不再有效,攻擊者只要知道一個合法的用戶登錄名稱,根本不需要知道用戶的密碼就可以順利獲得訪問權(quán)限。
第三:對于用來執(zhí)行查詢的數(shù)據(jù)庫帳戶,限制其權(quán)限。用不同的用戶帳戶執(zhí)行查詢、插入、更新、刪除操作。由于隔離了不同帳戶可執(zhí)行的操作,因而也就防止了原本用于執(zhí)行SELECT命令的地方卻被用于執(zhí)行INSERT、UPDATE或DELETE命令。
⑵ 用存儲過程來執(zhí)行所有的查詢。SQL參數(shù)的傳遞方式將防止攻擊者利用單引號和連字符實施攻擊。此外,它還使得數(shù)據(jù)庫權(quán)限可以限制到只允許特定的存儲過程執(zhí)行,所有的用戶輸入必須遵從被調(diào)用的存儲過程的安全上下文,這樣就很難再發(fā)生注入式攻擊了。
⑶ 限制表單或查詢字符串輸入的長度。如果用戶的登錄名字最多只有10個字符,那么不要認可表單中輸入的10個以上的字符,這將大大增加攻擊者在SQL命令中插入有害代碼的難度。
⑷ 檢查用戶輸入的合法性,確信輸入的內(nèi)容只包含合法的數(shù)據(jù)。數(shù)據(jù)檢查應(yīng)當(dāng)在客戶端和服務(wù)器端都執(zhí)行——之所以要執(zhí)行服務(wù)器端驗證,是為了彌補客戶端驗證機制脆弱的安全性。
在客戶端,攻擊者完全有可能獲得網(wǎng)頁的源代碼,修改驗證合法性的腳本(或者直接刪除腳本),然后將非法內(nèi)容通過修改后的表單提交給服務(wù)器。因此,要保證驗證操作確實已經(jīng)執(zhí)行,唯一的辦法就是在服務(wù)器端也執(zhí)行驗證。你可以使用許多內(nèi)建的驗證對象,例如 RegularExpressionValidator,它們能夠自動生成驗證用的客戶端腳本,當(dāng)然你也可以插入服務(wù)器端的方法調(diào)用。如果找不到現(xiàn)成的驗證對象,你可以通過CustomValidator自己創(chuàng)建一個。
⑸ 將用戶登錄名稱、密碼等數(shù)據(jù)加密保存。加密用戶輸入的數(shù)據(jù),然后再將它與數(shù)據(jù)庫中保存的數(shù)據(jù)比較,這相當(dāng)于對用戶輸入的數(shù)據(jù)進行了"消毒"處理,用戶輸入的數(shù)據(jù)不再對數(shù)據(jù)庫有任何特殊的意義,從而也就防止了攻擊者注入SQL命令。 System.Web.Security.FormsAuthentication類有一個HashPasswordForStoringInConfigFile,非常適合于對輸入數(shù)據(jù)進行消毒處理。
⑹ 檢查提取數(shù)據(jù)的查詢所返回的記錄數(shù)量。如果程序只要求返回一個記錄,但實際返回的記錄卻超過一行,那就當(dāng)作出錯處理。
20、如何實現(xiàn)數(shù)據(jù)庫的移動?
1)分離數(shù)據(jù)庫;2)把數(shù)據(jù)文件、日志文件移動到其他路徑上去;3)在另一臺計算機上進行附加。
21、默認的系統(tǒng)數(shù)據(jù)庫有哪些?
1)master數(shù)據(jù)庫(主);2)tempdb數(shù)據(jù)庫(臨時);3)model 數(shù)據(jù)庫(模板);4)msdb數(shù)據(jù)庫(計劃任務(wù));
22、默認創(chuàng)建一個數(shù)據(jù)庫,會生成哪些文件?
1)主文件(.mdf),2)日志文件(.ldf),無次要文件(.ndf)。
23、創(chuàng)建數(shù)據(jù)庫時,能不能把數(shù)據(jù)文件和日志文件分開?
可以分開,起到優(yōu)化作用。把數(shù)據(jù)文件放到高速讀寫區(qū),把日志文件放到低速讀寫區(qū)。
24、什么是索引覆蓋(Index Covering)查詢??
索引覆蓋(Index Covering)查詢是指數(shù)據(jù)可以只通過索引獲取,而不用接觸表。
25、事務(wù)是什么??
事務(wù)是作為一個邏輯單元執(zhí)行的一系列操作,一個邏輯工作單元必須有四個屬性,稱為 ACID(原子性、一致性、隔離性和持久性)屬性,只有這樣才能成為一個事務(wù):
1)原子性
事務(wù)必須是原子工作單元;對于其數(shù)據(jù)修改,要么全都執(zhí)行,要么全都不執(zhí)行。
2)一致性
事務(wù)在完成時,必須使所有的數(shù)據(jù)都保持一致狀態(tài)。在相關(guān)數(shù)據(jù)庫中,所有規(guī)則都必須應(yīng)用于事務(wù)的修改,以保持所有數(shù)據(jù)的完整性。事務(wù)結(jié)束時,所有的內(nèi)部數(shù)據(jù)結(jié)構(gòu)(如 B 樹索引或雙向鏈表)都必須是正確的。
3)隔離性
由并發(fā)事務(wù)所作的修改必須與任何其它并發(fā)事務(wù)所作的修改隔離。事務(wù)查看數(shù)據(jù)時數(shù)據(jù)所處的狀態(tài),要么是另一并發(fā)事務(wù)修改它之前的狀態(tài),要么是另一事務(wù)修改它之后的狀態(tài),事務(wù)不會查看中間狀態(tài)的數(shù)據(jù)。這稱為可串行性,因為它能夠重新裝載起始數(shù)據(jù),并且重播一系列事務(wù),以使數(shù)據(jù)結(jié)束時的狀態(tài)與原始事務(wù)執(zhí)行的狀態(tài)相同。
4)持久性
事務(wù)完成之后,它對于系統(tǒng)的影響是永久性的。該修改即使出現(xiàn)系統(tǒng)故障也將一直保持。
總結(jié)
以上是生活随笔為你收集整理的数据库面试题---原理的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 制作镜像包时遇到的模块加载错误的问题
- 下一篇: js正则表达式匹配span标签