數據庫技術與併發
1、數據庫基本知識
(1)主鍵與外鍵
(2)SQL中的join語句與多表查詢
(3)having語句
SELECT Customer,SUM(OrderPrice) FROM Orders
WHERE Customer='Bush' OR Customer='Adams'
GROUP BY Customer
HAVING SUM(OrderPrice)>1500
(4)SQL中的<=>作用
像常規的=運算符一樣,兩個值進行比較,結果是0(不等於)或1(相等);換句話說:'A'<=>'B'得0和'a'<=>'a‘得1。
2)和=號的不同點:
和=運算符不同的是,NULL可以作爲<=>的比較對象,但=號運算符不能把NULL作爲比較對象。所以當比較對象是NULL時請使用<=>。
例如:'a' <=> NULL 得0 NULL<=> NULL 得出 1;
(5)ER模型和關係模型
(6)SQL語句中的NULL應用
(7)SQL語句中的模糊查詢
比如 SELECT * FROM [user] WHERE u_name LIKE '_三_',只找出“唐三藏”這樣u_name爲三個字且中間一個字是“三”的;
比如 SELECT * FROM [user] WHERE u_name LIKE '[張李王]三'
將找出“張三”、“李三”、“王三”(而不是“張李王三”);
比如 SELECT * FROM [user] WHERE u_name LIKE '[^張李王]三'
將找出不姓“張”、“李”、“王”的“趙三”、“孫三”等;
2、一般數據庫若出現日誌滿了,會出現什麼情況,是否還能使用?
答:只能執行查詢等讀操作,不能執行更改,備份等寫操作,原因是任何寫操作都要記錄日誌,也就是說基本上處於不能使用的狀態。3、在一條SQL語句中同時對兩個數據庫中的不同表進行操作,有什麼好的解決方法嗎?
答:解決辦法:事務和存儲過程。即將操作多個表的操作放入到事務中進行處理。
4、數據庫觸發器怎麼工作的?
答:觸發器主要是通過事件進行觸發而被執行的,當對某一表進行諸如UPDATE、 INSERT、 DELETE 這些操作時,數據庫就會自動執行觸發器所定
義的SQL 語句,從而確保對數據的處理必須符合由這些SQL 語句所定義的規則。
5、數據庫的主索引、唯一索引、候選索引、普通索引
答:主索引:主索引是指定字段或表達式中不允許出現重複值的索引,其索引表達式值能夠唯一標識每個記錄處理順序,一個表只能創建一個主索引;
候選索引:和主索引具有相同特性,要求字段值的惟一性,一個表可建立多個候選索引;
普通索引:不僅允許字段出現重複值,且索引項中也允許出現重複值,一個表可建立多個普通索引;
惟一索引:指索引項的惟一,而非字段值的惟一。指定字段的首次出現值爲基礎,一個表可建立多個惟一索引.
6、數據庫視圖
答:視圖是虛表,是從一個或幾個基本表(或視圖)中導出的表,在系統的數據字典中僅存放了視圖的定義,不存放視圖對應的數據。
視圖是原始數據庫數據的一種變換,是查看錶中數據的另外一種方式。可以將視圖看成是一個移動的窗口,通過它可以看到感興趣的數據。
視圖是從一個或多個實際表中獲得的,這些表的數據存放在數據庫中。那些用於產生視圖的表叫做該視圖的基表。一個視圖也可以從另一個視圖中產
生。視圖本質上只用於查詢,如果用於增刪改也是先查表在進行其他操作(因爲視圖自身沒有數據);
總結:視圖是在表的基礎上產生的,相當於表上的一個窗口,級別低於表。並且視圖基本只用於查詢;
7、數據庫三級模式
答:三級模式結構:外模式(又叫子模式)、模式、內模式 ;
一、模式(Schema)
定義:也稱邏輯模式,是數據庫中全體數據的邏輯結構和特徵的描述,是所有用戶的公共數據視圖。
理解:
① 一個數據庫只有一個模式;
② 是數據庫數據在邏輯級上的視圖;
③ 數據庫模式以某一種數據模型爲基礎;
④ 定義模式時不僅要定義數據的邏輯結構(如數據記錄由哪些數據項構成,數據項的名字、類型、取值範圍等),而且要定義與數據有關的安全性、完整性要求,定義這些數據之間的聯繫。
二、外模式(External Schema)
定義:也稱子模式(Subschema)或用戶模式,是數據庫用戶(包括應用程序員和最終用戶)能夠看見和使用的局部數據的邏輯結構和特徵的描述,是數據庫用戶的數據視圖,是與某一應用有關的數據的邏輯表示。
理解:
① 一個數據庫可以有多個外模式;
② 外模式就是用戶視圖;
③ 外模式是保證數據安全性的一個有力措施。
三、內模式(Internal Schema)
定義:也稱存儲模式(Storage Schema),它是數據物理結構和存儲方式的描述,是數據在數據庫內部的表示方式(例如,記錄的存儲方式是順序存儲、按照B樹結構存儲還是按hash方法存儲;索引按照什麼方式組織;數據是否壓縮存儲,是否加密;數據的存儲記錄結構有何規定)。
理解:
① 一個數據庫只有一個內模式;
② 一個表可能由多個文件組成,如:數據文件、索引文件。
它是數據庫管理系統(DBMS)對數據庫中數據進行有效組織和管理的方法
其目的有:
① 爲了減少數據冗餘,實現數據共享;
② 爲了提高存取效率,改善性能。
8、數據庫解決併發操作帶來的數據不一致性問題,一般採用的方法是?
答:針對併發控制一般採用 封鎖、時間戳、樂觀控制法。但是商用的DBMS一般採用的是封鎖,使用鎖機制,每次只允許一個任務對其操作,操作完成後解鎖,才允許下一個任務對其進行操作。
9、數據庫4種隔離級別
答:在數據庫操作中,爲了有效保證併發讀取數據的正確性,提出的事務隔離級別。
數據庫事務的隔離級別有4個,由低到高依次爲Read uncommitted(未授權讀取、讀未提交)、Read committed(授權讀取、讀提交)、Repeatable read(可重複讀取)、Serializable(序列化),這四個級別可以逐個解決髒讀、不可重複讀、幻讀這幾類問題。
之所以提出事務隔離級別,是因爲在一個事務執行過程中,可能會出現以下幾種情況:
1、更新丟失
兩個事務都同時更新一行數據,一個事務對數據的更新把另一個事務對數據的更新覆蓋了。這是因爲系統沒有執行任何的鎖操作,因此併發事務並沒有被隔離開來。
2、髒讀
一個事務讀取到了另一個事務未提交的數據操作結果。
3、不可重複讀(Non-repeatable Reads):一個事務對同一行數據重複讀取兩次,但是卻得到了不同的結果。
包括以下情況:
(1) 虛讀:事務T1讀取某一數據後,事務T2對其做了修改,當事務T1再次讀該數據時得到與前一次不同的值。
(2) 幻讀(Phantom Reads):事務在操作過程中進行兩次查詢,第二次查詢的結果包含了第一次查詢中未出現的數據或者缺少了第一次查詢中出現的數據(這裏並不要求兩次查詢的SQL語句相同)。這是因爲在兩次查詢過程中有另外一個事務插入數據造成的。
下面介紹一下這幾種事務隔離級別的區別以及可能出現的問題:
Read uncommitted(未授權讀取、讀未提交):
如果一個事務已經開始寫數據,則另外一個事務則不允許同時進行寫操作,但允許其他事務讀此行數據。該隔離級別可以通過“排他寫鎖”實現。
避免了更新丟失,卻可能出現髒讀。也就是說事務B讀取到了事務A未提交的數據。
Read committed(授權讀取、讀提交):
讀取數據的事務允許其他事務繼續訪問該行數據,但是未提交的寫事務將會禁止其他事務訪問該行。
該隔離級別避免了髒讀,但是卻可能出現不可重複讀。事務A事先讀取了數據,事務B緊接了更新了數據,並提交了事務,而事務A再次讀取該數據時,數據已經發生了改變。
Repeatable read(可重複讀取):
讀取數據的事務將會禁止寫事務(但允許讀事務),寫事務則禁止任何其他事務。
避免了不可重複讀取和髒讀,但是有時可能出現幻讀。這可以通過“共享讀鎖”和“排他寫鎖”實現。
Serializable(序列化):
提供嚴格的事務隔離。它要求事務序列化執行,事務只能一個接着一個地執行,但不能併發執行。如果僅僅通過“行級鎖”是無法實現事務序列化的,必須通過其他機制保證新插入的數據不會被剛執行查詢操作的事務訪問到。
序列化是最高的事務隔離級別,同時代價也花費最高,性能很低,一般很少使用,在該級別下,事務順序執行,不僅可以避免髒讀、不可重複讀,還避免了幻像讀。
隔離級別越高,越能保證數據的完整性和一致性,但是對併發性能的影響也越大。對於多數應用程序,可以優先考慮把數據庫系統的隔離級別設爲Read Committed。它能夠避免髒讀取,而且具有較好的併發性能。儘管它會導致不可重複讀、幻讀和第二類丟失更新這些併發問題,在可能出現這類問題的個別場合,可以由應用程序採用悲觀鎖或樂觀鎖來控制。
大多數數據庫的默認級別就是Read committed,比如Sql Server , Oracle。
MySQL的默認隔離級別就是Repeatable read。
10、悲觀鎖和樂觀鎖
答:通俗解釋就是:
悲觀鎖(Pessimistic Lock),顧名思義,就是很悲觀,每次去拿數據的時候都認爲別人會修改,所以每次在拿數據的時候都會上鎖,這樣別人想拿這個數據就會block直到它拿到鎖。傳統的關係型數據庫裏邊就用到了很多這種鎖機制,比如行鎖,表鎖等,讀鎖,寫鎖等,都是在做操作之前先上鎖。
樂觀鎖(Optimistic Lock), 顧名思義,就是很樂觀,每次去拿數據的時候都認爲別人不會修改,所以不會上鎖,但是在更新的時候會判斷一下在此期間別人有沒有去更新這個數據,可以使用版本號等機制。樂觀鎖適用於多讀的應用類型,這樣可以提高吞吐量,像數據庫如果提供類似於write_condition機制的其實都是提供的樂觀鎖。
兩種鎖各有優缺點,不可認爲一種好於另一種,像樂觀鎖適用於寫比較少的情況下,即衝突真的很少發生的時候,這樣可以省去了鎖的開銷,加大了系
統的整個吞吐量。但如果經常產生衝突,上層應用會不斷的進行retry,這樣反倒是降低了性能,所以這種情況下用悲觀鎖就比較合適。
樂觀鎖實現:爲數據增加一個版本標識,一般是通過爲數據庫表增加一個數字類型的 “version” 字段或者時間戳類型來實現。當讀取數據時,將
version字段的值一同讀出,數據每更新一次,對此version值加1。當我們提交更新的時候,判斷數據庫表對應記錄的當前版本信息與第一次取出來的
version值進行比對,如果數據庫表當前版本號與第一次取出來的version值相等,則予以更新,否則認爲是過期數據。用下面的一張圖來說明:
悲觀鎖實現:
需要使用數據庫的鎖機制,比如SQL SERVER 的TABLOCKX(排它表鎖) 此選項被選中時,SQL Server 將在整個表上置排它鎖直至該命令或事務結
束,這將防止其他進程讀取或修改表中的數據。
11、bernstein條件
答:就是講兩個過程如果有數據衝突(Data hazard),那麼就沒法並行執行。比如,一個過程指令的運行會修改另一個過程指令的變量參數,那麼該兩者就無法並行。常見的s1:x=a+b;s2:y=c+x;前者影響後者,無法並行。
12、數據庫操作語句類型
答:有4種:DQL、DML、DDL、DCL;
DQL:數據庫查詢語句,SELECT;
DML:數據庫操縱語句,INSERT、DELETE、UPDATE;
DDL:數據庫定義語句,CREATE;
DCL:數據庫控制語句,數據控制語言DCL用來授予或回收訪問數據庫的某種特權,並控制數據庫操縱事務發生的時間及效果,對數據庫實行監視
等。例如: 1)GRANT:授權;REVOKE:收回所授權限 2) ROLLBACK [WORK] TO [SAVEPOINT]:回退到某一點 3) COMMIT [WORK]:提交(提交數據有三種類型:顯
式提交、隱式提交及自動提交)。
13、B樹索引和 HASH 索引的差異
答;如下:
(1)HASH索引只用於使用 = 或 <=> 操作符的等式比較。如果一定要使用範圍查詢 的話,只能使用B TREE索引;
(2)優化器不能使用 Hash 索引來加速 order by 操作;
(3)使用 Hash 索引時 MySQL 不能確定在兩個值之間大約有多少行。如果將一 個MyISAM表改爲的 Hash 索引 memory 表,
會影響一些查詢的執行效率;
(4)Hash索引只能使用整個關鍵字來搜索一行。
14、如何處理幾十萬條併發數據
答:常見的方法有:多主機分佈式處理、緩存技術、多線程
15、數據模型
答:數據模型的組成要素有:
1)數據結構,描述數據庫的組成對象以及對象之間的聯繫,數據結構是所描述的對象類型的集合,是對系統靜態特徵的描述;
2)數據操作,是指對數據庫中各種對象的實例允許執行的操作的集合,主要有查詢和更新;
3)數據的完整性約束條件,是一組完整性規則的集合。完整性規則是給定的數據模型中數據及其聯繫所具有的之約和依存規則,用以限定符合數據模型的數據庫狀態以及狀態的變化,以保證數據的正確、有效、相容。
16、數據庫第一、二、三範式(1NF、2NF、3NF)
答:參考:http://blog.csdn.net/famousdt/article/details/6921622
1NF:強調的是列的原子性,即列不能夠再分成其他幾列;
2NF:非主鍵列是否完全依賴於主鍵,還是依賴於主鍵的一部分;
3NF:非主鍵列是直接依賴於主鍵,還是直接依賴於非主鍵列。
17、數據庫系統的核心與基礎
答:1)數據庫系統的核心和基礎,是數據模型,現有的數據庫系統均是基於某種數據模型的;
2)數據庫系統的核心是數據庫管理系統。
18、關係模型的三類完整性約束
答:關係模型有三類完整性約束:實體完整性、參照完整性和用戶定義的完整性;
19、數據庫觸發器與存儲過程
答:觸發器:
(1)觸發器定義:觸發器是一種特殊的存儲過程,它在插入,刪除或修改特定表中的數據時觸發執行或激活,它比數據庫本身標準的功能有更精細和更復雜的數據控制能力。
注意事項:
1)只有表纔可以支持觸發器,視圖和臨時表都不支持觸發器;
2)每個表的每個事件只支持一個觸發器,因此每個表最多支持6個觸發器;
3)單一觸發器不能與多個操作相關;
4)觸發器不能更新和覆蓋,如果想更新一個觸發器必須先刪除,再創建;
(2)爲什麼要使用觸發器?
每當增加一個顧客到某個數據庫表時,都檢查其電話號碼格式是否正確,州的縮寫是否爲大寫
每當訂購一個產品時,都在庫存數量中減去訂購數量
無論何時刪除一行,都在某個存檔表中保留一個副本
共同的特點就是都需要在某個表發生更改時自動處理,觸發器是MySQL響應以下任意語句而自動執行的一條MySQL語句
(3)如何使用觸發器?
create trigger newproduct after insert on products
for each row select ‘product added’
newproduct:觸發器的名字
after:一個操作發生之前或之後執行
存儲過程:
存儲過程就是爲以後的使用而保存的一條或者多條MySQL語句的集合
爲什麼使用存儲過程?
1)通過把處理封裝在容易使用的單元,簡化複雜的操作
2)簡化對變動的管理。如果表名、列名或業務邏輯有變化,只需要更改存儲過程的代碼。使用它的人員甚至不需要知道這些變化
3)提高性能
總結起來就是簡單,安全,高性能
如何使用存儲過程?
創建存儲過程:
create procedure productpricing()
begin
select avg(prod_price) as priceaverage
from products;
end;
使用存儲過程:
call productpricing()
20、SQL語句中儘量避免使用or作爲條件連接
答:應儘量避免在 where 子句中使用 or 來連接條件,否則將導致引擎放棄使用索引而進行全表掃描,如:
select id from t where num=10 or num=20;
可以這樣查詢:
select id from t where num=10
union all
select id from t where num=20;
有時候,中間的連接符也可以直接用union,其與union all的區別是:
union會自動壓縮多個結果集合中的重複結果,而union all則將所有的結果全部顯示出來,不管是不是重複。
兩者查找速度:
Union因爲要進行重複值掃描,所以效率低。如果合併沒有刻意要刪除重複行,那麼就使用Union All;
21、池化技術——線程池、連接池、內存池
1)非常少(幾沒有) 堆碎片;
2)比通常的內存申請/釋放(比如通過malloc, new等)的方式快。
22、常見的數據備份方式
答:常見的數據備份方式有:完全備份(Full backup)、增量備份( Incremental backup)、差異備份(Differential backup)。具體如下: