1. 程式人生 > >Oracle學習總結(2)——Oracle資料庫設計總結(三大正規化)

Oracle學習總結(2)——Oracle資料庫設計總結(三大正規化)

一、實體與表對應關係

表<=>實體,欄位<=>屬性。

二、表與表的關係(實體間的關係):一對一、一對多、多對多

一對一:一條記錄只對應其他表中的一條記錄有關係

學生基本資訊表t_student,成績表t_studentScore含有一個外來鍵studentId。基本資訊表中的studentId和成績表中的studentId就是一對一的關係。

一對多:A表一條記錄對應B表中多條記錄有關係,B表的記錄不被A表記錄共享(有關係)。

班級表和學生表,一個班級有多個學生,對班級來說就是一對多的關係。

多對多:A表一條記錄和B表多條記錄有關係,B表的一條記錄也和A表的多條記錄有關係(互相共享)。

學生表和科目表,學生可以選擇多個科目,每個科目可以被多個學生選擇。

三、基本表的完整性

(1)原子性。欄位是不可再分解的。

(2)原始性。記錄是原始資料(基礎資料)的記錄。

(3)穩定性。結構是相對穩定的,表中的記錄是要長期儲存的。

(4)演繹性。由基本表與程式碼表中的資料,可以派生出所有的輸出資料。

四、其他常用表

1.中間表

中間表是針對多對多關係的。就比如做公交查詢系統,裡面有兩個表,分別是車站表t_busstation、線路表t_road,根據常識,一個站有多個線路經過,而每個線路又有多個車站,怎麼才能將兩個表聯絡起來呢,如果是一對一,一對多,我們一個表, 兩個表就可以將他們實現了。但是多對多呢,這樣我們就必須藉助中間表用來連線兩個表。一般中間表只有一個自增主鍵+兩個表的主鍵。中間表是沒有屬性的因為它不是一個基本表。

2.臨時表

臨時表是那些以#號開頭為名字的資料表,它主要是用來存放臨時資料的,當用戶斷開連線但沒有清除臨時表裡的資料時,系統會自動把臨時表裡的資料清空。臨時表是放在系統資料庫 tempdb中的,而不是當前資料庫。

臨時表分兩種:本地臨時表和全域性臨時表。

a.本地臨時表

本地臨時表是以#開頭的,只對當前的資料庫使用者可見,而其他的使用者是不可見的。當資料庫例項斷開後當然也就丟失了資料了,不管是顯式清空還是系統回收。

b.全域性臨時表

以“##”開頭的,而且是對所有的使用者都是可見,當你斷開資料庫例項連線時,只要還有別的系統專案在引用它,連著資料庫,那麼資料就存在,只有當別的系統也全部斷開連線時,系統才會清除全域性臨時表的資料。

建立臨時表的語句:

本地臨時表:

create table #student(
studentID int ,
studentName nvarchar (40),
classID int
)

全域性臨時表:

create table ##student
(
studentID int ,
studentName nvarchar (40).
classID int
)

也可以用SQL語句完成:

select * from employee into #student

五、三大正規化

第一正規化:如果每列(或者每個屬性)都是不可再分的最小資料單元(也稱為最小的原子單元),則滿足第一正規化.比如一個工人的基本資訊表,裡面有工人的工號,性別,年齡,這些屬性都是不可分割的,所以這個表就符合了第一正規化。

第二正規化: 就是在第一正規化的基礎上延伸,使之表裡的每個欄位都與主鍵發生關係。假如一個關係滿足第一正規化,並且除了主鍵以外的其它欄位,都依賴於該主鍵,則滿足第二正規化.例如:訂單表(訂單編號、產品編號、定購日期、價格、……),"訂單編號"為主鍵,"產品編號"和主鍵列沒有直接的關係,即"產品編號"列不依賴於主鍵列,這個列我們就可以把它刪除。

第三正規化:在第二正規化的基礎上更進一步,也就是為了實現表裡的列都與主鍵列直接相關,不是間接相關。這個我們可以用“Armstrong 公理”中的傳遞規則來推理。

