數據庫複習

一、數據庫連接池原理

爲什麼需要使用數據庫連接池。像打開和關閉數據庫連接這種操作是很耗時的,當客戶端數量增加的時候會造成瓶頸。爲了解決此問題,將所有連接形成一個連接池。用戶需要連接時從連接池中獲取一個連接,使用結束後歸還連接。

連接池的工作原理一般由三部分組成,分別是連接池的建立,連接池中連接的管理分配,連接池的關閉。

1.連接池的建立。一般在系統初始化的時候,連接池會根據配置建立,建立幾個連接對象。連接不能隨便創建和銷燬,爲了減少開銷。

2.連接池中連接的管理。當用戶請求數據庫連接時,首先看連接池中有沒有空閒連接。如果有空閒連接直接將其分配給用戶。如果沒有空閒連接,看連接數是否達到最大連接數。如果沒有達到最大連接數,則創建一個連接分配給用戶。如果達到最大連接數,則等待。如果等待時間超過設定的時間,則拋出異常。

3.連接池的關閉。應用程序退出時,連接池關閉所有連接。

二、數據庫分頁查詢

數據庫分頁查詢:Limit

SELECT ... FROM ...WHERE ... ORDER BY ...LIMIT

三、DDL DML DCL

DML(date manipulation language):它們是SELECT,UPDATE,INSERT,DELETE,就像它們的名字一樣,這四條命令是對數據庫進行操作的。

DDL(data definition laguage):數據定義語言,用戶定義和管理SQL數據庫中的所有對象的語言。包括CREATE,ALTER,DROP,TRUNCATE。

DCL(data control languaeg):數據控制語言。包括COMMIT,ROLLBACK,SET TRANCATION。

四、分庫分表

1、分表

MySQL是slave-master模式,只能對slave的讀進行擴展。而寫仍然在master上面。而slave的數量也不是能夠無限擴展的。

對於訪問即爲頻繁且數據量很大的表來說,我們可以做的就是減少單張表的記錄條數,減少數據庫的查詢時間,提高數據庫的吞吐量,這就是我們所說的分表。分表首先要選擇分表策略,可以根據用戶ID來分。

假設有一張用戶表信息太多,需要進行分表,將它分爲256張表。拆分的記錄根據user_id%256找到對應的表進行操作。

假設order表結構如下:

create table order(
order_id bigint(20) primary key auto_increment,
user_id bigint(20) ,
user_nick varchar(50),
auction_id bigint(20)
)

 那麼分表後,假設user_id=257,並且auction_id=100,需要根據auction信息來查詢對應的訂單信息,則對應SQL語句如下:

select * from table_1 where user_id=257 and auction_id=100;

其中,table_1是根據user_id%256=1計算出來的。

2.分庫

分表雖然能夠處理單表數據量過大帶來的查詢效率下降問題,卻無法給數據庫的併發處理能力帶來質的提升。當面對高併發的讀寫訪問,服務器無法承載寫操作壓力時,無論如何擴展slave服務器,此時都沒有意義了。我們必須要換一種思路,對數據庫進行拆分,提高數據庫寫入能力,這就是所謂的分庫。

還是之前的訂單表,假設user_id=258,那麼應該查詢數據庫database_2,數據庫的訪問請求將被路由到第二個庫。

3.分庫分表

有時數據庫既要面臨高併發訪問的壓力,又要面對海量數據的存儲問題,這時需要對數據庫即採取分庫策略,又採取分表策略,以便擴展併發處理能力,以及提升單表的查詢性能。

分庫分表的策略比分庫或分表要複雜,需要用到一箇中間變量。

  • 中間變量=user_id%(分庫數量*每個庫的表數量)
  • 庫=取整數(中間變量/每個庫的表數量)
  • 表=中間變量%每個庫的表數量

同樣採用user_id字段作爲路由字段。

例如:假設將原來的數據庫分爲256個庫,每個庫包含1024個表。那麼按照前面鎖提到的路由策略,對於user_id=262145的訪問,路由的算法過程就是。

  • 中間變量=262145%(256*1024)=1
  • 庫=取整數(1%1024)=0
  • 表=1/1024=1

這就意味着,對於user_id=262145的訂單記錄的查詢和修改,將被路由到第0個庫的第1個order_1中執行。

