數據庫技術與併發(筆記)

數據庫技術與併發

1、數據庫基本知識

(1)主鍵與外鍵

主鍵:數據表屬性中可以唯一表示行數據的一個屬性,比如學生信息表中的學號;
外鍵:如果兩個表的公共關鍵字在一個表中是主鍵,那麼這個公共關鍵字被稱爲另一個表的外鍵。由此可見,外鍵表示了兩個表之間的關聯。以另一個表的外鍵作主鍵的表被稱爲主表,具有此外鍵的表被稱爲主表的從表。外鍵又稱作外關鍵字。

(2)SQL中的join語句與多表查詢

作用:JOIN的作用就是通過主鍵外鍵關係拼接兩個表,從而實現對多表進行聯合查詢;
舉例:(1)普通的聯合查詢:SELECT Persons.LastName, Persons.FirstName, Orders.OrderNo from Persons, Orders where Persons.Id_P = Orders.Id_P ;
(2)JOIN方式的聯合查詢:上述用於查詢兩個表(Persons,Orders)中主鍵外鍵相等的行,也可以使用join語句實現,如下:
SELECT Persons.LastName, Persons.FirstName, Orders.OrderNo from Persons INNER JOIN Orders ON Persons.Id_P = Orders.Id_P;

JOIN分類:
上述是內連接,除此之外,JOIN還有其他的連接方式:

內連接圖示:

FROM A INNER JOIN B on A.Key=B.Key

左外連接圖示:

右外鏈接圖示:

全外連接圖示:


交叉連接:
語句:cross join;
注意:沒有on條件

多表查詢需要通過join實現,一般格式都是:
(1)兩表聯合查詢:
FROM A a INNER JOIN B b on a.Key=b.Key WHERE ……;
join後面跟着on,用來確定聯合條件(a、b分別是表的別名);

(2)上述是兩表聯合,下面介紹三表聯合,一般如下:
FROM A a INNER JOIN B b ON a.Key=b.Key INNER JOIN C c ON c.Key=a.Key WHERE ……;
就是將兩表聯合的結果作爲一個表,繼續與第三個表聯合查詢。


(3)having語句

在 SQL 中where和having的區別:
Where 是一個約束聲明,使用Where約束來自數據庫的數據,Where是在結果返回之前起作用的,Where中不能使用聚合函數;
Having是一個過濾聲明,是在查詢返回結果集以後對查詢結果進行的過濾操作,在Having中可以使用聚合函數;
注:在查詢過程中聚合語句(sum、min、max、avg、count)要比having子句優先執行。而where子句在查詢過程中執行優先級高於聚合語
句。
HAVING語句後面應該是:組條件表達式(多個通過 AND、OR 或 NOT 組合在一起。);
總結:where由於不能和聚合函數(sum、min、avg、count)一起使用,故需引入having子句;
having使用舉例:
SELECT Customer,SUM(OrderPrice) FROM Orders
WHERE Customer='Bush' OR Customer='Adams'
GROUP BY Customer
HAVING SUM(OrderPrice)>1500
SUM在where執行之後,HAVING執行之前有效;

(4)SQL中的<=>作用

1)和=號的相同點:

像常規的=運算符一樣,兩個值進行比較,結果是0(不等於)或1(相等);換句話說:'A'<=>'B'得0和'a'<=>'a‘得1。

2)和=號的不同點:

和=運算符不同的是,NULL可以作爲<=>的比較對象,但=號運算符不能把NULL作爲比較對象。所以當比較對象是NULL時請使用<=>。

例如:'a' <=> NULL 得0 NULL<=> NULL 得出 1;

或者有一個對象可能爲空,也可以使用,如:where Date<=>12;其中Date可能爲空,所以要使用<=>。

(5)ER模型和關係模型

ER模型:ER模型即實體聯繫模型,ER模型的基本元素是:實體、聯繫和屬性
實體:是一個數據對象,指應用中可以區別的客觀存在的
事物。(ER模型中的實體往往是指實體集)實體集指同一類實體構成的集合;

關係模型:
關係模型是用二維表的形式表示實體和實體間聯繫的數據模型;關係模型中,字段稱爲屬性,字段值稱爲屬性值,記錄類型稱爲關係模型;有時也稱關係爲表格,元組爲行,屬性爲列。

(6)SQL語句中的NULL應用

SQL語句中,若要使用條件爲空的判斷,需要如下:
where xx is NULL 或 where xx is not NULL;
不可以使用xx=NULL或xx!=NULL的判斷,因爲NULL是類型不確定的,在SQL語句中比較符號左右都是類型確定且相同的;

(7)SQL語句中的模糊查詢

一般模糊查詢語句:SELECT 字段 FROM 表 WHERE 某字段 Like 條件;
關於條件,SQL提供了四種匹配模式:
①%:表示任意0個或多個字符。可匹配任意類型和長度的字符;
例如,SELECT * FROM [user] WHERE u_name LIKE '%三%',將會把u_name爲“張三”,“張貓三”、“三腳貓”,“唐三藏”等等有“三”的記錄全找出來。

②_ : 表示任意單個字符。匹配單個任意字符,它常用來限制表達式的字符長度語句:
比如 SELECT * FROM [user] WHERE u_name LIKE '_三_',只找出“唐三藏”這樣u_name爲三個字且中間一個字是“三”的;

③[ ] :表示括號內所列字符中的一個字符(類似正則表達式)。指定一個字符、字符串或範圍,要求所匹配對象爲它們中的任一個。
比如 SELECT * FROM [user] WHERE u_name LIKE '[張李王]三'
將找出“張三”、“李三”、“王三”(而不是“張李王三”);

④[^ ] :表示不在括號所列之內的單個字符。其取值和 [] 相同,但它要求所匹配對象爲指定字符以外的任一個字符。
比如 SELECT * FROM [user] WHERE u_name LIKE '[^張李王]三'
將找出不姓“張”、“李”、“王”的“趙三”、“孫三”等;

(9)SQL語句中個關鍵詞執行順序

一般都是:from->where->group by->having->select->obder by;

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)線程池
①線程池的原理很簡單,類似於操作系統中的緩衝區的概念,它的流程:先啓動若干數量的線程,並讓這些線程都處於睡眠狀態,當客戶端有一個新請求時,就會喚醒線程池中的某一個睡眠線程,讓它來處理客戶端的這個請求,當處理完這個請求後,線程又處於睡眠狀態。

②爲什麼要預先創建若干線程,而不是在需要的時候再創建?
答:因爲在數據量很大的條件下,某一時刻可能有大量的(上百個)併發請求,而線程創建的過程是比較耗時的,若此時對每個請求都新創建一個線程,那麼會耗費大量的時間,造成擁塞。

(3)連接池:
①常見的數據庫oracle、SQL server都有連接池技術,數據庫連接池是在數據庫啓動時建立足夠的數據庫連接,並將這些連接組成一個連接池(簡單說:在一個“池”裏放了好多半成品的數據庫聯接對象),由應用程序動態地對池中的連接進行申請、使用和釋放。對於多於連接池數據庫連接數的併發請求,則在請求隊列中排隊等待。並且應用程序可以根據池中連接的使用率,動態增加或減少池中的連接數,這個增加減少由數據庫連接池管理線程進行操作。

②爲什麼要創建連接池?
答:因爲需要連接數據庫時再創建連接,然後用完就釋放的方式會造成很多重複的數據庫連接釋放操作,且容易因爲忘記釋放而長期佔用鏈接資源的缺陷。而用數據庫連接池負責分配、管理和釋放數據庫連接,它允許應用程序重複使用一個現有的數據庫連接,而不是再重新建立一個;釋放空閒時間超過最大空閒時間的數據庫連接來避免因爲沒有釋放數據庫連接而引起的數據庫連接遺漏。這項技術能明顯提高對數據庫操作的性能。

(4)內存池:
①內存池是一種內存分配方式。通常我們習慣直接使用new、malloc等API申請分配內存,這樣做的缺點在於:由於所申請內存塊的大小不定,當頻繁使用時會造成大量的內存碎片並進而降低性能。

②一個解決方法是內存池:在啓動的時候,一個內存池(Memory Pool)分配一塊很大的內存,並將會將這個大塊分成較小的塊。每次你從內存池申請內存空間時,它會從先前已經分配的塊中得到,而不是從操作系統。最大的優勢在於:
1)非常少(幾沒有) 堆碎片;
2)比通常的內存申請/釋放(比如通過malloc, new等)的方式快。

22、常見的數據備份方式

答:常見的數據備份方式有:完全備份(Full backup)、增量備份( Incremental backup)、差異備份(Differential backup)。具體如下:



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章