數(shù)據(jù)庫設計基礎

此頁沒有內(nèi)容條目
內(nèi)容

Access > Access 基礎知識

 

數(shù)據(jù)庫設計基礎

設計合理的數(shù)據(jù)庫可以讓您訪問最新的、準確的信息。由于正確的設計對于實現(xiàn)使用數(shù)據(jù)庫的目標非常重要,因此有必要投入時間學習良好設計的相關原則。這樣,最終就更有可能獲得一個既能滿足您的需要又能輕松適應變化的數(shù)據(jù)庫。

本文提供了規(guī)劃桌面數(shù)據(jù)庫的一些原則。您將了解到如何確定需要哪些信息,如何將這些信息劃分到相應的表和列,以及這些表如何彼此關聯(lián)。在創(chuàng)建第一個桌面數(shù)據(jù)庫之前,首先應閱讀本文。

要點  Microsoft Access 2010 提供了新的設計體驗,可讓您為網(wǎng)站創(chuàng)建數(shù)據(jù)庫應用程序。在為網(wǎng)站設計數(shù)據(jù)庫時,有很多不同的設計注意事項。本文不討論 Web 數(shù)據(jù)庫應用程序設計。有關詳細信息,請參閱生成可在 WEB 上共享的數(shù)據(jù)庫一文。

本文內(nèi)容


hrefIcon_ZA10069439 需要了解的一些數(shù)據(jù)庫術語

hrefIcon_ZA10069439 什么是好的數(shù)據(jù)庫設計?

hrefIcon_ZA10069439 設計過程

hrefIcon_ZA10069439 確定數(shù)據(jù)庫的用途

hrefIcon_ZA10069439 查找和組織所需的信息

hrefIcon_ZA10069439 將信息劃分到表中

hrefIcon_ZA10069439 將信息項轉(zhuǎn)換為列

hrefIcon_ZA10069439 指定主鍵

hrefIcon_ZA10069439 創(chuàng)建表關系

hrefIcon_ZA10069439 優(yōu)化設計

hrefIcon_ZA10069439 應用規(guī)范化規(guī)則


 

需要了解的一些數(shù)據(jù)庫術語

Access 2010 可將信息組織到中, 表是由行和列組成的列表,與會計人員的便箋簿或電子表格類似。在簡單的數(shù)據(jù)庫中,可能僅包含一個表。對于大多數(shù)數(shù)據(jù)庫,可能需要多個表。例如,可以在一個表中存儲有關產(chǎn)品的信息,在另一個表中存儲有關訂單的信息,再在另一個表中存儲有關客戶的信息。

TP_CPUC]{A1G~JXAAZ0979V

按照更為準確的說法,每一行稱為“記錄”,而每一列稱為“字段”。記錄是一種用來組合某事項的相關信息的有效且一致的方法。字段是單個信息項,即出現(xiàn)在每條記錄中的項類型。  例如,在“產(chǎn)品”表中,每一行或記錄中都會包含與某個產(chǎn)品相關的信息。每一列或字段則包含有關該產(chǎn)品的某種類型的信息,如名稱或價格。

TopPageIcon_CLV 返回頁首

什么是好的數(shù)據(jù)庫設計?

一些原則可為數(shù)據(jù)庫設計過程提供指導。第一個原則是,重復信息(也稱為冗余數(shù)據(jù))很糟糕,因為重復信息會浪費空間,并會增加出錯和不一致的可能性。第二個原則是,信息的正確性和完整性非常重要。如果數(shù)據(jù)庫中包含不正確的信息,任何從數(shù)據(jù)庫中提取信息的報表也將包含不正確的信息。因此,基于這些報表所做的任何決策都將提供錯誤信息。

所以,良好的數(shù)據(jù)庫設計應該是這樣的:

將信息劃分到基于主題的表中,以減少冗余數(shù)據(jù)。
向 Access 提供根據(jù)需要聯(lián)接表中信息時所需的信息。
可幫助支持和確保信息的準確性和完整性。
可滿足數(shù)據(jù)處理和報表需求。

TopPageIcon_CLV 返回頁首

設計過程

設計過程包括以下步驟:

確定數(shù)據(jù)庫的用途

這可幫助進行其他步驟的準備工作。

查找和組織所需的信息

收集可能希望在數(shù)據(jù)庫中記錄的各種信息,如產(chǎn)品名稱和訂單號。

將信息劃分到表中

將信息項劃分到主要的實體或主題中,如“產(chǎn)品”或“訂單”。每個主題即構成一個表。

將信息項轉(zhuǎn)換為列

確定希望在每個表中存儲哪些信息。每個項將成為一個字段,并作為列顯示在表中。例如,“雇員”表中可能包含“姓氏”和“聘用日期”等字段。

指定主鍵

選擇每個表的主鍵。主鍵是一個用于唯一標識每個行的列。例如,主鍵可以為“產(chǎn)品 ID”或“訂單 ID”。

建立表關系

查看每個表,并確定各個表中的數(shù)據(jù)如何彼此關聯(lián)。根據(jù)需要,將字段添加到表中或創(chuàng)建新表,以便清楚地表達這些關系。

優(yōu)化設計

分析設計中是否存在錯誤。創(chuàng)建表并添加幾條示例數(shù)據(jù)記錄。確定是否可以從表中獲得期望的結果。根據(jù)需要對設計進行調(diào)整。

應用規(guī)范化規(guī)則

應用數(shù)據(jù)規(guī)范化規(guī)則,以確定表的結構是否正確。根據(jù)需要對表進行調(diào)整。

TopPageIcon_CLV 返回頁首

確定數(shù)據(jù)庫的用途

最好將數(shù)據(jù)庫的用途記錄在紙上,包括數(shù)據(jù)庫的用途、預期使用方式及使用者。  例如,對于供家庭辦公用戶使用的小型數(shù)據(jù)庫,可以記錄與“客戶數(shù)據(jù)庫保存客戶信息列表,用于生成郵件和報表”類似的簡單內(nèi)容。如果數(shù)據(jù)庫比較復雜或者由很多人使用(在企業(yè)環(huán)境中通常是這樣),數(shù)據(jù)庫的用途可以簡單地分為一段或多段描述性內(nèi)容,且應包含每個人將在何時及以何種方式使用數(shù)據(jù)庫。這種做法的目的是為了獲得一個良好的任務說明,作為整個設計過程的參考。任務說明可以幫助您在進行決策時將重點集中在目標上。

TopPageIcon_CLV 返回頁首

查找和組織所需的信息

要查找和組織所需信息,請從現(xiàn)有信息著手。例如,您可能會將采購訂單記錄在分類帳中,或?qū)⒖蛻粜畔⒈4嬖谖募裰械哪硞€紙質(zhì)表單中。收集這些文檔,并列出所顯示的每種信息(例如在表單中填寫的每個框)。如果沒有任何現(xiàn)有表單,則請設想您必須設計一個表單來記錄客戶信息。將要在表單中存放哪些信息?將要創(chuàng)建哪些填充框?確定并列出其中的每一項。例如,假定當前在索引卡上記錄客戶列表。這些卡片上可能記錄了客戶姓名、地址、城市、省/市/自治區(qū)、郵政編碼和電話號碼。其中的每一項都可能表示表中的一個列。

在準備此列表時,不要為讓它在最開始就能達到完美的效果而擔憂。相反,請列出每個想到的項。如果還有其他人使用該數(shù)據(jù)庫,也應向他們征求意見??稍谝院髮υ摿斜磉M行優(yōu)化。

接下來,考慮可能希望從數(shù)據(jù)庫生成的報表或郵件的類型。例如,可能會希望生成按照區(qū)域顯示銷售量的產(chǎn)品銷售報表,或生成顯示庫存水平的庫存匯總報表。還可能希望生成發(fā)送給客戶、用來通告銷售活動或提供優(yōu)惠的套用信函。在心中設計此類報表,并想象其外觀。將在報表中放置哪些信息?列出每一項。對希望創(chuàng)建的套用信函和任何其他報表進行相同的工作。

正在設想產(chǎn)品庫存報表的人員

考慮可能希望創(chuàng)建的報表和郵件,可以幫助確定數(shù)據(jù)庫中將需要的各個項。例如,假定向客戶提供選擇訂閱(或取消訂閱)周期性電子郵件更新的機會,且希望打印已經(jīng)選擇訂閱的客戶的列表。為了記錄該信息,向客戶表中添加了一個“發(fā)送電子郵件”列。對于每個客戶,可以將此字段設置為“是”或“否”。

向客戶發(fā)送電子郵件的要求還意味著要記錄另一個項。知道客戶希望接收電子郵件后,還需要知道這些電子郵件的接收地址。因此,需要記錄每個客戶的電子郵件地址。

有一種很好的做法:為每個報表或輸出列表構造一個原型,并考慮需要哪些項才能生成該報表。例如,檢查套用信函時,可能會想到一些事項。如果希望包括恰當?shù)姆Q呼語(如作為問候語開頭的“先生”、“太太”或 “女士”等字符串), 則需要創(chuàng)建一個稱呼語項。另外,通??赡懿捎谩白鹁吹耐跸壬倍皇恰白鹁吹耐跛济飨壬?作為信件的開頭。這表示一般要將姓和名分開存儲。

需要記住的要點是,應該將每條信息分為最小的有用單元。對于姓名,為了讓姓氏易于使用,需要將姓名分為兩部分:名字和姓氏。例如,為了按照姓氏對報表進行排序,將客戶的姓氏分開存儲將很有幫助。一般情況下,如果希望根據(jù)信息項進行排序、搜索、計算或生成報表,應當將該項放置在單獨的字段中。

考慮希望數(shù)據(jù)庫進行回答的問題。例如,上個月您的特色產(chǎn)品的銷售量是多少?您的主要客戶在什么地方?您的暢銷產(chǎn)品的供應商是誰?對這些問題進行估計,可以幫助您將精力集中于需要記錄的其他項。

收集這些信息后,就可以進行下面的步驟。

TopPageIcon_CLV 返回頁首

將信息劃分到表中

要將信息劃分到表中,請選擇主要實體或主題。例如,在查找和組織用于產(chǎn)品銷售數(shù)據(jù)庫的信息后,初步列表可能與下圖類似:

劃分為若干主題的手寫信息項

此處所示的主要實體為產(chǎn)品、供應商、客戶和訂單。因此,可以從以下四個表開始:一個用來存儲有關產(chǎn)品的真實信息、一個用來存儲有關供應商的真實信息、一個用來存儲有關客戶的真實信息、一個用來存儲有關訂單的真實信息。盡管這樣并沒有完成列表,但卻是一個不錯的起點??梢岳^續(xù)對此列表進行優(yōu)化,直到獲得適用的設計為止。

首次檢查項的初步列表時,可能非常想將所有項全部放入一個表中,而不是放入上圖中顯示的四個表中。您將在此處了解到為什么這樣做不好??紤]一下此處所示的表:

顯示同時包含產(chǎn)品和供應商的表的圖像

在這種情況下,每行中同時包含有關產(chǎn)品及其供應商的信息。由于可能擁有來自同一供應商的許多產(chǎn)品,因此供應商的名稱和地址信息不得不多次重復。這就浪費了磁盤空間。在單獨的“供應商”表中僅記錄一次供應商信息,然后將該表鏈接到“產(chǎn)品”表,是更好的解決方案。

此設計的另一個問題出現(xiàn)在需要修改有關供應商的信息時。例如,假定需要更改供應商的地址。由于此信息出現(xiàn)在多個位置,您可能會意外地更改了一個位置的地址而忘記更改其他位置的地址信息。將供應商的地址記錄在唯一一個位置就可以解決該問題。

設計數(shù)據(jù)庫時,應始終盡可能僅記錄每個事實一次。如果發(fā)現(xiàn)自己在多個位置重復相同的信息(如特定供應商的地址),則請將該信息放入單獨的表中。

最后,假定只有 Coho Winery 提供的一個產(chǎn)品,并且您想刪除該產(chǎn)品但仍保留供應商名稱和地址信息。如何在不丟失供應商信息的前提下刪除產(chǎn)品記錄呢?您無法做到這一點。因為每條記錄中既包含有關產(chǎn)品的事實,也包含有關供應商的事實,無法刪除一個事實而保留另一個事實。為了分開保存這些事實,必須將一個表拆分為兩個表:一個表存儲產(chǎn)品信息,另一個表存儲供應商信息。刪除產(chǎn)品記錄應僅刪除有關產(chǎn)品的事實,而不會刪除有關供應商的事實。

選擇了用表來表示的主題后,該表中的列就應僅存儲有關該主題的事實。例如,產(chǎn)品表應僅存儲有關產(chǎn)品的事實。由于供應商地址是有關供應商的事實,而不是有關產(chǎn)品的事實,因此屬于供應商表。

TopPageIcon_CLV 返回頁首

將信息項轉(zhuǎn)換為列

要確定表中的列,請確定需要跟蹤表中所記錄主題的哪些信息。例如,對于“客戶”表,“姓名”、“地址”、“市-省/自治區(qū)-郵編”、“發(fā)送電子郵件”、“稱呼”和“電子郵件地址”就是不錯的列初始列表。表中的每條記錄包含同一組列,因此,可以為每條記錄存儲“姓名”、“地址”、“市-省/自治區(qū)-郵編”、“發(fā)送電子郵件”、“稱呼”和“電子郵件地址”。例如,“地址”列包含客戶的地址。每條記錄包含有關一位客戶的數(shù)據(jù),而“地址”字段包含該客戶的地址。

為每個表確定了初始的一組列后,可以對列進行進一步優(yōu)化。例如,將客戶姓名作為兩個單獨的列存儲是有用的:即“名字”和“姓氏”,以便僅在這些列上進行排序、搜索和索引操作。類似地,地址實際上包含五個獨立的組成部分:地址、城市、省/市/自治區(qū)、郵政編碼和國家/地區(qū),也可以將這些信息存儲在單獨的列中。例如,如果希望按照省/市/自治區(qū)執(zhí)行搜索、篩選或排序操作,則需要將省/市/自治區(qū)信息存儲在單獨的列中。

還應該考慮數(shù)據(jù)庫是僅存儲國內(nèi)的信息,還是也要存儲國際信息。例如,如果打算存儲國際地址,則最好使用“地區(qū)”列代替“省/市/自治區(qū)”列,因為這樣的列既可能存儲國內(nèi)的省/市/自治區(qū),也可能存儲屬于其他國家/地區(qū)的地區(qū)。同樣,如果要存儲國際地址,則采用 Postal Code 比使用 Zip Code 更有用。

下面的列表顯示了用于確定列的一些提示。

不要包含已計算的數(shù)據(jù)

大多數(shù)情況下,不應在表中存儲計算結果。在希望查看相應結果時,可以讓 Access 執(zhí)行計算。例如,假如有一個“已訂購產(chǎn)品”報表,該報表顯示數(shù)據(jù)庫中每類產(chǎn)品的已訂購數(shù)量的分類匯總。不過,在所有表中都沒有“已訂購數(shù)量”分類匯總列。相反,“產(chǎn)品”表中包含存儲每種產(chǎn)品的已訂購數(shù)量的“已訂購數(shù)量”列。通過使用該數(shù)據(jù),Access 可以在每次打印報表時計算相應的分類匯總。而分類匯總本身不應存儲在表中。

將信息按照其最小的邏輯單元進行存儲

您可能非常想使用單個字段存儲全名,或使用單個字段存儲產(chǎn)品名稱和產(chǎn)品說明。如果將一種以上信息存儲在一個字段中,則在以后要檢索單個事實就會很困難。請嘗試將信息拆分為多個邏輯單元,例如,為姓氏和名字或為產(chǎn)品名稱、類別和說明創(chuàng)建單獨的字段。

設計過程中信息項的列表

對每個表中的數(shù)據(jù)列進行優(yōu)化后,就可以選擇每個表的主鍵了。

TopPageIcon_CLV 返回頁首

指定主鍵

每個表應包含一個列或一組列,用于對存儲在該表中的每個行進行唯一標識。這通常是一個唯一的標識號,如雇員 ID 號或序列號。在數(shù)據(jù)庫術語中,此信息稱為表的主鍵。Access 使用主鍵字段將多個表中的數(shù)據(jù)關聯(lián)起來,從而將數(shù)據(jù)組合在一起。

如果已經(jīng)為表指定了唯一標識符(如唯一標識目錄中的每種產(chǎn)品的產(chǎn)品編號),就可以使用該標識符作為表的主鍵,但僅當此列的值對每條記錄而言始終不同時才能如此。主鍵中不能有重復的值。例如,不要使用人名作為主鍵,因為姓名不是唯一的。很容易在同一個表中出現(xiàn)兩個同名的人。

