20120711DB2數據庫邏輯設計(一)

鑑於CSDN無故刪除博文,本博客不再更新,暫時遷至http://www.db365.net


商業智能羣199567325,2012年7月11號《db2數據庫邏輯設計(一)》,講解者:趙堅密Jimmy。

講課方式,YY頻道號:85536471


YY頻道每週三講解,具體請加QQ羣199567325下載講課錄音。


DB2邏輯設計

趙堅密[email protected]

1表

1.1規範化和反規範化

a不能拆分1NF

  表1 不符合1NF

員工

部門

部門經理

 

人力資源

張三

 

財務

李四

 

財務

李四

 

 

 

 

 

 

  表2 符合1NF

員工

部門

部門經理

 

張三

人力資源

張三

 

張三

財務

李四

 

李四

財務

李四

 

 

 

 

 

b不能重複2NF(1—>2:消除非主屬性對碼的部分依賴)

  表3 符合2NF

員工編號

員工姓名

部門

部門經理

 

1

張三

人力資源

張三

 

2

張三

財務

李四

 

3

李四

財務

李四

 

 

 

 

 

 

c不能冗餘3NF(2—>3:消除非主屬性對碼的傳遞依賴)

  表4 符合3NF

員工編號

員工姓名

部門

 

 

1

張三

人力資源

 

 

2

張三

財務

 

 

3

李四

財務

 

 

 

 

 

 

 

  表5

部門編號

部門

部門經理

 

 

1

人力資源

張三

 

 

2

財務

李四

 

 

 

 

 

 

 

 

 

 

 

 

 

d通俗的介紹:

第一範式:屬性不可再分

就是字段A,不能再分成A.filed1,A.filed2

第二範式實在第一範式得基礎上

第二範式其實就是要求有主鍵

通過主鍵可以唯一確定一行記錄

也就是員工表,必須有個員工ID

部門表必須有部門ID

第三範式實在第二範式得基礎上

消除了字段對非主屬性得傳遞依賴

員工表

員工ID,員工姓名,部門ID,部門名稱

這個是不允許得

不能有部門名稱

部門會有另一張表

e反規範化

反規範化,即數據冗餘。首先需要付出空間代價,其次是管理代價,維護數據的完整性。它的好處是:減少查詢所要連接表的個數,減少了I/O和CPU時間,加速了查詢。。因此做反規範化時,一定要權衡利弊,仔細分析數據的存取需求和實際的性能特點。

1.2創建表時的可選參數

a COMPRESSION 壓縮70%

b APPEND ON 直接插入表尾

c PCTFREE 表中空閒百分比

d PARTITION BY RANGE 快速加載和分離數據

e VOLATILE 訪問時使用索引

2索引

2.1執行計劃

DB2基於成本的優化,優化器計算SQL語句的多種訪問路徑下的執行成本(CPU內存硬盤等),最終選擇最優路徑作爲SQL語句的執行計劃。

動態SQL每執行一次都需要重新編譯和優化,靜態SQL不需要。所以靜態SQL免去了編譯和優化得過程,節約了時間,但是隨着時間的改變,數據庫的數據以及服務器的資源負載改變之後原先的執行計劃可能不是最優。

2.2訪問數據的方法

a表掃描

按順序掃描整個表。

b索引掃描

通過首先訪問表上的索引來定位到某一行,然後再訪問該行。

c完全索引訪問

所有需要的數據都在索引中,那麼就沒必要訪問索引所在的基表

2.3影響索引作用的因素

a區分度(檢索比例)

優化器根據統計信息來生成執行計劃,如果數據庫沒有收集索引的統計信息,優化器就無從下手,只能按部就班,通過全表掃描來執行查詢。所以,新創建的索引需要重新運行統計,否則索引無效。

舉一個例子,有個表TABLE1,其中有一個字段COL1取值是“1”、“2”、“3”三種,運行統計的結果是告訴數據庫TABLE1中的數據其中字段COL1的各種取值所佔的比重。示意如下:

“1”- 12%;

“2”- 66%;

“3”- 22%。

