資料庫規範化與優化問題講解

2021-09-30 03:55:08 字數 3211 閱讀 9776

資料庫設計是應用程式設計的基礎,其效能直接影響應用程式的效能。資料庫效能包括儲存空間需求量的大小和查詢響應時間的長短兩個方面。為了優化資料庫效能,需要對資料庫中的表進行規範化。規範化的正規化可分為第一正規化、第二正規化、第三正規化、bcnf正規化、第四正規化和第五正規化。一般來說,邏輯資料庫設計會滿足規範化的前3級標準,但由於滿足第三正規化的表結構容易維護且基本滿足實際應用的要求。因此,實際應用中一般都按照第三正規化的標準進行規範化。但是,規範化也有缺點:由於將乙個表拆分成為多個表,在查詢時需要多表連線,降低了查詢速度。

由於規範化有可能導致查詢速度慢的缺點,考慮到一些應用需要較快的響應速度,在設計表時應同時考慮對某些表進行反規範化。反規範化可以採用以下幾種方法:

1. 分割表

分割表包括水平分割和垂直分割。

水平分割是按照行將乙個表分割為多個表,這可以提高每個表的查詢速度,但查詢、更新時要選擇不同的表,統計時要彙總多個表,因此應用程式會更複雜。

垂直分割是對於乙個列很多的表,若某些列的訪問頻率遠遠高於其它列,就可以將主鍵和這些列作為乙個表,將主鍵和其它列作為另外乙個表。通過減少列的寬度,增加了每個資料頁的行數,一次i/o就可以掃瞄更多的行,從而提高了訪問每乙個表的速度。但是由於造成了多表連線,所以應該在同時查詢或更新不同分割表中的列的情況比較少的情況下使用。

2. 保留冗餘列

當兩個或多個表在查詢中經常需要連線時,可以在其中乙個表上增加若干冗餘的列,以避免表之間的連線過於頻繁。由於對冗餘列的更新操作必須對多個表同步進行,所以一般在冗餘列的資料不經常變動的情況下使用。

3. 增加派生列

派生列是由表中的其它多個列計算所得,增加派生列可以減少統計運算,在資料彙總時可以大大縮短運算時間。

二 應用程式效能的優化

應用程式的優化通常可分為兩個方面:源**和sql語句。由於涉及到對程式邏輯的改變,源**的優化在時間成本和風險上代價很高,而對資料庫系統效能的提公升收效有限,因此應用程式的優化應著重在sql語句的優化。對於海量資料,劣質sql語句和優質sql語句之間的速度差別可以達到上百倍,可見對於乙個系統不是簡單地能實現其功能就行,而是要寫出高質量的sql語句,提高系統的可用性。

下面就某些sql語句的where子句編寫中需要注意的問題作詳細介紹。在這些where子句中,即使某些列存在索引,但是由於編寫了劣質的sql,系統在執行該sql語句時也不能使用該索引,而同樣使用全表掃瞄,這就造成了響應速度的極大降低。

1. is null 與 is not null

不能用null作索引,任何包含null值的列都將不會被包含在索引中。即使索引有多列的情況下,只要這些列中有一列含有null,該列就會從索引中排除。也就是說如果某列存在空值,即使對該列建索引也不會提高效能。

任何在where子句中使用is null或is not null的語句優化器是不允許使用索引的。

2. 聯接列

對於有聯接的列,即使最後的聯接值為乙個靜態值,優化器不會使用索引的。例如,假定有乙個職工表(employee),對於乙個職工的姓和名分成兩列存放(first_name和last_name),現在要查詢乙個叫喬治·布希(george bush)的職工。 下面是乙個採用聯接查詢的sql語句:

select * from employee where first_name||''||last_name ='george bush';

上面這條語句完全可以查詢出是否有george bush這個員工,但是這裡需要注意,系統優化器對基於last_name建立的索引沒有使用。

當採用下面這種sql語句的編寫,oracle系統就可以採用基於last_name建立的索引:

select * from employee where first_name ='george' and last_name ='bush';

遇到下面這種情況又如何處理呢?如果乙個變數(name)中存放著george bush這個員工的姓名,對於這種情況我們又如何避免全程遍歷使用索引呢?可以使用乙個函式,將變數name中的姓和名分開就可以了,但是有一點需要注意,這個函式是不能作用在索引列上。下面是sql查詢指令碼:

select *

from employee where first_name = substr

('&&name',1,instr('&&name',' ')-1)

and last_name = substr('&&name',instr

('&&name』,' ')+1) ;

3. 帶萬用字元(%)的like語句

同樣以上面的例子來看這種情況。目前的需求是這樣的,要求在職工表中查詢名字中包含bush的人。可以採用如下的查詢sql語句:

select * from employee where last_name like '%bush%';

這裡由於萬用字元(%)在搜尋詞首出現,所以oracle系統不使用last_name的索引。在很多情況下可能無法避免這種情況,但是一定要心中有底,萬用字元如此使用會降低查詢速度。然而當萬用字元出現在字串其他位置時,優化器就能利用索引。例如,在下面的查詢中索引得到了使用:

select * from employee where last_name like 'c%';

4. not

我們在查詢時經常在where子句使用一些邏輯表示式,如大於、小於、等於以及不等於等等,也可以使用and(與)、or(或)以及not(非)。not可用來對任何邏輯運算符號取反。下面是乙個not子句的例子:

... where not (status ='valid')

如果要使用not,則應在取反的短語前面加上括號,並在短語前面加上not運算子。not運算子包含在另外乙個邏輯運算子中,這就是不等於(<>)運算子。換句話說,即使不在查詢where子句中顯式地加入not詞,not仍在運算子中,見下例:

... where status <>'invalid';

再看下面這個例子:

select * from employee where salary<>3000;

對這個查詢,可以改寫為不使用not的語句:

select * from employee where salary<3000 or salary>3000;

雖然這兩種查詢的結果一樣,但是第二種查詢方案會比第一種查詢方案更快些。第二種查詢允許oracle對salary列使用索引,而第一種查詢則不能使用索引。

資料庫規範化與優化問題講解

資料庫設計是應用程式設計的基礎,其效能直接影響應用程式的效能。資料庫效能包括儲存空間需求量的大小和查詢響應時間的長短兩個方面。為了優化資料庫效能,需要對資料庫中的表進行規範化。規範化的正規化可分為第一正規化 第二正規化 第三正規化 bcnf正規化 第四正規化和第五正規化。一般來說,邏輯資料庫設計會滿...

資料庫規範化

規範化 normalization 是資料庫系統設計中非常重要的乙個技術。資料庫規範化能夠讓資料庫設計者更好地了解組織內部當前的資料結構,最終得到一系列的資料實體。資料庫規範化通過對資料庫表的設計,可以有效降低資料庫冗餘程度。在進行資料庫規範化的時候,我們有一系列的步驟需要遵循。我們把這些步驟稱作正...

資料庫規範化大全

er圖是一種關聯式資料庫邏輯設計的一種方法。normalization 正規化 是另一種 關係型資料庫的邏輯設計的方法。normal forms 正規化 1nf 2nf 3nf bcnf 4nf 5nf 1.不好的資料庫會出現的問題 a.修改異常 anomaly b.刪除異常 c.插入異常 d.資料...