數據庫專題

第十章 數據庫專題

10.1. 如何獲取當前數據庫版本?

答:運行 SQL SERVER 服務管理器,在任務欄小托盤處,右鍵單擊管理器圖標,選「關於」,在彈出的窗口中,對照上面的信息即可獲取。java

10.2. InnoDB 題

一張自增表裏面總共有 7 條數據,刪除了最後 2 條數據,重啓 MySQL 數據庫,又插入了一條數據,此時 id 是幾?
答:表類型若是是 MyISAM ,那 id 就是 8。
表類型若是是 InnoDB,那 id 就是 6。mysql

10.3. 序列的做用

Oracle 使用序列來生成惟一編號,用來處理一個表中自增字段。 Oracle 序列是原子對象,而且是一致的。也就是說,一旦您訪問一個序列號,Oracle 將在處理下一個請求以前自動遞增下一個編號,從而確保不會出現重複值。算法

10.4. 觸發器的做用:

觸發器是一中特殊的存儲過程,主要是經過事件來觸發而被執行的。它能夠強化約束,來維護數據的完整性和一致性,能夠跟蹤數據庫內的操做從而不容許未經許可的更新和變化。能夠聯級運算。如,某表上的觸發器上包含對另外一個表的數據操做,而該操做又會致使該表觸發器被觸發。sql

10.5. 什麼是存儲過程?用什麼來調用?

存儲過程是一個預編譯的 SQL 語句,優勢是容許模塊化的設計,就是說只需建立一次,之後在該程序中就能夠調用屢次。若是某次操做須要執行屢次 SQL,使用存儲過程比單純SQL 語句執行要快。
調用:
1)能夠用一個命令對象來調用存儲過程。
2)能夠供外部程序調用,好比:java 程序。數據庫

10.6. 存儲過程的優缺點?

優勢:
存儲過程是預編譯過的,執行效率高。
存儲過程的代碼直接存放於數據庫中,經過存儲過程名直接調用,減小網絡通信。
安全性高,執行存儲過程須要有必定權限的用戶。
存儲過程能夠重複使用,可減小數據庫開發人員的工做量。
缺點:
移植性差編程

10.7. 存儲過程與函數的區別

存儲過程 函數用於在數據庫中完成特定的操做或者任務(如插入、刪除等)用於特定的數據(如選擇)程序頭部聲明用 procedure 程序頭部聲明用 function程序頭部聲明時不需描述返回類型 程序頭部聲明時要描述返回類型,並且PL/SQL 塊中至少要包括一個有效的return 語句可使用 in/out/in out 三種模式的參數可使用 in/out/in out 三種模式的參數可做爲一個獨立的 PL/SQL 語句來執行 不能獨立執行,必須做爲表達式的一部分調用能夠經過 out/in out 返回零個或多個值經過 return 語句返回一個值,且改值要與聲明部分一致,也能夠是經過 out類型的參數帶出的變量SQL 語句(DML或 SELECT)中不可調用存儲過程SQL 語句(DML 或 SELECT)中能夠調用函數數組

10.8. 索引的做用?和它的優勢缺點是什麼?

索引:索引就一種特殊的查詢表,數據庫的搜索能夠利用它加速對數據的檢索。
優勢:它很相似與現實生活中書的目錄,不須要查詢整本書內容就能夠找到想要的數據。索引能夠是惟一的,建立索引容許指定單個列或者是多個列。
缺點:是它減慢了數據錄入的速度,同時也增長了數據庫的尺寸大小。安全

10.9. 什麼樣的字段適合建索引

惟1、不爲空、常常被查詢的字段服務器

10.10. 索引類型有哪些?

邏輯上:
1.Single column 單行索引
2.Concatenated 多行索
3.Unique 惟一索引
4.NonUnique 非惟一索引
5.Function-based 函數索引
6.Domain 域索引 物理上:
7.Partitioned 分區索引
8.NonPartitioned 非分區索引
9.tree :
Normal 正常型 B 樹
Rever Key 反轉型 B 樹 Bitmap 位圖索引網絡

10.11. 什麼是數據庫事務?