主鍵必須始終具有值。如果某列的值可以在某個時間變成未分配或未知(缺少值),則該值不能作為主鍵的組成部分。

應該始終選擇其值不會更改的主鍵。在使用多個表的數(shù)據(jù)庫中,可將一個表的主鍵作為引用在其他表中使用。如果主鍵發(fā)生更改,還必須將此更改應用到其他任何引用該鍵的位置。使用不會更改的主鍵可降低出現(xiàn)主鍵與其他引用該鍵的表不同步的幾率。

通常將任意唯一數(shù)字作為主鍵使用。例如,可能會為每個訂單分配一個唯一的訂單號。訂單號的唯一用途是對訂單進行標識。分配后,訂單號就永遠都不更改。

如果尚未確定可能成為好的主鍵的一個或一組列,請考慮使用具有“自動編號”數(shù)據(jù)類型的列。使用“自動編號”數(shù)據(jù)類型時,Access 將自動為您分配一個值。這樣的標識符不包含事實數(shù)據(jù),即不包含描述它所表示的行的事實信息。不包含事實數(shù)據(jù)的標識符非常適合作為主鍵使用,因為它們不會更改。包含有關某一行的事實數(shù)據(jù)的主鍵(如電話號碼或客戶名稱)很有可能會改變,因為事實信息本身可能會更改。


顯示具有主鍵字段的“產(chǎn)品”表的圖像

標注 1 設置為“自動編號”數(shù)據(jù)類型的列通常是很好的主鍵。任何兩個產(chǎn)品 ID 都是不同的。


在某些情況下,您可能想使用兩個或多個字段一起作為表的主鍵。例如,存儲訂單行項目的“訂單細節(jié)”表將在其主鍵中使用兩個列:“訂單 ID”和“產(chǎn)品 ID”。當一個主鍵使用多個列時,它又被稱為復合鍵。

對于產(chǎn)品銷售數(shù)據(jù)庫,可以為每個表創(chuàng)建一個自動編號列作為主鍵使用:為“產(chǎn)品”表創(chuàng)建“產(chǎn)品 ID”、為“訂單”表創(chuàng)建“訂單 ID”、為“客戶”表創(chuàng)建“客戶 ID”、為“供應商”表創(chuàng)建“供應商 ID”。

顯示設計過程中的信息項的圖像

 

TopPageIcon_CLV 返回頁首

創(chuàng)建表關系

既然已經(jīng)將信息劃分到各表中,接下來需要一種方法,以有意義的方式再次將信息組織到一起。例如,下面的窗體包含來自幾個表的信息。


“訂單”窗體

標注 1 此窗體中的信息來自“客戶”表……

標注 2 ……“雇員”表……

標注 3 ……“訂單”表……

標注 4 ……“產(chǎn)品”表……

標注 5 ……和“訂單明細”表。


Access 是關系數(shù)據(jù)庫管理系統(tǒng)。在關系數(shù)據(jù)庫中,您將信息劃分到基于主題的不同表中。然后使用表關系根據(jù)需要將信息組合在一起。

TopPageIcon_CLV 返回頁首

創(chuàng)建一對多關系

請考慮下面的示例:產(chǎn)品訂單數(shù)據(jù)庫中的“供應商”和“產(chǎn)品”表。供應商可以提供任意數(shù)量的產(chǎn)品。“供應商”表中表示的任何供應商都是這樣,“產(chǎn)品”表中可以表示很多產(chǎn)品。因此,“供應商”表和“產(chǎn)品”表之間的關系就是一對多關系。

一對多的概念

為了在數(shù)據(jù)庫設計中表示一對多關系,請獲取關系“一”方的主鍵,并將其作為附加的一列或多列添加到關系“多”方的表中。例如在本例中,將“供應商”表中的“供應商 ID”列添加到“產(chǎn)品”表中。Access 可以隨后使用“產(chǎn)品”表中的供應商 ID 號來查找每個產(chǎn)品的正確供應商。

“產(chǎn)品”表中的“供應商 ID”列稱為外鍵。外鍵是另一個表的主鍵。“產(chǎn)品”表中的“供應商 ID”列之所以是外鍵,是因為它也是“供應商”表中的主鍵。