假設還有個字段COL2取值和數據所佔的百分比如下:

“A”- 50%;

“B”- 50%。

則查詢語句1:

select * from TABLE1 where COL1 = “1” and COL2 = “A”,

數據庫優化器會優先選擇字段COL1上的索引來定位表中的數據,因爲通過COL1上的索引就可以將結果集迅速定位在一個小範圍內12%。而相反的,對於查詢語句2:

select * from TABLE1 where COL1 = “2” and COL2 = “A”,

數據庫會優先選擇COL2上的索引,因爲對於語句2的查詢條件COL2上的索引具有更好的區分度。

從上面可以看出,數據庫的優化器通常會優先選擇區分度較高的索引(針對於查詢條件,條件不同選擇的索引可能不同)。

數據庫裏的數據是變化的,所以某個時候採集的統計信息,過一段時間後可能會過時,甚至誤導數據庫優化器,這樣同樣會造成運行性能的低下。所以除了,最初建立索引時需要運行統計,在表中的數據發生變化時也需要運行統計。經驗:當表中數據量變化達到10%時,需要重新運行統計。

b聚集度

補充知識:按塊訪問表數據。

c函數與索引

函數,like語句。。。

Substring(col_name,1, 3) vs. Substring(col_name, 3, 3)

like ‘QQQ% vs.like ‘%QQQ’

 

2.4謂詞

a範圍定界

 

b索引控制

 

c數據控制

 

d保留謂詞

 

2.5索引與操作

 

 

2.6索引或操作

 

 

2.7索引參數

索引或者表空間的CREATE/ALTER語句可以指定FREEPAGE和PCTFREE參數。可通過ALTER語句修改參數。

例子,FREEPAGE爲5:5頁之後空1頁;

PCTFREE取值0~99,如爲40:某一頁有超過40%的可用空間,則利用。

2.8索引優化嚮導

db2advis

2.9索引開銷

性能利器

雙刃劍