答案:
單個邏輯單元執行的一系列操做,這些操做要麼全作要麼全不作,是不可分割的.事務的開始和結束用戶是能夠控制的,若是沒控制則由數據庫默認的劃分事務.事務具備如下性質:
(1) 原子性:
指一個事務要麼全執行,要麼全不執行.也就是說一個事務不可能執行到一半就中止了.
(2) 一致性:
指事務的運行並不改變數據庫中的一致性.好比 a+b=10;a 改變了,b 也應該隨之改變.
(3) 獨立性:- 63 -
兩個以上的事務不會出現交替運行的狀態,由於這樣可能致使數據的不一致
(4) 持久性:
事務運行成功以後數據庫的更新是永久的

10.12. SQL 中分別有幾種事務?各有什麼特色?:

答:4 種事務:
自動提交事務
隱式事務特色
顯示事務
分佈式事務
自動提交事務特色:每條單獨語句都是一個事務。
隱式事務特色:前一個事務完成時新事務隱式啓動,每一個事務仍以 COMMIT 或ROLLBACK 語句、顯示結束。
顯示事務特色:每一個事務均已 BEGIN TRANSACTION 語句顯示開始,以 COMMIT 或ROLLBACK 語句顯示結束。
分佈式事務特色:跨越多個服務器的事務

10.13. 什麼是回滾?

爲了保證在應用程序、數據庫或系統出現錯誤後,數據庫可以被還原,以保證數據庫的完整性 ,因此須要進行回滾。回滾(rollback)就是在事務提交以前將數據庫數據恢復到事務修改以前數據庫數據狀態。

10.14. 什麼是事務?什麼是鎖?

事務:
事務就是被綁定在一塊兒做爲一個邏輯工做單元的 SQL 語句分組,若是任何一個語句操做失敗那麼整個操做就被失敗,之後操做就會回滾到操做前狀態,或者是上有個節點。爲了確保要麼執行,要麼不執行,就可使用事務。要將有組語句做爲事務考慮,就須要經過ACID 測試,即原子性,一致性,隔離性和持久性。
鎖:
在全部的 DBMS 中,鎖是實現事務的關鍵,鎖能夠保證事務的完整性和併發性。與現
實生活中鎖同樣,它可使某些數據的擁有者,在某段時間內不能使用某些數據或數據結構。
固然鎖還分級別的。- 64 -

10.15. 什麼是封鎖?封鎖的基本類型有哪幾種?含義是什麼?

封鎖:
所謂封鎖就是當一個事務在對某個數據對象(能夠是數據項、記錄、數據集、以致整個數據庫)進行操做以前,必須得到相應的鎖,以保證數據操做的正確性和一致性。
基本的封鎖類型有兩種:排它鎖和共享鎖
(1)排它鎖:排它鎖又稱寫鎖,簡稱爲 X 鎖,其採用的原理是禁止併發操做。
(2)共享鎖:共享鎖又稱讀鎖,,簡稱爲 S 鎖,其採用的原理是容許其餘用戶對同一數
據對象進行查詢,但不能對該數據對象進行修改。

10.16. sql 數據庫裏鎖是什麼以及分類介紹

目前的 C/S,B/S 結構都是多用戶訪問數據庫,每一個時間點會有成千上萬個 user 來訪問DB,其中也會同時存取同一份數據,會形成數據的不一致性或者讀髒數據,數據庫必須有鎖的機制來確保數據的完整和一致性
6 種鎖的類型:
(1) 共享鎖:
共享鎖用於全部的只讀數據操做.
(2) 修改鎖:
修改鎖在修改操做的初始化階段用來鎖定可能要被修改的資源,這樣能夠避免使用共享
鎖形成的死鎖現象
(3) 獨佔鎖:
獨佔鎖是爲修改數據而保留的。它所鎖定的資源,其餘事務不能讀取也不能修改。獨佔
鎖不能和其餘鎖兼容。
(4) 架構鎖
結構鎖分爲結構修改鎖(Sch-M)和結構穩定鎖(Sch-S)。執行表定義語言操做時,
SQLServer 採用 Sch-M 鎖,編譯查詢時,SQLServer 採用 Sch-S 鎖。
(5) 意向鎖
意向鎖說明 SQL Server 有在資源的低層得到共享鎖或獨佔鎖的意向。
(6) 批量修改鎖
批量複製數據時使用批量修改鎖