設計過程中信息項的列表

通過建立主鍵和外鍵的配對提供了聯(lián)接相關表的基礎。如果不確定哪些表應該共享一個公共列,通過確定一對多關系,就可以確保涉及的兩個表的確需要一個共享列。

TopPageIcon_CLV 返回頁首

創(chuàng)建多對多關系

考慮一下“產(chǎn)品”表和“訂單”表之間的關系。

單個訂單中可以包含多個產(chǎn)品。另一方面,一個產(chǎn)品可能出現(xiàn)在多個訂單中。因此,對于“訂單”表中的每條記錄,都可能與“產(chǎn)品”表中的多條記錄對應。同樣,對于“產(chǎn)品”表中的每條記錄,都可能與“訂單”表中的多條記錄對應。這種關系稱為多對多關系,因為對于任何產(chǎn)品,都可能有多個訂單,而對于任何訂單,都可能包含許多產(chǎn)品。請注意,為了檢測到表之間的多對多關系,務必要同時對關系的雙方進行考慮。

兩個表的主題(即訂單和產(chǎn)品)具有多對多關系, 這就帶來了一個問題。為了理解這個問題,請想像一下,如果試圖向“訂單”表添加“產(chǎn)品 ID”字段來創(chuàng)建兩個表之間的關系,會發(fā)生什么情況。為了讓每個訂單包含多個產(chǎn)品,則需要在“訂單”表中為每個訂單添加多條記錄。與單個訂單相關的每個行將重復使用相同的訂單信息,從而產(chǎn)生可能導致數(shù)據(jù)不準確的低效設計。如果在“產(chǎn)品”表中放置“訂單 ID”字段,也會遇到相同的問題,即在“產(chǎn)品”表中每個產(chǎn)品將有多條記錄與之對應。如何解決此問題呢?

答案是創(chuàng)建第三個表(通常稱為聯(lián)接表),該表將多對多關系分為兩個一對多關系。將這兩個表的主鍵都插入到第三個表中。因此,第三個表記錄關系的每個匹配項或?qū)嵗?/span>

多對多關系

“訂單明細”表中的每條記錄都代表訂單上的一個行項目?!坝唵蚊骷殹北淼闹麈I包含兩個字段,即“訂單”表和“產(chǎn)品”表的外鍵。僅使用“訂單 ID”字段作為此表的主鍵將不起作用,因為一個訂單可能具有多個行項目。“訂單 ID”對訂單上的每個行項目都會重復,因此該字段并不包含唯一的值。僅使用“產(chǎn)品 ID”字段作為主鍵也不起作用,因為一個產(chǎn)品可能會出現(xiàn)在多個不同的訂單中。但如果這兩個字段聯(lián)合起來,就始終都能為每條記錄生成一個唯一值。

在產(chǎn)品銷售數(shù)據(jù)庫中,“訂單”表和“產(chǎn)品”表并不直接彼此關聯(lián)。它們是通過“訂單細節(jié)”表間接關聯(lián)的。訂單和產(chǎn)品之間的多對多關系是通過使用兩個一對多關系在數(shù)據(jù)庫中得到表示的:

“訂單”表和“訂單細節(jié)”表具有一對多關系。每個訂單可以具有多個行項目,而每個行項目僅與一個訂單相關。
“產(chǎn)品”表和“訂單細節(jié)”表具有一對多關系。每個產(chǎn)品有多個與之關聯(lián)的行項目,而每個行項目僅引用一個產(chǎn)品。

通過“訂單細節(jié)”表,可以確定特定訂單中的所有產(chǎn)品。還可以確定特定產(chǎn)品的所有訂單。

引入了“訂單細節(jié)”表后,表和字段列表可能與以下所示類似:

設計過程中信息項的列表

 

TopPageIcon_CLV 返回頁首

創(chuàng)建一對一關系