定義:設U是關係模式R 的屬性集,F 是R 上成立的只涉及U 中屬性的函式依賴集。若X→Y 和 Y→Z在R 上成立,則X →Z 在R 上成立。因此我們就來看在網上搜索到的例子:例如:訂單表(訂單編號,定購日期,顧客編號,顧客姓名,……),初看該表沒有問題,滿足第二正規化,每列都和主鍵列"訂單編號"相關,再細看你會發現"顧客姓名"和"顧客編號"相關,"顧客編號"和"訂單編號"又相關,最後經過傳遞依賴,"顧客姓名"也和"訂單編號"相關。為了滿足第三正規化,應去掉"顧客姓名"列,放入客戶表中。這裡其實就是為了說明資料庫的表裡步要出現冗餘,在顧客表裡已經有了"顧客姓名"了,而在訂單表裡就別出現了,而直接根據顧客編號相關聯就可以,否則造成資源浪費。

三大正規化延伸:

第一正規化:1NF是對屬性的原子性約束,要求屬性具有原子性,不可再分解;

第二正規化:2NF是對記錄的惟一性約束,要求記錄有惟一標識,即實體的惟一性;

第三正規化:3NF是對欄位冗餘性的約束,即任何欄位不能由其他欄位派生出來,它要求欄位沒有冗餘。

其實在設計資料庫的時候我們最多的要遵循的就是第三正規化,但是並不是越滿足第三正規化資料庫就設計的越完美,這種錯誤是錯誤的。有時候增加點冗餘相反的會提高訪問速率,因此在實際的設計過程中應降低對正規化的要求。以前對資料冗餘並不是很瞭解,在百度知道里的定義是這樣的:在一個數據集合中重複的資料稱為資料冗餘. 但是不是說我們表的主鍵在其他表裡重複出現就是冗餘,這不是,而是為了連線兩個表。只有非鍵欄位就是既不是主鍵外來鍵等約束的鍵如果重複出現,就會形成資料冗餘。資料冗餘也包括重複性冗餘和派生冗餘。比如工人表裡有"基本工資","獎金"兩列,然後還有一個"總工資"的列,這個總工資就是派生冗餘。低階的重複性冗餘一定要避免,杜絕,但是像派生冗餘還是提倡的因為它能提高訪問的效率。

六、資料庫設計中具體要注意的幾點;

1.凡是使用者輸入的不能作為主鍵

這點大概都知道,主鍵是唯一的,一般不能讓客戶做任何操作;

2.凡是有業務意義的不能作為主鍵

既然是具有業務意義,客戶隨時都有可能提出這個業務,要求修改業務,也會有變動的可能!

3.除非確定是有必要的欄位,其他都允許為空

設計資料庫時,約束簡單點最好,約束多則在系統中開發時要注意的就多,開發效率相對會底,因為系統是可以通過驗證輔助完成這些約束的!

4.不能缺少時間或日期欄位

有時間是永遠前進,時間的用處很多,打個很簡單的比方,在使用者表中我們有一個使用者建立的時間,在吧專案交個客戶後使用一段時間,客戶提出新的需求,

比如說:要搞一個週年慶活動,每個滿5個月的使用者都獎勵200代金卷,等等。在這時我們如國有時間欄位,那就很容易加上這個業務,但要是沒有呢?將會如何?修改資料庫?公司的利益會受到嚴重的打擊;

5. 業務的時效(時間有效)性;

6.資料的採集寧濫毋缺

這點非常重要,這就是資料庫設計者的後瞻能力了,也就是說我們能在使用者還沒有提出一些新的需求是,已經把資料都採集好了,就等客戶提出需求很輕鬆的搞定一些業務;有了資料什麼都不怕;但有些人也會問,我們前期就把沒有用到的資料存進去,後期可以利用也就罷了,如果沒有利用到呢?是不是很浪費空間;其實這個問題,我可以這樣回答,絕大多數公司在很多方面都是以空間換取時間的;(相信大家都明白!比如在web中使用的AJAX技術)

7.外來鍵欄位需要維護或變更,就需要表來維護,如果欄位簡單,不需要經常變更的,可以直接是程式維護;

總結

資料庫設計就是根據業務系統的具體需要,結合我們所選用的DBMS(資料庫管理系統),為這個業務系統構造出最優的資料儲存模型,並建立好資料庫中的表結構及表與表之間的關聯關係的過程。使之能有效的對應用系統中的資料進行儲存,並可以高效的對已經儲存的資料進行訪問。