10.17. 什麼是死鎖?產生死鎖的必要條件。

1)在同時處於等待狀態的兩個或多個事務中,每一個事務都在等待其中另外一個事務解除封鎖,它才能繼續執行下去,結果形成任何一個事務都沒法繼續執行,這種狀態稱爲死鎖.
2)發生死鎖的必要條件有如下四條:
(1)互斥條件:一個數據對象一次只能被一個事務所使用,即對數據的封鎖採用排它式;
(2)不可搶佔條件:一個數據對象只能被佔有它的事務所釋放,而不能被別的事務強行搶佔
(3)互斥條件:一個數據對象一次只能被一個事務所使用,即對數據的封鎖用排它式;
(4)不可搶佔條件:一個數據對象只能被佔有它的事務所釋放,而不能被別的事務強行搶佔

10.18. 什麼叫視圖?遊標是什麼?

視圖:
是一種虛擬的表,具備和物理表相同的功能。能夠對視圖進行增,改,查,操做,試圖一般是有一個表或者多個表的行或列的子集。對視圖的修改會影響基本表。它使得咱們獲取數據更容易,相比多表查詢。
遊標:
是對查詢出來的結果集做爲一個單元來有效的處理。遊標能夠定在該單元中的特定行,從結果集的當前行檢索一行或多行。能夠對結果集當前行作修改。通常不使用遊標,可是須要逐條處理數據的時候,遊標顯得十分重要。

10.19. 使用遊標的基本步驟有哪些?

  1. 聲明遊標
  2. 打開遊標
  3. 讀取遊標中的數據
  4. 關閉遊標
  5. 釋放遊標

10.20. 視圖的優缺點

優勢:
對數據庫的訪問,由於視圖能夠有選擇性的選取數據庫裏的一部分。用戶經過簡單的查詢能夠從複雜查詢中獲得結果。維護數據的獨立性,試圖可從多個表檢索數據。對於相同的數據可產生不一樣的視圖。
缺點:
性能:查詢視圖時,必須把視圖的查詢轉化成對基本表的查詢,若是這個視圖是由一個複雜的多表查詢所定義,那麼,那麼就沒法更改數據。

10.21. 列舉幾種錶鏈接方式,有什麼區別?

內鏈接、自鏈接、外鏈接(左、右、全)、交叉鏈接
內鏈接:只有兩個元素表相匹配的才能在結果集中顯示。
外鏈接:左外鏈接:左邊爲驅動表,驅動表的數據所有顯示,匹配表的不匹配的不會顯示。
右外鏈接: 右邊爲驅動表,驅動表的數據所有顯示,匹配表的不匹配的不會顯示。
全外鏈接:鏈接的表中不匹配的數據所有會顯示出來。
交叉鏈接: 笛卡爾效應,顯示的結果是連接表數的乘積。

10.22. 主鍵和外鍵的區別?

1.主鍵在本表中是惟一的、不可惟空的。
2.外鍵能夠重複能夠惟空。
3.外鍵和另外一張表的主鍵關聯,不能建立對應表中不存在的外鍵。

10.23. 在數據庫中查詢語句速度很慢,如何優化?

  1. 建索引
  2. 減小表之間的關聯
  3. 優化 sql,儘可能讓 sql 很快定位數據,不要讓 sql 作全表查詢,應該走索引,把數據 量大的表排在前面
  4. 簡化查詢字段,沒用的字段不要,已經對返回結果的控制,儘可能返回少許數據
  5. 儘可能用 PreparedStatement 來查詢,不要用 Statement

10.24. 數據庫三範式是什麼?