另一種關系類型是一對一關系。例如,假定需要記錄某種特別的補充產(chǎn)品信息,此類信息很少需要使用或僅適用于少數(shù)產(chǎn)品。由于并不經(jīng)常需要此信息,并且在“產(chǎn)品”表中存儲此信息會導致不適用此信息的每個產(chǎn)品出現(xiàn)空白,因此請將此類信息放入單獨的表中。和“產(chǎn)品”表一樣,可以使用“產(chǎn)品 ID”作為主鍵。此補充表和“產(chǎn)品”表之間是一對一的關系。對于“產(chǎn)品”表中的每條記錄,在補充表中都存在單一的匹配記錄。標識此類關系時,這兩個表必須共享一個公共字段。

檢測到數(shù)據(jù)庫中對一對一關系的需求時,請考慮是否可以將兩個表中的信息放入一個表中。如果由于某種原因而不希望這樣做,或許是因為這樣會造成大量空白字段,下面的列表顯示如何在設計中表示這種關系:

如果兩個表具有相同主題,則可以通過在兩個表中使用相同的主鍵來建立這種關系。
如果兩個表具有不同的主題和不同的主鍵,則請選擇一個表(任意一個表),并將其主鍵作為外鍵插入到另一個表中。

通過確定表之間的關系,可幫助確保具有正確的表和列。當存在一對一或一對多關系時,所涉及的表需要共享一個或多個列。當存在多對多關系時,需要使用第三個表來表示該關系。

TopPageIcon_CLV 返回頁首

優(yōu)化設計

確定所需的表、字段和關系后,就應創(chuàng)建表并使用示例數(shù)據(jù)來填充表, 然后嘗試通過創(chuàng)建查詢、添加新記錄等操作來使用這些信息。這些操作可幫助發(fā)現(xiàn)潛在的問題,例如,可能需要添加在設計階段忘記插入的列,或者可能需要將一個表拆分為兩個表以消除重復。

確定是否可以使用數(shù)據(jù)庫獲得所期望的答案。創(chuàng)建窗體和報表的粗略草稿,檢查這些窗體和報表是否顯示所期望的數(shù)據(jù)。查找不必要的數(shù)據(jù)重復,找到后對設計進行更改,以消除這種數(shù)據(jù)重復。

在測試初始數(shù)據(jù)庫時,可能會發(fā)現(xiàn)可改進之處。以下是要檢查的事項:

是否忘記了任何列?如果是的話,該信息是否屬于現(xiàn)有的表?如果是有關其他主題的信息,則可能需要創(chuàng)建另一個表, 并為需要跟蹤的每個信息項創(chuàng)建一列。如果無法通過其他列計算出信息,則可能需要為其創(chuàng)建一個新列。
是否存在可通過現(xiàn)有字段計算得到的不必要的列?如果某信息項可以從其他現(xiàn)有列計算得出(例如通過零售價計算出的折扣價),則進行計算通常會更好,并能夠避免創(chuàng)建新列。
是否在某個表中重復輸入相同的信息?如果是的話,則可能需要將這個表拆分為兩個具有一對多關系的表。
是否存在這樣的表:具有很多字段,但記錄數(shù)量有限,且各個記錄中有很多空字段?如果有的話,則要考慮對該表進行重新設計,使其包含更少的字段和更多的記錄。
每個信息項是否已拆分為最小的有用單元?如果需要對某個信息項進行報告、排序、搜索或計算,則請將該項放入其自己的列中。
每一列是否包含有關所屬表的主題的事實?如果某一列不滿足此條件,則該列屬于其他表。
表之間的所有關系是否已經(jīng)都由公共字段或第三個表加以表示?一對一和一對多關系要求使用公共列, 而多對多關系要求使用第三個表來表示。

優(yōu)化“產(chǎn)品”表

假定產(chǎn)品銷售數(shù)據(jù)庫中的每個產(chǎn)品都歸屬于一個大類別,如飲料、調(diào)味品或海產(chǎn)品。“產(chǎn)品”表可以包含顯示每個產(chǎn)品所屬類別的字段。

假定檢查并優(yōu)化數(shù)據(jù)庫設計后,您決定存儲類別說明及其名稱。如果向“產(chǎn)品”表添加“類別說明”字段,則必須對屬于相應類別的每個產(chǎn)品重復使用其類別說明,但這并不是一個好的解決方法。

更好的方法是讓“類別”成為數(shù)據(jù)庫中要跟蹤的新主題,使其具有自己的表和主鍵。然后可以將“類別”表的主鍵作為外鍵添加到“產(chǎn)品”表中。