索引對插入操作的影響(Oracle

索引對插入操作的影響(MySQL)

比較索引與促發器對性能的影響

 

2.10索引總結

使用索引實現關鍵數據的高效訪問。但是需要知道每個索引都會給數據庫更新帶來額外的開銷。這就意味着,低效的索引會給數據庫帶來災難。

對於數據庫,我們必須關注關鍵數據的讀取,爲他們提供最高效的訪問路徑。對此,基本策略就是建立索引。在索引提供高效訪問的同時,也帶來了額外的系統開銷。開銷分爲磁盤空間的開銷和處理器開銷。下面我們討論一下處理器開銷。每當在表中插入或刪除記錄時,該表的所有索引必須進行相應調整。每當對已建立索引的字段進行更新時,這種調整也會發生。舉例子說,如果在未建立索引的表中插入數據需要100個單位時間,那麼每增加一個索引就會增加100到250個單位時間。有趣的是,維護索引的開銷與簡單觸發器帶來的開銷大致相當。

在建立索引前線介紹一些最通俗的信息,這些信息來自developWorks,列出這些信息是因爲我覺得這些信息通常情況下是值得參考的:

1.         當要在一個合理的時間內結束查詢時,應避免添加索引,因爲索引會降慢更新操作的速度並消耗額外的空間。有時候還可能存在覆蓋好幾個查詢的大型索引。

2.         基數較大的列很適合用來做索引。

3.         考慮到管理上的開銷,應避免在索引中使用多於5個的列。

4.         對於多列索引,將查詢中引用最多的列放在定義的前面。

5.         避免添加與已有的索引相似的索引。因爲這樣會給優化器帶來更多的工作,並且會降慢更新操作的速度。相反,我們應該修改已有的索引,使其包含附加的列。例如,假設在一個表的 (c1,c2)上有一個索引i1。您注意到查詢中使用了"wherec2=?",於是又創建一個(c2)上的索引i2。但是這個相似的索引沒有添加任何東西,它只是i1的冗餘,而現在反而成了額外的開銷。

6.         如果表是隻讀的,並且包含很多的行,那麼可以嘗試定義一個索引,通過CREATE INDEX中的INCLUDE子句使該索引包含查詢中引用的所有列(被INCLUDE子句包含的列並不是索引的一部分,而只是作爲索引頁的一部分來存儲,以避免附加的數據FETCHES)。

對於數據倉庫(查詢系統數據庫)可以建立較多的索引(索引和數據的比例可以是1:1)。

決定是否使用索引,可以重點考慮檢索比率。即,判斷索引有效性的依據,就使用鍵值作唯一性條件檢索出的數據的百分比。百分比越低,索引越有效。做出這個論斷的前提是一些假設,如磁盤訪問的相關性能。

索引鍵值相關記錄的物理位置是否相鄰也很重要,因爲是通過塊來操作數據的。建立了索引之後,如果索引鍵所指向的記錄散佈於整個表中,即使這些記錄在表中佔的比率很小,但因爲它們分散在整個磁盤上,所以索引的性能就會大打折扣。

另外值得注意的是,函數和類型轉換可能導致索引失效。

3表分區

2.1分區表的優勢

當單表數據量達到一定級別,隨着數據量的增長,響應時間高於線性增長,呈現指數級增長趨勢。

P570,16C,32G的機器,測試,當數據量達到千萬及以上,即使對索引列進行聚集操作也是呈現非線性增長。

分區表根據表分區鍵將表數據分佈到多個表分區中。比起普通表,分區表憑藉其先天優勢,在表功能、SQL處理性能等多方面遙遙領先。它允許一個邏輯表被分成多個分散的邏輯存儲對象,每個村處對象對應表的一部分,用值的範圍來指定每個分區。

總結:首先,增加了表的功能。數據可以分區、分表空間存放,這也可以方便的進行數據的轉入轉出。其次,這樣做提高了SQL處理的性能,由於各個月的數據分區存放,如果用戶需要訪問某一特定月的數據,可以直接對相應的分區訪問即可,這樣避免了對其他數據的訪問。同時,數據存放在不同表空間,在進行數據訪問時,可以並行I/O,以提高訪問效率。同時,使用分區表還有一個很大的好處,就是鎖方面的好處。當應用程序訪問某一月數據時,只需對相應的分區加鎖,從而避免了像普通表一樣對整個表加鎖,這就大大提高了數據庫併發性。

轉入轉出功能對大數據量的表非常有用,數據可以靈活插拔,不用時轉出,用時轉入。如果把不用的數據轉出,可以減少數據量,顯著提高性能。並且用轉入轉出刪除和插入數據非常快。

2.2分區表設計

可以根據轉入轉出的特點來設計分區,根據月份分區。控制每個分區的數據量在合理的範圍,讓數據儘可能平均分佈到各個分區。表分區的範圍跟轉出數據範圍一致,可以使轉入轉出操作簡化。

儘量避免全局索引。

可以使用db2advisor來生創建成分區表語句。

2.3分區表索引

a全局索引(9)

b分區索引(9.7之後)

2.4分區是把雙刃劍

數據驅動分區能將一個表中的數據分散到多個獨立的分區中,但這並不意味着併發問題就完全解決了。例如,一個表按日期進行分區,每星期的數據一個分區。若把一年的數據寫入五十二個邏輯上不同的分區,這種分區方式的確很有效。但問題是,每個星期所有人都會擁入同一個分區插入新數據——更糟的是,如果分區鍵是當前系統日期,所有這些併發操作,都會針對同一個數據塊(除非利用一些結構上得實現技巧,例如維持幾個可供插入的頁或數據塊列表),結果將導致非常棘手得內存爭用。這個大型表中的大部分都無人訪問,但存儲最新數據分區的訪問卻過於集中,當許多進程同時插入數據時,這樣的分區方式顯然不夠理想。

注意:如果所有數據都通過單一進程進行插入(數據倉庫環境中會出現這種情況),“訪問過於集中”問題就不存在了,而五十二個星期的分區方案也不會導致併發性問題。

另一方面,假設根據訂單的地理位置進行分區(如果產品在某地熱銷而在另一些地方銷路不暢,則應謹慎採用此分區方式)。指定某個時間,由於銷售不太可能全部來自同一區域,所以插入的數據大體會隨機分不到各分區。但要基於時間生成報表時,這種分區對性能影響較爲明顯,因爲分區是按地理位置劃分的,效率肯定比按時間劃分的分區要低。然而,基於地理位置的分區也有可能對基於時間的查詢有利,因爲在多處理器的機器上,對各分區的搜尋可以並行執行,隨後將結果合併。

因此,分區是把雙刃劍。一方面,它通過分區鍵將數據聚集在一起,利於高速檢索。另一方面,對併發執行的插入操作,分散數據可避免出現“訪問過於集中”的問題。但在實踐中,這兩個目標可能彼此矛盾,所以首要問題是搞清楚要解決的主要問題是什麼,並針對主要問題設計分區。而且,兩方面的得失都要檢查,看結果能否接受。理想的情況是爲select而設計的數據聚集方式,與爲insert而設計的散步方式是一致的,只可惜這並不常見。

2.5分區與數據分佈

或許你認爲,只要表非常大,且希望避免數據的併發寫入操作發生資源爭用,就一定要採用某種方法對數據進行分區。但時事並非如此。

假設有個很大的客戶訂單表,如果該表中大部分數據都來自於同一個客戶(該情況時有發生),那麼按客戶ID對數據進行分區,就不會有太大幫助。我們可以非常粗略的把查詢分爲兩大類:與大客戶相關的查詢及與較小客戶相關的查詢。當查詢小客戶的數據時,在客戶ID上的索引選擇性(區分度)會很高,因而查詢效率也很高,這時完全不需要分區。聰明的優化器在獲得關於鍵值分佈的適當統計數據後,即可偵測到分不得不均勻並轉而使用索引。這種把小客戶存儲在較小的分區,緊靠在含有主要客戶的大分區旁的做法,好處並不大。

相反,當查詢大客戶的相關數據時,優化器也知道掃描表時效率最高的處理方式。在此情況下,由於該大客戶的數據佔全表很大比例——假設爲80%,僅掃描該客戶數據所在分區並不比全表掃描快很多,所以性能提升不大,但購買DBMS的分區功能(該功能單獨定價)卻需要額外開銷。

總結:對分區表進行查詢,當數據按分區鍵分佈均勻時,收益最大。

2.6數據分區的最佳方法

絕對不要忘記,整體改善業務處理的操作,纔是選擇非標準的存儲選項(例如分區)的目標。這意味着,改善不合理的業務流程是重中之重。例如,犧牲晚上的時間進行批處理工作,優化白天的事物型處理,是合理的;也可以優化批處理工作,如果將關鍵的上載時間減至最短(期間數據對用戶仍不可用),我們可以接受交易處理速度稍慢一些。這是平衡問題。

一般而言,當有多個處理在類似條件下執行時,不應過度偏袒其中一個。就這點上,只要是根據數據值決定物理位置的存儲方式(例如聚集型索引和分區),更新數據時代價都非常高。對普通表的更新,幾乎是在物理地址不變的情況下做更改,最多隻修改和移動表中的一些字節而已;但如果採用了上述那些存儲方式,更新必將導致一系列刪除、插入操作和相關索引維護工作。

更新分區鍵會引起移動數據,似乎應避免這麼做,但奇怪的是,更具可更新的鍵值進行分區,有時效果更好。例如,有個表,用作服務隊列,某進程會在該表中插入不同類型(例如T1到Tn)的服務請求。新出現的服務請求,初始化狀態被設爲W——表示“等待處理”。服務器進場S1到Sp會定期檢查表中是否有W狀態得請求,若有則將其狀態更改爲P——表示“處理中”,接着,在完成每個請求後其狀態被置爲D——表示“已完成”。

。。。。。。

總結:對錶進行分區的方法有多種,顯而易見的分區方法未必是最有效的,一定要從整體考慮。

 

4 MDC

5 MQT

6 DPF

 


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