五、分庫分表的壞處及解決

  • 單機的ACID被打破了,數據到了多機之後,原來在單機通過事務來進行的處理邏輯會受到很大影響。爲了解決此問題,可以引入分佈式事務。
  • 一些Join操作變得比較困難,因爲數據可能已經在兩個數據庫中了,不能很方便的利用數據庫自身的Join了,需要應用其他方法解決。比如分部查找,或者留有一些數據冗餘,對常用的一些數據進行冗餘,這樣就可以把原來需要Join的操作變爲單表操作。
  • 考外鍵去進行約束的場景會受到影響。

六、數據庫鎖

封鎖是併發控制的一個非常重要的技術。基本的封鎖類型有兩種:排它鎖(簡稱X鎖),共享鎖(share locks:簡稱S鎖)。

X鎖(排它寫鎖):若事務T1對對象A加上X鎖,則只允許事務T!對A進行讀寫操作,其他任務事務都不能再對A加任何類型的鎖。

S鎖(共享讀鎖):如事務T對對象A加S鎖,則事務T只能讀A但是不能修改A。其他事務只能對A家S鎖。只有對象A上的S鎖全部釋放,才能加X鎖。

封鎖協議(解決髒讀不可重複讀):

  • 一級封鎖協議(未提交讀):事務T對對象A進行修改之前,必須加X鎖,直至事務結束才釋放。如果僅僅是讀取數據,是不需要加鎖的。只能避免修改丟失而不能避免不可重複讀和髒讀。
  • 二級封鎖協議(提交讀):在一級封鎖協議的基礎上增加事務T在讀取數據R之前必須對其家S鎖,讀完後釋放S鎖。二級封鎖協議除了防止丟失修改,還可以進一步防止讀髒數據。
  • 三級封鎖協議(可重複讀):在一級封鎖協議的基礎上增加事務T在讀取數據R之前對其家S鎖直至事務結束才釋放。三級封鎖協議防止了“不可重複讀”。
  • 解決幻讀問題:GAP鎖。

死鎖和活鎖:

預防死鎖的方法:一次封鎖法,順序封鎖法

一次封鎖法:一次封鎖法要求每個事務必須一次將所有要使用的數據加鎖。

順序封鎖法:預先對數據對象規定一個封鎖順序,所有事務都按照這個順序實施封鎖。

兩端鎖協議:事務分爲兩個階段。第一個階段是獲得封鎖,在這個階段,事務可以申請獲得任何鎖,但是不能釋放鎖。第二個階段是釋放鎖階段,在這個階段,事務可以釋放任何鎖,但是不能獲得鎖。

七、Char、Varchar、text的區別

  • char最大長度是255字符,字符數和字符集沒關係,可以有默認值。
  • varchar最大長度是65535字節。字節數和字符集有關係,可以有默認值。一個漢字字符用utf-8佔用3字節,用gbk佔用2個字節。
  • text和varchar基本相同,text不能有默認值。

八、drop、delete、truncate區別

  • drop直接刪掉表
  • delete刪掉表中數據,不刪除表結構。delete會被防到rollback segement中,事務提交後才生效,可以回滾。
  • truncate刪掉表中數據,不刪除表結構。truncate操作後立即生效,不可用回滾。

九、基本概念

  • 事務:併發控制的基本單位。一個事務要麼都執行,要麼都不執行,不會有中間狀態。
  • 超鍵:在關係中能唯一標識元組的屬性集稱爲關係模式的超鍵。
  • 主鍵:數據庫表中對存儲數據對象予以唯一和完整標識的數據列或屬性的組合。一個數據列只能有一個主鍵。
  • 存儲過程:一組爲了完成特定功能的SQL語句集。經編譯後存儲在數據庫中,用戶通過指定存儲過程的名字並給定參數來調用它。
  • 觸發器:某個條件成立的時候,在觸發器裏面定義的語句就會被執行。因此觸發器不需要人爲的去調用,也不能調用。
  • 遊標:遊標是一段私有的SQL工作區,也就是一段內存區域,用於暫時存放受SQL語句影響到的數據。通俗理解就是將受影響的數據暫時放到了一個內存區域的虛表中,而這個虛表就是遊標。作用是什麼?大家都知道數據庫中的事物可以回滾,而遊標在其中起着非常重要的作用,由於對數據庫的操作我們會暫時放在遊標中,只要不提交,我們就可以根據遊標中內容進行回滾,在一定意義有利於數據庫的安全。

 

 

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