“類別”和“產(chǎn)品”表具有一對多關系:一個類別可以包含多個產(chǎn)品,但一個產(chǎn)品只能屬于一個類別。

復查表結構時,要密切注意重復的組。例如,考慮一下包含以下列的表:

產(chǎn)品 ID
名稱
產(chǎn)品 ID1
名稱1
產(chǎn)品 ID2
名稱2
產(chǎn)品 ID3
名稱3

其中每個產(chǎn)品都是重復的列組,只通過向列名的末尾添加一個數(shù)字加以區(qū)別??吹揭赃@種方式進行編號的列時,應重新對設計進行檢查。

此類設計有幾個缺點。首先,這將強制對產(chǎn)品的數(shù)量施加一個上限。超過了這個上限后,就必須向表結構中添加一組新列,而這是一項主要的管理任務。

另一個問題是,對于那些擁有的產(chǎn)品數(shù)量少于產(chǎn)品的最大數(shù)量的供應商,將浪費一定的空間,因為其他列將為空。此類設計最嚴重的缺陷在于,它使得很多任務都難以執(zhí)行,例如按照產(chǎn)品 ID 或名稱對表進行排序或索引。

只要看到重復組,就應該仔細地對設計進行復查,以期將該表拆分為兩個表。在上面的示例中,使用兩個表會更好,一個存儲供應商信息,另一個存儲產(chǎn)品信息,通過供應商 ID 進行鏈接。

TopPageIcon_CLV 返回頁首

應用規(guī)范化規(guī)則

接下來可以在設計中應用數(shù)據(jù)規(guī)范化規(guī)則(有時候直接稱為規(guī)范化規(guī)則)。可以使用這些規(guī)則來確定表的結構設計是否正確。將這些規(guī)則應用到數(shù)據(jù)庫設計的過程稱為數(shù)據(jù)庫規(guī)范化,或直接稱為規(guī)范化。

在表示了所有信息項并完成了初步設計時,規(guī)范化過程最有用。它將幫助確保已經(jīng)將信息項劃分到恰當?shù)谋碇?。?guī)范化無法確保一開始就擁有所有的正確數(shù)據(jù)項。

需要在每個步驟中持續(xù)應用這些規(guī)則,以確保設計達到“范式”要求。廣泛接受的范式有五個:第一范式到第五范式。本文將對前面三個范式展開討論,因為大部分數(shù)據(jù)庫設計都要求使用這三個范式。

第一范式

第一范式規(guī)定,表中每個行和列的交叉處只存在一個值,而決不是值的列表。例如,不能在一個名為“價格”的字段中放置多個“價格”。如果將行與列的每個交叉點看作一個單元格,則每個單元格中只能包含一個值。

第二范式

第二范式要求每個非鍵列完全依賴于整個主鍵,而不僅僅依賴于主鍵的一部分。當主鍵由多個列組成時,就適用此規(guī)則。例如,假定有包含以下列的表,其中“訂單 ID”和“產(chǎn)品 ID”構成主鍵:

訂單 ID(主鍵)
產(chǎn)品 ID(主鍵)
產(chǎn)品名稱

此設計違反了第二范式,因為“產(chǎn)品名稱”依賴于“產(chǎn)品 ID”,但并不依賴于“訂單 ID”,因此并不依賴于整個主鍵。必須將“產(chǎn)品名稱”從表中刪除。它屬于不同的表,即屬于“產(chǎn)品”表。

第三范式

第三范式要求不僅每個非鍵列依賴于整個主鍵,且非鍵列要互相獨立。

另一種說法就是,每個非鍵列必須且只能依賴于主鍵。例如,假定有包含以下列的表:

產(chǎn)品 ID(主鍵)
名稱
SRP
折扣

假定“折扣”依賴于建議零售價 (SRP)。此表就違反了第三范式,因為非鍵列“折扣”依賴于另一個非鍵列 SRP。列獨立性表示應該可以在不影響任何其他列的情況下更改任何非鍵列。如果更改了 SRP 字段中的值,“折扣”將相應地發(fā)生改變,這樣就違反了該規(guī)則。在本例中,“折扣”應該移到另一個以 SRP 為主鍵的表中。

TopPageIcon_CLV 返回頁首