(1)第一範式(1NF):
所謂第一範式(1NF)是指在關係模型中,對於添加的一個規範要求,全部的域都應該是原子性的,即數據庫表的每一列都是不可分割的原子數據項,而不能是集合,數組,記錄等非原子數據項。
(2)第二範式(2NF):
在 1NF 的基礎上,非碼屬性必須徹底依賴於候選碼(在 1NF 基礎上消除非主屬性對主碼的部分函數依賴)。
第二範式(2NF)是在第一範式(1NF)的基礎上創建起來的,即知足第二範式(2NF)必須先知足第一範式(1NF)。第二範式(2NF)要求數據庫表中的每一個實例或記錄必須能夠被惟一地區分。選取一個能區分每一個實體的屬性或屬性組,做爲實體的惟一標識。
(3)第三範式(3NF):
第三範式(3NF)是第二範式(2NF)的一個子集,即知足第三範式(3NF)必須知足第二範式(2NF)。簡而言之,第三範式(3NF)要求一個關係中不包含已在其它關係已包含的非主關鍵字信息。

10.25. union 和 union all 有什麼不一樣?

Union:
UNION 在進行表連接後會篩選掉重複的記錄,因此在表連接後會對所產生的結果集進行排序運算,刪除重複的記錄再返回結果。實際大部分應用中是不會產生重複的記錄,最多見的是過程表與歷史表 UNION。
union all:
UNION ALL 只是簡單的將兩個結果合併後就返回。這樣,若是返回的兩個結果集中有重複的數據,那麼返回的結果集就會包含重複的數據了。 從效率上說,UNION ALL 要比UNION 快不少,因此,若是能夠確認合併的兩個結果集中不包含重複的數據的話,那麼就使用 UNION ALL。

10.26. CHAR 和 VARCHAR 的區別是什麼?

答:
(1)CHAR 的長度是固定的,而 VARCHAR 的長度是能夠變化的。
(2)CHAR 的效率比 VARCHAR 的效率稍高。
(3)目前 VARCHAR 是 VARCHAR 的同義詞。

10.27. Varchar2 和 varchar 有什麼區別?

Char 的長度是固定的,而 varchar2 的長度是能夠變化的,好比,存儲字符串「abc」對於 char(20),表示你存儲的字符將佔 20 個字節,包含 17 個空,而一樣的 varchar2(20)只佔了 3 個字節,20 只是最大值,當你存儲的字符小於 20 時,按實際長度存儲。 char 的效率要被 varchar2 的效率高。 目前 varchar 是 varchar2 的同義詞,工業標準的 varchar類型能夠存儲空字符串,可是 oracle 不能這樣作,儘管它保留之後這樣作的權利。Oracle本身開發了一個數據類型 varchar2,這個類型不是一個標準的 varchar,他將在數據庫中varchar 列能夠存儲空字符串的特性改成存儲 null 值,若是你想有向後兼容的能力,oracle建議使用 varchar2 而不是 varchar

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

(1)範圍
float 和 double 的範圍是由指數的位數來決定的。
(2)精度
float 和 double 的精度是由尾數的位數來決定的。浮點數在內存中是按科學計數法來存儲的,其整數部分始終是一個隱含着的「1」,因爲它是不變的,故不能對精度形成影響。

10.29. Oracle 和 Mysql 的區別?

1)庫函數不一樣。
2)Oracle 是用表空間來管理的,Mysql 不是。
3)顯示當前全部的表、用戶、改變鏈接用戶、顯示當前鏈接用戶、執行外部腳本的語句的不一樣。
4)分頁查詢時候時候,mysql 用 limit oracle 用 rownum

10.30. sql 語句應該考慮哪些安全性?

(1)防止 sql 注入,對特殊字符進行轉義,過濾或者使用預編譯的 sql 語句綁定變量。
(2)最小權限原則,特別是不要用 root 帳戶,爲不一樣的類型的動做或者組建使用不一樣的帳戶。
(3)當 sql 運行出錯時,不要把數據庫返回的錯誤信息所有顯示給用戶,以防止泄漏服務器和數據庫相關信息。

10.31. 什麼是內存泄漏?

答:通常咱們所說的內存泄漏指的是堆內存的泄漏。堆內存是程序從堆中爲其分配的,大小任意的,使用完後要顯示釋放內存。當應用程序用關鍵字 new 等建立對象時,就從堆中爲它分配一塊內存,使用完後程序調用 free 或者 delete 釋放該內存,不然就說該內存就不能被使用,咱們就說該內存被泄漏了。

