資料庫筆試題【20181025】
一 . 資料庫索引
1.什麼是索引
在資料庫中,索引的含義與日常意義上的“索引”一詞並無多大區別(想想小時候查字典),它是用於提高資料庫表資料訪問速度的資料庫物件。
A)索引可以避免全表掃描。多數查詢可以僅掃描少量索引頁及資料頁,而不是遍歷所有資料頁。
B)對於非聚集索引,有些查詢甚至可以不訪問資料頁。
C)聚集索引可以避免資料插入操作集中於表的最後一個數據頁。
D)一些情況下,索引還可用於避免排序操作。
當然,眾所周知,雖然索引可以提高查詢速度,但是它們也會導致資料庫系統更新資料的效能下降,因為大部分資料更新需要同時更新索引。
2 . 索引的儲存
一條索引記錄中包含的基本資訊包括:鍵值(即你定義索引時指定的所有欄位的值)+邏輯指標(指向資料頁或者另一索引頁)。
當你為一張空表建立索引時,資料庫系統將為你分配一個索引頁,該索引頁在你插入資料前一直是空的。此頁此時既是根結點,也是葉結點。每當你往表中插入一行資料,資料庫系統即向此根結點中插入一行索引記錄。當根結點滿時,資料庫系統大抵按以下步驟進行分裂:
A)建立兩個兒子結點
B)將原根結點中的資料近似地拆成兩半,分別寫入新的兩個兒子結點
C)根結點中加上指向兩個兒子結點的指標
通常狀況下,由於索引記錄僅包含索引欄位值(以及4-9位元組的指標),索引實體比真實的資料行要小許多,索引頁相較資料頁來說要密集許多。一個索引頁可以儲存數量更多的索引記錄,這意味著在索引中查詢時在I/O上佔很大的優勢,理解這一點有助於從本質上了解使用索引的優勢。
3.索引的型別
A)聚集索引,表資料按照索引的順序來儲存的。對於聚集索引,葉子結點即儲存了真實的資料行,不再有另外單獨的資料頁。
B)非聚集索引,表資料儲存順序與索引順序無關。對於非聚集索引,葉結點包含索引欄位值及指向資料頁資料行的邏輯指標,該層緊鄰資料頁,其行數量與資料錶行資料量一致。
在一張表上只能建立一個聚集索引,因為真實資料的物理順序只可能是一種。如果一張表沒有聚集索引,那麼它被稱為“堆集”(Heap)。這樣的表中的資料行沒有特定的順序,所有的新行將被新增的表的末尾位置。
4.聚集索引
在聚集索引中,葉結點也即資料結點,所有資料行的儲存順序與索引的儲存順序一致。
1)聚集索引與查詢操作
如上圖,我們在名字欄位上建立聚集索引,當需要在根據此欄位查詢特定的記錄時,資料庫系統會根據特定的系統表查詢的此索引的根,然後根據指標查詢下一個,直到找到。例如我們要查詢“Green”,由於它介於[Bennet,Karsen],據此我們找到了索引頁1007,在該頁中“Green”介於[Greane, Hunter]間,據此我們找到葉結點1133(也即資料結點),並最終在此頁中找以了目標資料行。
此次查詢的IO包括3個索引頁的查詢(其中最後一次實際上是在資料頁中查詢)。這裡的查詢可能是從磁碟讀取(Physical Read)或是從快取中讀取(Logical Read),如果此表訪問頻率較高,那麼索引樹中較高層的索引很可能在快取中被找到。所以真正的IO可能小於上面的情況。
2)聚集索引與插入操作
最簡單的情況下,插入操作根據索引找到對應的資料頁,然後通過挪動已有的記錄為新資料騰出空間,最後插入資料。
如果資料頁已滿,則需要拆分資料頁(頁拆分是一種耗費資源的操作,一般資料庫系統中會有相應的機制要儘量減少頁拆分的次數,通常是通過為每頁預留空間來實現):
A)在該使用的資料段(extent)上分配新的資料頁,如果資料段已滿,則需要分配新段。
B)調整索引指標,這需要將相應的索引頁讀入記憶體並加鎖。
C)大約有一半的資料行被歸入新的資料頁中。
D)如果表還有非聚集索引,則需要更新這些索引指向新的資料頁。
特殊情況:
A)如果新插入的一條記錄包含很大的資料,可能會分配兩個新資料頁,其中之一用來儲存新記錄,另一儲存從原頁中拆分出來的資料。
B)通常資料庫系統中會將重複的資料記錄儲存於相同的頁中。
C)類似於自增列為聚集索引的,資料庫系統可能並不拆分資料頁,頁只是簡單的新添資料頁。
3)聚集索引與刪除操作
刪除行將導致其下方的資料行向上移動以填充刪除記錄造成的空白。
如果刪除的行是該資料頁中的最後一行,那麼該資料頁將被回收,相應的索引頁中的記錄將被刪除。如果回收的資料頁位於跟該表的其它資料頁相同的段上,那麼它可能在隨後的時間內被利用。如果該資料頁是該段的唯一一個數據頁,則該段也被回收。
對於資料的刪除操作,可能導致索引頁中僅有一條記錄,這時,該記錄可能會被移至鄰近的索引頁中,原索引頁將被回收,即所謂的“索引合併”。
5.非聚集索引
非聚集索引與聚集索引相比:
A)葉子結點並非資料結點
B)葉子結點為每一真正的資料行儲存一個“鍵-指標”對
C)葉子結點中還儲存了一個指標偏移量,根據頁指標及指標偏移量可以定位到具體的資料行。
D)類似的,在除葉結點外的其它索引結點,儲存的也是類似的內容,只不過它是指向下一級的索引頁的。
聚集索引是一種稀疏索引,資料頁上一級的索引頁儲存的是頁指標,而不是行指標。而對於非聚集索引,則是密集索引,在資料頁的上一級索引頁它為每一個數據行儲存一條索引記錄。
對於根與中間級的索引記錄,它的結構包括:
A)索引欄位值
B)RowId(即對應資料頁的頁指標+指標偏移量)。在高層的索引頁中包含RowId是為了當索引允許重複值時,當更改資料時精確定位資料行。
C)下一級索引頁的指標
對於葉子層的索引物件,它的結構包括:
A)索引欄位值
B)RowId
1)非聚集索引與查詢操作
針對上圖,如果我們同樣查詢“Green”,那麼一次查詢操作將包含以下IO:3個索引頁的讀取+1個數據頁的讀取。同樣,由於快取的關係,真實的IO實際可能要小於上面列出的。
2)非聚集索引與插入操作
如果一張表包含一個非聚集索引但沒有聚集索引,則新的資料將被插入到最末一個數據頁中,然後非聚集索引將被更新。如果也包含聚集索引,該聚集索引將被用於查詢新行將要處於什麼位置,隨後,聚集索引、以及非聚集索引將被更新。
3)非聚集索引與刪除操作
如果在刪除命令的Where子句中包含的列上,建有非聚集索引,那麼該非聚集索引將被用於查詢資料行的位置,資料刪除之後,位於索引葉子上的對應記錄也將被刪除。如果該表上有其它非聚集索引,則它們葉子結點上的相應資料也要刪除。
如果刪除的資料是該數所頁中的唯一一條,則該頁也被回收,同時需要更新各個索引樹上的指標。
由於沒有自動的合併功能,如果應用程式中有頻繁的隨機刪除操作,最後可能導致表包含多個數據頁,但每個頁中只有少量資料。
6.索引覆蓋
索引覆蓋是這樣一種索引策略:當某一查詢中包含的所需欄位皆包含於一個索引中,此時索引將大大提高查詢效能。
包含多個欄位的索引,稱為複合索引。索引最多可以包含31個欄位,索引記錄最大長度為600B。如果你在若干個欄位上建立了一個複合的非聚集索引,且你的查詢中所需Select欄位及Where,Order By,Group By,Having子句中所涉及的欄位都包含在索引中,則只搜尋索引頁即可滿足查詢,而不需要訪問資料頁。由於非聚集索引的葉結點包含所有資料行中的索引列值,使用這些結點即可返回真正的資料,這種情況稱之為“索引覆蓋”。
在索引覆蓋的情況下,包含兩種索引掃描:
A)匹配索引掃描
B)非匹配索引掃描
1)匹配索引掃描
此類索引掃描可以讓我們省去訪問資料頁的步驟,當查詢僅返回一行資料時,效能提高是有限的,但在範圍查詢的情況下,效能提高將隨結果集數量的增長而增長。
針對此類掃描,索引必須包含查詢中涉及的的所有欄位,另外,還需要滿足:Where子句中包含索引中的“引導列”(Leading Column),例如一個複合索引包含A,B,C,D四列,則A為“引導列”。如果Where子句中所包含列是BCD或者BD等情況,則只能使用非匹配索引掃描。
2)非配置索引掃描
正如上述,如果Where子句中不包含索引的導引列,那麼將使用非配置索引掃描。這最終導致掃描索引樹上的所有葉子結點,當然,它的效能通常仍強於掃描所有的資料頁。
二.事務
事務(Transaction)是併發控制的基本單位。所謂的事務,它是一個操作序列,這些操作要麼都執行,要麼都不執行,它是一個不可分割的工作單位。例如,銀行轉賬工作:從一個賬號扣款並使另一個賬號增款,這兩個操作要麼都執行,要麼都不執行。所以,應該把它們看成一個事務。事務是資料庫維護資料一致性的單位,在每個事務結束時,都能保持資料一致性。
針對上面的描述可以看出,事務的提出主要是為了解決併發情況下保持資料一致性的問題。
事務具有以下4個基本特徵。
● Atomic(原子性):事務中包含的操作被看做一個邏輯單元,這個邏輯單元中的操作要麼全部成功,要麼全部失敗。
● Consistency(一致性):只有合法的資料可以被寫入資料庫,否則事務應該將其回滾到最初狀態。
● Isolation(隔離性):事務允許多個使用者對同一個資料進行併發訪問,而不破壞資料的正確性和完整性。同時,並行事務的修改必須與其他並行事務的修改相互獨立。
● Durability(永續性):事務結束後,事務處理的結果必須能夠得到固化。
1 . 事務的語句
開始事物:BEGIN TRANSACTION
提交事物:COMMIT TRANSACTION
回滾事務:ROLLBACK TRANSACTION
2 . 事務的4個屬性
①原子性(Atomicity):事務中的所有元素作為一個整體提交或回滾,事務的個元素是不可分的,事務是一個完整操作。
②一致性(Consistemcy):事物完成時,資料必須是一致的,也就是說,和事物開始之前,資料儲存中的資料處於一致狀態。保證資料的無損。
③隔離性(Isolation):對資料進行修改的多個事務是彼此隔離的。這表明事務必須是獨立的,不應該以任何方式以來於或影響其他事務。
④永續性(Durability):事務完成之後,它對於系統的影響是永久的,該修改即使出現系統故障也將一直保留,真實的修改了資料庫
3 . 事務的儲存點
SAVE TRANSACTION 儲存點名稱 --自定義儲存點的名稱和位置
ROLLBACK TRANSACTION 儲存點名稱 --回滾到自定義的儲存點
其他高手的一些補充:
事務的標準定義: 指作為單個邏輯工作單元執行的一系列操作,而這些邏輯工作單元需要具有原子性, 一致性,隔離性和永續性四個屬性,統稱為ACID特性。
所謂事務是使用者定義的一個數據庫操作序列,這些操作要麼全做要麼全不做,是一個不可分割的工作單位。例如,在關係資料庫中,一個事務可以是一條SQL語句、一組SQL語句或整個程式。
事務和程式是兩個概念。一般地講,一個程式中包含多個事務。
事務的開始與結束可以由使用者顯式控制。如果使用者沒有顯式地定義事務,則由DBMS按預設規定自動劃分事務。
在SQL語言中,定義事務的語句有三條:
BEGIN TRANSACTION
COMMIT
ROLLBACK
顯示事務被用begin transaction 與 end transaction 標識起來,其中的 update 與 delete 語句或者全部執行或者全部不執行。。 如:
begin transaction T1
update student
set name=‘Tank’
where id=2006010
delete from student
where id=2006011
commit
簡單地說,事務是一種機制,用以維護資料庫的完整性。
其實現形式就是將普通的SQL語句嵌入到Begin Tran…Commit Tran 中(或完整形式 Begin Transaction…Commit Transaction),當然,必要時還可以使用RollBack Tran 回滾事務,即撤銷操作。
利用事務機制,對資料庫的操作要麼全部執行,要麼全部不執行,保證資料庫的一致性。需要使用事務的SQL語句通常是更新和刪除操作等。
end transaction T1
關於savepoint
使用者在事務(transaction)內可以宣告(declare)被稱為儲存點(savepoint)的標記。儲存點將一個大事務劃分為較小的片斷。
使用者可以使用儲存點(savepoint)在事務(transaction)內的任意位置作標記。之後使用者在對事務進行回滾操作(rolling back)時,就可以選擇從當前執行位置回滾到事務內的任意一個儲存點。例如使用者可以在一系列複雜的更新(update)操作之間插入儲存點,如果執行過程中一個語句出現錯誤,使用者 可以回滾到錯誤之前的某個儲存點,而不必重新提交所有的語句。
在開發應用程式時也同樣可以使用儲存點(savepoint)。如果一個過程
(procedure)內包含多個函式(function),使用者可以在每個函式的開始位置建立一個儲存點。當一個函式失敗時, 就很容易將資料恢復到函式執行之前的狀態,回滾(roll back)後可以修改引數重新呼叫函式,或執行相關的誤處理。
當事務(transaction)被回滾(rollback)到某個儲存點(savepoint)後,
Oracle將釋放由被回滾語句使用的鎖。其他等待被鎖資源的事務就可以繼續執行。需要更新(update)被鎖資料行的事務也可以繼續執行。
將事務(transaction)回滾(roll back)到某個儲存點(savepoint)的過程如下:
- Oracle 回滾指定儲存點之後的語句
- Oracle 保留指定的儲存點,但其後建立的儲存點都將被清除
- Oracle 釋放此儲存點後獲得的表級鎖(table lock)與行級鎖(row
lock),但之前的資料鎖依然保留。被部分回滾的事務(transaction)依然處於活動狀態,可以繼續執行。一個事務(transaction)在等待其他事務的過程中,進行回滾(roll back)到某個儲存點(savepoint)的操作不會釋放行級鎖(row lock)。為了避免事務因為不能獲得鎖而被掛起,應在執行 UPDATE 或 DELETE 操作前使用 FORUPDATE … NOWAIT 語句。(以上內容講述的是回滾儲存點之前所獲得的鎖。而在儲存點之後獲得的行級鎖是會被釋放的,同時儲存點之後執行的SQL 語句也會被完全回滾)。
三.樂觀鎖和悲觀鎖
在資料庫的鎖機制中介紹過,資料庫管理系統(DBMS)中的併發控制的任務是確保在多個事務同時存取資料庫中同一資料時不破壞事務的隔離性和統一性以及資料庫的統一性。
樂觀併發控制(樂觀鎖)和悲觀併發控制(悲觀鎖)是併發控制主要採用的技術手段。
無論是悲觀鎖還是樂觀鎖,都是人們定義出來的概念,可以認為是一種思想。其實不僅僅是資料庫系統中有樂觀鎖和悲觀鎖的概念,像memcache、hibernate、tair等都有類似的概念。
針對於不同的業務場景,應該選用不同的併發控制方式。所以,不要把樂觀併發控制和悲觀併發控制狹義的理解為DBMS中的概念,更不要把他們和資料中提供的鎖機制(行鎖、表鎖、排他鎖、共享鎖)混為一談。其實,在DBMS中,悲觀鎖正是利用資料庫本身提供的鎖機制來實現的。
悲觀鎖
在關係資料庫管理系統裡,悲觀併發控制(又名“悲觀鎖”,Pessimistic Concurrency Control,縮寫“PCC”)是一種併發控制的方法。它可以阻止一個事務以影響其他使用者的方式來修改資料。如果一個事務執行的操作都某行資料應用了鎖,那只有當這個事務把鎖釋放,其他事務才能夠執行與該鎖衝突的操作。悲觀併發控制主要用於資料爭用激烈的環境,以及發生併發衝突時使用鎖保護資料的成本要低於回滾事務的成本的環境中。
悲觀鎖,正如其名,它指的是對資料被外界(包括本系統當前的其他事務,以及來自外部系統的事務處理)修改持保守態度(悲觀),因此,在整個資料處理過程中,將資料處於鎖定狀態。 悲觀鎖的實現,往往依靠資料庫提供的鎖機制 (也只有資料庫層提供的鎖機制才能真正保證資料訪問的排他性,否則,即使在本系統中實現了加鎖機制,也無法保證外部系統不會修改資料)
在資料庫中,悲觀鎖的流程如下:
在對任意記錄進行修改前,先嚐試為該記錄加上排他鎖(exclusive locking)。如果加鎖失敗,說明該記錄正在被修改,那麼當前查詢可能要等待或者丟擲異常。 具體響應方式由開發者根據實際需要決定。如果成功加鎖,那麼就可以對記錄做修改,事務完成後就會解鎖了。其間如果有其他對該記錄做修改或加排他鎖的操作,都會等待我們解鎖或直接丟擲常。
MySQL InnoDB中使用悲觀鎖
要使用悲觀鎖,我們必須關閉mysql資料庫的自動提交屬性,因為MySQL預設使用autocommit模式,也就是說,當你執行一個更新操作後,MySQL會立刻將結果進行提交。 set autocommit=0;
//0.開始事務
begin;/begin work;/start transaction; (三者選一就可以)
//1.查詢出商品資訊
select status from t_goods where id=1 for update;
//2.根據商品資訊生成訂單
insert into t_orders (id,goods_id) values (null,1);
//3.修改商品status為2
update t_goods set status=2;
//4.提交事務
commit;/commit work;
上面的查詢語句中,我們使用了 select…for update 的方式,這樣就通過開啟排他鎖的方式實現了悲觀鎖。此時在t_goods表中,id為1的 那條資料就被我們鎖定了,其它的事務必須等本次事務提交之後才能執行。這樣我們可以保證當前的資料不會被其它事務修改。
上面我們提到,使用 select…for update 會把資料給鎖住,不過我們需要注意一些鎖的級別,MySQL InnoDB預設行級鎖。行級鎖都是基於索引的,如果一條SQL語句用不到索引是不會使用行級鎖的,會使用表級鎖把整張表鎖住,這點需要注意。
優點與不足
悲觀併發控制實際上是“先取鎖再訪問”的保守策略,為資料處理的安全提供了保證。但是在效率方面,處理加鎖的機制會讓資料庫產生額外的開銷,還有增加產生死鎖的機會;另外,在只讀型事務處理中由於不會產生衝突,也沒必要使用鎖,這樣做只能增加系統負載;還有會降低了並行性,一個事務如果鎖定了某行資料,其他事務就必須等待該事務處理完才可以處理那行數
樂觀鎖
在關係資料庫管理系統裡,樂觀併發控制(又名“樂觀鎖”,Optimistic Concurrency Control,縮寫“OCC”)是一種併發控制的方法。它假設多使用者併發的事務在處理時不會彼此互相影響,各事務能夠在不產生鎖的情況下處理各自影響的那部分資料。在提交資料更新之前,每個事務會先檢查在該事務讀取資料後,有沒有其他事務又修改了該資料。如果其他事務有更新的話,正在提交的事務會進行回滾。樂觀事務控制最早是由孔祥重(H.T.Kung)教授提出。
樂觀鎖( Optimistic Locking ) 相對悲觀鎖而言,樂觀鎖假設認為資料一般情況下不會造成衝突,所以在資料進行提交更新的時候,才會正式對資料的衝突與否進行檢測,如果發現衝突了,則讓返回使用者錯誤的資訊,讓使用者決定如何去做。
相對於悲觀鎖,在對資料庫進行處理的時候,樂觀鎖並不會使用資料庫提供的鎖機制。一般的實現樂觀鎖的方式就是記錄資料版本。
資料版本,為資料增加的一個版本標識。當讀取資料時,將版本標識的值一同讀出,資料每更新一次,同時對版本標識進行更新。當我們提交更新的時候,判斷資料庫表對應記錄的當前版本資訊與第一次取出來的版本標識進行比對,如果資料庫表當前版本號與第一次取出來的版本標識值相等,則予以更新,否則認為是過期資料。
實現資料版本有兩種方式,第一種是使用版本號,第二種是使用時間戳。
使用版本號實現樂觀鎖
使用版本號時,可以在資料初始化時指定一個版本號,每次對資料的更新操作都對版本號執行+1操作。並判斷當前版本號是不是該資料的最新的版本號。
1.查詢出商品資訊
select (status,status,version) from t_goods where id=#{id}
2.根據商品資訊生成訂單
3.修改商品status為2
update t_goods
set status=2,version=version+1
where id=#{id} and version=#{version};
優點與不足
樂觀併發控制相信事務之間的資料競爭(data race)的概率是比較小的,因此儘可能直接做下去,直到提交的時候才去鎖定,所以不會產生任何鎖和死鎖。但如果直接簡單這麼做,還是有可能會遇到不可預期的結果,例如兩個事務都讀取了資料庫的某一行,經過修改以後寫回資料庫,這時就遇到了問題。
四.drop、truncate和delete的區別
(1)DELETE語句執行刪除的過程是每次從表中刪除一行,並且同時將該行的刪除操作作為事務記錄在日誌中儲存以便進行進行回滾操作。
TRUNCATE TABLE 則一次性地從表中刪除所有的資料並不把單獨的刪除操作記錄記入日誌儲存,刪除行是不能恢復的。並且在刪除的過程中不會啟用與表有關的刪除觸發器。執行速度快。
(2)表和索引所佔空間。
當表被TRUNCATE 後,這個表和索引所佔用的空間會恢復到初始大小,
DELETE操作不會減少表或索引所佔用的空間。
drop語句將表所佔用的空間全釋放掉。
(3)一般而言,drop > truncate > delete
(4)應用範圍。
TRUNCATE 只能對TABLE; DELETE可以是table和view
(5)TRUNCATE 和DELETE只刪除資料, DROP則刪除整個表(結構和資料)。
(6)truncate與不帶where的delete :只刪除資料,而不刪除表的結構(定義)drop語句將刪除表的結構被依賴的約束(constrain),觸發器(trigger)索引(index);依賴於該表的儲存過程/函式將被保留,但其狀態會變為:invalid。
(7)delete語句為DML(data maintain Language),這個操作會被放到 rollback segment中,事務提交後才生效。如果有相應的 tigger,執行的時候將被觸發。
(8)truncate、drop是DLL(data define language),操作立即生效,原資料不放到 rollback segment中,不能回滾
(9)在沒有備份情況下,謹慎使用 drop 與 truncate。要刪除部分資料行採用delete且注意結合where來約束影響範圍。回滾段要足夠大。要刪除表用drop;若想保留表而將表中資料刪除,如果於事務無關,用truncate即可實現。如果和事務有關,或老師想觸發trigger,還是用delete。
(10) Truncate table 表名 速度快,而且效率高,因為:
truncate table 在功能上與不帶 WHERE 子句的 DELETE 語句相同:二者均刪除表中的全部行。但 TRUNCATE TABLE 比 DELETE 速度快,且使用的系統和事務日誌資源少。DELETE 語句每次刪除一行,並在事務日誌中為所刪除的每行記錄一項。TRUNCATE TABLE 通過釋放儲存表資料所用的資料頁來刪除資料,並且只在事務日誌中記錄頁的釋放。
(11) TRUNCATE TABLE 刪除表中的所有行,但表結構及其列、約束、索引等保持不變。新行標識所用的計數值重置為該列的種子。如果想保留標識計數值,請改用 DELETE。如果要刪除表定義及其資料,請使用 DROP TABLE 語句。
(12) 對於由 FOREIGN KEY 約束引用的表,不能使用 TRUNCATE TABLE,而應使用不帶 WHERE 子句的 DELETE 語句。由於 TRUNCATE TABLE 不記錄在日誌中,所以它不能啟用觸發器。
1 . delete
1、delete是DML,執行delete操作時,每次從表中刪除一行,並且同時將該行的的刪除操作記錄在redo和undo表空間中以便進行回滾(rollback)和重做操作,但要注意表空間要足夠大,需要手動提交(commit)操作才能生效,可以通過rollback撤消操作。
2、delete可根據條件刪除表中滿足條件的資料,如果不指定where子句,那麼刪除表中所有記錄。
3、delete語句不影響表所佔用的extent,高水線(high watermark)保持原位置不變。
2 . truncate
1、truncate是DDL,會隱式提交,所以,不能回滾,不會觸發觸發器。
2、truncate會刪除表中所有記錄,並且將重新設定高水線和所有的索引,預設情況下將空間釋放到minextents個extent,除非使用reuse storage,。不會記錄日誌,所以執行速度很快,但不能通過rollback撤消操作(如果一不小心把一個表truncate掉,也是可以恢復的,只是不能通過rollback來恢復)。
3、對於外來鍵(foreignkey )約束引用的表,不能使用 truncate table,而應使用不帶 where 子句的 delete 語句。
4、truncatetable不能用於參與了索引檢視的表。
3 . drop
1、drop是DDL,會隱式提交,所以,不能回滾,不會觸發觸發器。
2、drop語句刪除表結構及所有資料,並將表所佔用的空間全部釋放。
3、drop語句將刪除表的結構所依賴的約束,觸發器,索引,依賴於該表的儲存過程/函式將保留,但是變為invalid狀態。
總結:
1、在速度上,一般來說,drop> truncate > delete。
2、在使用drop和truncate時一定要注意,雖然可以恢復,但為了減少麻煩,還是要慎重。
3、如果想刪除部分資料用delete,注意帶上where子句,回滾段要足夠大;
如果想刪除表,當然用drop;
如果想保留表而將所有資料刪除,如果和事務無關,用truncate即可;
如果和事務有關,或者想觸發trigger,還是用delete;
如果是整理表內部的碎片,可以用truncate跟上reuse stroage,再重新匯入/插入資料。
1、超鍵、候選鍵、主鍵、外來鍵
超鍵:在關係中能唯一標識元組的屬性集稱為關係模式的超鍵。一個屬性可以為作為一個超鍵,多個屬性組合在一起也可以作為一個超鍵。超鍵包含候選鍵和主鍵。
候選鍵:是最小超鍵,即沒有冗餘元素的超鍵。
主鍵:資料庫表中對儲存資料物件予以唯一和完整標識的資料列或屬性的組合。一個數據列只能有一個主鍵,且主鍵的取值不能缺失,即不能為空值(Null)。
外來鍵:在一個表中存在的另一個表的主鍵稱此表的外來鍵。
2、什麼是事務?什麼是鎖?
事務:就是被繫結在一起作為一個邏輯工作單元的 SQL 語句分組,如果任何一個語句操作失敗那麼整個操作就被失敗,以後操作就會回滾到操作前狀態,或者是上有個節點。為了確保要麼執行,要麼不執行,就可以使用事務。要將有組語句作為事務考慮,就需要通過 ACID 測試,即原子性,一致性,隔離性和永續性。
鎖:在所以的 DBMS 中,鎖是實現事務的關鍵,鎖可以保證事務的完整性和併發性。與現實生活中鎖一樣,它可以使某些資料的擁有者,在某段時間內不能使用某些資料或資料結構。當然鎖還分級別的。
3、資料庫事務的四個特性及含義
原子性:整個事務中的所有操作,要麼全部完成,要麼全部不完成,不可能停滯在中間某個環節。事務在執行過程中發生錯誤,會被回滾(Rollback)到事務開始前的狀態,就像這個事務從來沒有執行過一樣。
一致性:在事務開始之前和事務結束以後,資料庫的完整性約束沒有被破壞。
隔離性:隔離狀態執行事務,使它們好像是系統在給定時間內執行的唯一操作。如果有兩個事務,執行在相同的時間內,執行 相同的功能,事務的隔離性將確保每一事務在系統中認為只有該事務在使用系統。這種屬性有時稱為序列化,為了防止事務操作間的混淆,必須序列化或序列化請 求,使得在同一時間僅有一個請求用於同一資料。
永續性:在事務完成以後,該事務所對資料庫所作的更改便持久的儲存在資料庫之中,並不會被回滾。
4、什麼是檢視?
檢視是一種虛擬的表,具有和物理表相同的功能。可以對檢視進行增,改,查,操作,試圖通常是有一個表或者多個表的行或列的子集。對檢視的修改不影響基本表。它使得我們獲取資料更容易,相比多表查詢。
如下兩種場景一般會使用到檢視:
(1)不希望訪問者獲取整個表的資訊,只暴露部分欄位給訪問者,所以就建一個虛表,就是檢視。
(2)查詢的資料來源於不同的表,而查詢者希望以統一的方式查詢,這樣也可以建立一個檢視,把多個表查詢結果聯合起來,查詢者只需要直接從檢視中獲取資料,不必考慮資料來源於不同表所帶來的差異。
注:這個檢視是在資料庫中建立的 而不是用程式碼建立的。
5、觸發器的作用?
觸發器是一中特殊的儲存過程,主要是通過事件來觸發而被執行的。它可以強化約束,來維護資料的完整性和一致性,可以跟蹤資料庫內的操作從而不允許未經許可的更新和變化。可以聯級運算。如,某表上的觸發器上包含對另一個表的資料操作,而該操作又會導致該表觸發器被觸發。
6、 維護資料庫的完整性和一致性,你喜歡用觸發器還是自寫業務邏輯?為什麼?
儘可能使用約束,如 check, 主鍵,外來鍵,非空欄位等來約束,這樣做效率最高,也最方便。其次是使用觸發器,這種方法可以保證,無論什麼業務系統訪問資料庫都可以保證資料的完整新和一致性。最後考慮的是自寫業務邏輯,但這樣做麻煩,程式設計複雜,效率低下。
7、索引的作用?和它的優點缺點是什麼?
資料庫索引,是資料庫管理系統中一個排序的資料結構,以協助快速查詢、更新資料庫表中資料。索引的實現通常使用B樹及其變種B+樹。
在資料之外,資料庫系統還維護著滿足特定查詢演算法的資料結構,這些資料結構以某種方式引用(指向)資料,這樣就可以在這些資料結構上實現高階查詢演算法。這種資料結構,就是索引。
為表設定索引要付出代價的:一是增加了資料庫的儲存空間,二是在插入和修改資料時要花費較多的時間(因為索引也要隨之變動)。
建立索引可以大大提高系統的效能(優點):
第一,通過建立唯一性索引,可以保證資料庫表中每一行資料的唯一性。
第二,可以大大加快資料的檢索速度,這也是建立索引的最主要的原因。
第三,可以加速表和表之間的連線,特別是在實現資料的參考完整性方面特別有意義。
第四,在使用分組和排序子句進行資料檢索時,同樣可以顯著減少查詢中分組和排序的時間。
第五,通過使用索引,可以在查詢的過程中,使用優化隱藏器,提高系統的效能。
也許會有人要問:增加索引有如此多的優點,為什麼不對錶中的每一個列建立一個索引呢?因為,增加索引也有許多不利的方面:
第一,建立索引和維護索引要耗費時間,這種時間隨著資料量的增加而增加。
第二,索引需要佔物理空間,除了資料表佔資料空間之外,每一個索引還要佔一定的物理空間,如果要建立聚簇索引,那麼需要的空間就會更大。
第三,當對錶中的資料進行增加、刪除和修改的時候,索引也要動態的維護,這樣就降低了資料的維護速度。
索引是建立在資料庫表中的某些列的上面。在建立索引的時候,應該考慮在哪些列上可以建立索引,在哪些列上不能建立索引。
一般來說,應該在這些列上建立索引:
(1)在經常需要搜尋的列上,可以加快搜索的速度;
(2)在作為主鍵的列上,強制該列的唯一性和組織表中資料的排列結構;
(3)在經常用在連線的列上,這些列主要是一些外來鍵,可以加快連線的速度;
(4)在經常需要根據範圍進行搜尋的列上建立索引,因為索引已經排序,其指定的範圍是連續的;
(5)在經常需要排序的列上建立索引,因為索引已經排序,這樣查詢可以利用索引的排序,加快排序查詢時間;
(6)在經常使用在WHERE子句中的列上面建立索引,加快條件的判斷速度。
同樣,對於有些列不應該建立索引:
第一,對於那些在查詢中很少使用或者參考的列不應該建立索引。這是因為,既然這些列很少使用到,因此有索引或者無索引,並不能提高查詢速度。相反,由於增加了索引,反而降低了系統的維護速度和增大了空間需求。
第二,對於那些只有很少資料值的列也不應該增加索引。這是因為,由於這些列的取值很少,例如人事表的性別列,在查詢的結果中,結果集的資料行佔了表中資料行的很大比例,即需要在表中搜索的資料行的比例很大。增加索引,並不能明顯加快檢索速度。
第三,對於那些定義為text, image和bit資料型別的列不應該增加索引。這是因為,這些列的資料量要麼相當大,要麼取值很少。
第四,當修改效能遠遠大於檢索效能時,不應該建立索引。這是因為,修改效能和檢索效能是互相矛盾的。當增加索引時,會提高檢索效能,但是會降低修改效能。當減少索引時,會提高修改效能,降低檢索效能。因此,當修改效能遠遠大於檢索效能時,不應該建立索引。
8、drop,delete與truncate的區別
drop直接刪掉表 。
truncate刪除表中資料,再插入時自增長id又從1開始 。
delete刪除表中資料,可以加where字句。
(1) DELETE語句執行刪除的過程是每次從表中刪除一行,並且同時將該行的刪除操作作為事務記錄在日誌中儲存以便進行進行回滾操作。TRUNCATE TABLE 則一次性地從表中刪除所有的資料並不把單獨的刪除操作記錄記入日誌儲存,刪除行是不能恢復的。並且在刪除的過程中不會啟用與表有關的刪除觸發器。執行速度快。
(2) 表和索引所佔空間。當表被TRUNCATE 後,這個表和索引所佔用的空間會恢復到初始大小,而DELETE操作不會減少表或索引所佔用的空間。drop語句將表所佔用的空間全釋放掉。
(3) 一般而言,drop > truncate > delete
(4) 應用範圍。TRUNCATE 只能對TABLE;DELETE可以是table和view
(5) TRUNCATE 和DELETE只刪除資料,而DROP則刪除整個表(結構和資料)。
(6) truncate與不帶where的delete :只刪除資料,而不刪除表的結構(定義)drop語句將刪除表的結構被依賴的約束(constrain),觸發器(trigger)索引(index);依賴於該表的儲存過程/函式將被保留,但其狀態會變為:invalid。
(7) delete語句為DML(data maintain Language),這個操作會被放到 rollback segment中,事務提交後才生效。如果有相應的 tigger,執行的時候將被觸發。
(8) truncate、drop是DLL(data define language),操作立即生效,原資料不放到 rollback segment中,不能回滾。
(9) 在沒有備份情況下,謹慎使用 drop 與 truncate。要刪除部分資料行採用delete且注意結合where來約束影響範圍。回滾段要足夠大。要刪除表用drop;若想保留表而將表中資料刪除,如果於事務無關,用truncate即可實現。如果和事務有關,或老師想觸發trigger,還是用delete。
(10) Truncate table 表名 速度快,而且效率高,因為:
truncate table 在功能上與不帶 WHERE 子句的 DELETE 語句相同:二者均刪除表中的全部行。但 TRUNCATE TABLE 比 DELETE 速度快,且使用的系統和事務日誌資源少。DELETE 語句每次刪除一行,並在事務日誌中為所刪除的每行記錄一項。TRUNCATE TABLE 通過釋放儲存表資料所用的資料頁來刪除資料,並且只在事務日誌中記錄頁的釋放。
(11) TRUNCATE TABLE 刪除表中的所有行,但表結構及其列、約束、索引等保持不變。新行標識所用的計數值重置為該列的種子。如果想保留標識計數值,請改用 DELETE。如果要刪除表定義及其資料,請使用 DROP TABLE 語句。
(12) 對於由 FOREIGN KEY 約束引用的表,不能使用 TRUNCATE TABLE,而應使用不帶 WHERE 子句的 DELETE 語句。由於 TRUNCATE TABLE 不記錄在日誌中,所以它不能啟用觸發器。
9、SQL常用命令:
CREATE TABLE Student(
ID NUMBER PRIMARY KEY,
NAME VARCHAR2(50) NOT NULL);//建表
CREATE VIEW view_name AS
Select * FROM Table_name;//建檢視
Create UNIQUE INDEX index_name ON TableName(col_name);//建索引
INSERT INTO tablename {column1,column2,…} values(exp1,exp2,…);//插入
INSERT INTO Viewname {column1,column2,…} values(exp1,exp2,…);//插入檢視實際影響表
UPDATE tablename SET name=‘zang 3’ condition;//更新資料
DELETE FROM Tablename WHERE condition;//刪除
GRANT (Select,delete,…) ON (物件) TO USER_NAME [WITH GRANT OPTION];//授權
REVOKE (許可權表) ON(物件) FROM USER_NAME [WITH REVOKE OPTION] //撤權
10、內聯接,外聯接區別?
內連線是保證兩個表中所有的行都要滿足連線條件,而外連線則不然。
在外連線中,某些不滿條件的列也會顯示出來,也就是說,只限制其中一個表的行,而不限制另一個表的行。分左連線、右連線、全連線三種
11、什麼叫檢視?遊標是什麼?
答:檢視是一種虛擬的表,具有和物理表相同的功能。可以對檢視進行增,改,查,操作,試圖通常是有一個表或者多個表的行或列的子集。對檢視的修改不影響基本表。它使得我們獲取資料更容易,相比多表查詢。
遊標:是對查詢出來的結果集作為一個單元來有效的處理。遊標可以定在該單元中的特定行,從結果集的當前行檢索一行或多行。可以對結果集當前行做修改。一般不使用遊標,但是需要逐條處理資料的時候,遊標顯得十分重要。
12、NULL是什麼意思?
NULL(空)這個值是資料庫世界裡一個非常難纏的東西,所以有不少應聘者會在這個問題上跌跟頭您也不要覺得意外。
NULL這個值表示UNKNOWN(未知):它不表示“”(空字串)。假設您的SQL Server資料庫裡有ANSI_NULLS,當然在預設情況下會有,對NULL這個值的任何比較都會生產一個NULL值。您不能把任何值與一個 UNKNOWN值進行比較,並在邏輯上希望獲得一個答案。您必須使用IS NULL操作符。
13、日誌的作用是什麼
日誌檔案(Log File)記錄所有對資料庫資料的修改,主要是保護資料庫以防止故障,以及恢復資料時使用。其特點如下:
a)每一個數據庫至少包含兩個日誌檔案組。每個日誌檔案組至少包含兩個日誌檔案成員。
b)日誌檔案組以迴圈方式進行寫操作。
c)每一個日誌檔案成員對應一個物理檔案。
記錄資料庫事務,最大限度地保證資料的一致性與安全性
重做日誌檔案:含對資料庫所做的更改記錄,這樣萬一出現故障可以啟用資料恢復,一個數據庫至少需要兩個重做日誌檔案
歸檔日誌檔案:是重做日誌檔案的離線副本,這些副本可能對於從介質失敗中進行恢復很必要。