10.32. Delete、truncate、drop 都是刪除語句,它們有什麼分別?

  1. delete 屬於 DML 語句,刪除數據,保留表結構,須要 commit,能夠回滾,若是數據量大,很慢。
  2. truncate 屬於 DDL 語句,刪除全部數據,保留表結構,自動 commit,不能夠回滾,一次所有刪除全部數據,速度相對較快。
  3. Drop 屬於 DDL 語句,刪除數據和表結構,不須要 commit,刪除速度最快。

10.33. order by 和 groupby 的區別

order by: 排序查詢、asc 升序、desc 降序
group by:分組查詢、having 只能用於 groupby 子句、做用於組內,having 條件子句能夠直接跟函數表達式。使用 group by 子句的查詢語句須要使用聚合函數。

10.34. 何謂悲觀鎖與樂觀鎖

樂觀鎖對應於生活中樂觀的人老是想着事情往好的方向發展,悲觀鎖對應於生活中悲觀的人老是想着事情往壞的方向發展。這兩種人各有優缺點,不能不以場景而定說一種人好於另一種人。
悲觀鎖
老是假設最壞的狀況,每次去拿數據的時候都認爲別人會修改,因此每次在拿數據的時候都會上鎖,這樣別人想拿這個數據就會阻塞直到它拿到鎖(共享資 源每次只給一個線程使用,其它線程阻塞,用完後再把資源轉讓給其它線程)。傳統的關係型數據庫裏邊就用到了不少這種鎖機制,好比行鎖,表鎖 等,讀鎖,寫鎖等,都是在作操做以前先上鎖。Java中 synchronized 和 ReentrantLock 等獨佔鎖就是悲觀鎖思想的實現。
樂觀鎖
老是假設最好的狀況,每次去拿數據的時候都認爲別人不會修改,因此不會上鎖,可是在更新的時候會判斷一下在此期間別人有沒有去更新這個數據,能夠 使用版本號機制和CAS 算法實現。樂觀鎖適用於多讀的應用類型,這樣能夠提 高吞吐量,像數據庫提供的相似於 write_condition 機制,其實都是提供的樂 觀鎖。在 Java 中java.util.concurrent.atomic 包下面的原子變量類就是使用了 樂觀鎖的一種實現方式 CAS實現的。
兩種鎖的使用場景
從上面對兩種鎖的介紹,咱們知道兩種鎖各有優缺點,不可認爲一種好於另外一 種,像樂觀鎖適用於寫比較少的狀況下(多讀場景),即衝突真的不多發生的 時候,這樣能夠省去了鎖的開銷,加大了系統的整個吞吐量。但若是是多寫的 狀況,通常會常常產生衝突,這就會致使上層應用會不斷的進行 retry,這樣反 卻是下降了性能,因此通常多寫的場景下用悲觀鎖就比較合適。
樂觀鎖常見的兩種實現方式
樂觀鎖通常會使用版本號機制或 CAS 算法實現。
版本號機制
通常是在數據表中加上一個數據版本號 version 字段,表示數據被修改的次 數,當數據被修改時,version 值會加一。當線程 A 要更新數據值時,在讀取數 據的同時也會讀取version 值,在提交更新時,若剛纔讀取到的 version 值爲當 前數據庫中的 version 值相等時才更新,不然重試更新操做,直到更新成功。
舉一個簡單的例子:假設數據庫中賬戶信息表中有一個 version 字段,當前值 爲 1 ;
而當前賬戶餘額字段( balance )爲 $100 。

  1. 操做員 A 此時將其讀出( version=1 ),並從其賬戶餘額中扣除 $50

( $100-$50 )。

  1. 在操做員 A 操做的過程當中,操做員 B 也讀入此用戶信息( version=1 ),並從

其賬戶餘額中扣除 $20 ( $100-$20 )。

  1. 操做員 A 完成了修改工做,將數據版本號加一( version=2 ),連同賬戶扣除後餘額( balance=$50 ),提交至數據庫更新,此時因爲提 交數據版本大於數據庫記錄當前版本,數據被更新,數據庫記錄 version 更新爲 2 。
  2. 操做員 B 完成了操做,也將版本號加一( version=2 )試圖向數據庫 提交數據( balance=$80 ),但此時比對數據庫記錄版本時發現,操 做員 B 提交的數據版本號爲 2 ,數據庫記錄當前版本也爲 2 ,不滿 足 「 提交版本必須大於記錄當前版本才能執行更新 「 的樂觀鎖策略, 所以,操做員 B 的提交被駁回。這樣,就避免了操做員 B 用基於 version=1 的舊數據修改的結果覆蓋操做員 A 的操做結果的可能。
  3. CAS 算法

即 compare and swap(比較與交換),是一種有名的無鎖算法。無鎖編程, 即不使用鎖的狀況下實現多線程之間的變量同步,也就是在沒有線程被阻塞的 狀況下實現變量的同步,因此也叫非阻塞同步(Non-blocking Synchronization)。CAS 算法涉及到三個操做數須要讀寫的內存值 V進行比較的值 A擬寫入的新值 B當且僅當 V 的值等於 A 時,CAS 經過原子方式用新值 B 來更新 V 的值,不然不會執行任何操做(比較和替換是一個原子操做)。通常狀況下是一個自旋操做,即不斷的重試。
樂觀鎖的缺點
ABA 問題是樂觀鎖一個常見的問題
1 ABA 問題
若是一個變量 V 初次讀取的時候是 A 值,而且在準備賦值的時候檢查到它仍然 是 A 值,那咱們就能說明它的值沒有被其餘線程修改過了嗎?很明顯是不能的,由於在這段時間它的值可能被改成其餘值,而後又改回 A,那 CAS 操做就 會誤認爲它歷來沒有被修改過。這個問題被稱爲 CAS 操做的 "ABA"問題。
JDK 1.5 之後的 AtomicStampedReference 類就提供了此種能力,其中的compareAndSet 方法就是首先檢查當前引用是否等於預期引用,而且當前標誌是 否等於預期標誌,若是所有相等,則以原子方式將該引用和該標誌的值設置爲 給定的更新值。
2 循環時間長開銷大
自旋 CAS(也就是不成功就一直循環執行直到成功)若是長時間不成功,會給 CPU 帶來很是大的執行開銷。 若是 JVM 能支持處理器提供的 pause 指令那麼 效率會有必定的提高,pause 指令有兩個做用,第一它能夠延遲流水線執行指 令(de-pipeline),使 CPU 不
會消耗過多的執行資源,延遲的時間取決於具體 實現的版本,在一些處理器上延遲時間是零。第二它能夠避免在退出循環的時 候因內存順序衝突(memory order violation)而引發 CPU 流水線被清空 (CPU pipeline flush),從而提升 CPU 的執行效率。
3 只能保證一個共享變量的原子操做
CAS 只對單個共享變量有效,當操做涉及跨多個共享變量時 CAS 無效。可是 從 JDK1.5 開始,提供了 AtomicReference 類來保證引用對象之間的原子性,你 能夠把多個變量放在一個對象裏來進行 CAS 操做.因此咱們可使用鎖或者利 用 AtomicReference類把多個共享變量合併成一個共享變量來操做。CAS 與 synchronized 的使用情景
簡單的來講 CAS 適用於寫比較少的狀況下(多讀場景,衝突通常較少),synchronized適用於寫比較多的狀況下(多寫場景,衝突通常較多)
1.對於資源競爭較少(線程衝突較輕)的狀況,使用 synchronized 同步鎖 進行線程阻塞和喚醒切換以及用戶態內核態間的切換操做額外浪費消耗 cpu 資源;而 CAS 基於硬件實現,不須要進入內核,不須要切換線程, 操做自旋概率較少,所以能夠得到更高的性能。

  1. 對於資源競爭嚴重(線程衝突嚴重)的狀況,CAS 自旋的機率會比較 大,從而浪費更多的 CPU 資源,效率低於 synchronized。

補充: Java 併發編程這個領域中 synchronized 關鍵字一直都是元老級的角 色,好久以前不少人都會稱它爲 「重量級鎖」 。可是,在 JavaSE 1.6 以後進行了 主要包括爲了減小得到鎖和釋放鎖帶來的性能消耗而引入的 偏向鎖 和 輕量級 鎖 以及其它各類優化以後變得在某些狀況下並非那

相關文章
相關標籤/搜索