天天看點

資料庫規範化設計理論摘要要

SQL資料庫設計規範參考之資料庫對象命名詳細文檔

時間:2009-12-16 13:23:29 來源:www.cnblogs.com 作者:

-

對于一個大項目來講,資料庫的設計命名規範是很重要的一個環節,好的表設計,讓人看得很舒服,一看就明白是什麼意思了,下面看到一篇很不錯的資料庫對象命名參考文檔,是以整理分享給大家。

引言

編碼規範是一個優秀程式員的必備素質,然而,有很多人非常注重程式中變量、方法、類的命名,卻忽視了同樣重要的資料庫對象命名。這篇文章結合許多技術文章和資料,以及我自己的開發經驗,對資料庫對象的命名規則提出了一點建議,希望能為大家提供一些參考。

NOTE:雖然這篇文章名為“資料庫對象命名參考”,實際上,在這篇文章中我不僅介紹了資料庫命名的規則,連帶講述了在資料庫設計與開發時所需要注意的幾個問題。

基本命名規則

表1. 基本資料庫對象命名

資料庫對象 字首 舉例

表(Table)

字段(Column)

視圖(View)

存儲過程(Stored procedure)

觸發器(Trigger)

索引(Index)

主鍵(Primary key)

外鍵(Foreign key)

Check限制(Check Constraint)

Unique限制

使用者定義資料類型(User-defined data type)

使用者定義函數(User-defined function) 無

v

pr

tr

ix_

pk_

fk_

ck_

uq_

udt

fn Student

Title

vActivity

prDelOrder

trOrder_D

ix_CustomerID

pk_Admin

fk_Order_OrderType

ck_TableColumn

uq_TableColumn

udtPhone

fnDueDate

關于命名的約定

變量(T-SQL程式設計中聲明的變量)、過程(存儲過程或觸發器等)、實體(表、字段)應該根據他們所代表的實體意義和程序作用來命名:

表2.好的命名 和 不好的命名 範例

好的命名 不好的命名

@CurrentDate

@ActivityCount

@EquipmentType

prCalculateTotalPrice @D

@ActNum

@ET

@prRunCalc

還有一個常見的錯誤就是隻使用面向計算機的術語,而不是面向公司業務的術語,比如ProcessRecord就是一個含糊不清的命名,應該使用一個程序業務描述來替換它,比如CompleteOrder.

如果完全根據上一條的要求,那麼根據業務描述的過程名可能會變得很冗長,比如下面:

prCountTotalAmountOfMonthlyPayments (計算每月付費的總金額)

prGetParentOrganizationalUnitName (擷取上級機關名稱)

此時則應該考慮使用縮寫:

如果可以在字典裡找到一個詞的縮寫,就用這個做為縮寫,比如:Mon(Monday)、Dec(December)

可以删除單詞元音(詞首字母除外)和每個單詞的重複字母來縮寫一個單詞。比如:Current = Crnt、Address = Adr、Error = Err、Average = Avg

不要使用有歧異的縮寫(一般是語音上的歧義)。比如b4(before)、xqt(execute),4tran(Fortran)

表格、字段的命名:

單數表名、字段名 還是 複數表名、字段名?

可能大家很少會考慮到給表名起單數還是複數,比如,對存儲客人資訊的表,我們應該起Customer,還是Customers?我主張起單數表名,下面是來自《SQL Server 2000 寶典》的一段引用:

主張用複數表名的陣營認為:表是由一組記錄構成的,是以應當使用複數名詞來命名它。他們經常使用的理由是:客戶表是客戶們的集合,而集合意味着多個,是以應當稱他們為Customers表。除非你隻有一個客戶,但這種情況你根本用不着資料庫。

根據筆者的非正式調查,有3/4的SQL Server開發人員支援使用單數命名。這些開發人員認為,客戶表是客戶的集合,而不是客戶們的集合。一組行不應當也不會被成為rows set(行們的集合),而會被稱為row set(行集)。并且,通常在讨論時人們會使用單數名稱來稱呼表,說Customer表比說Customers表聽起來更為清晰。

避免無謂的表格字尾

這兩點我想大家都知道:1、表是用來存儲資料資訊的。2、表是行的集合。那麼如果表名已經能夠很好地說明其包含的資料資訊,就不需要再添加展現上面兩點的字尾了。

實際工作中,我看到有的同僚對表這樣命名:GuestInfo,用于存儲客戶資訊。這個命名與上面所說的第1點重複,誰都知道表本來就是存儲資訊(information)的,再加個Info無異于畫蛇添足,個人認為直接用Guest做表名就可以了。

對于存儲航班資訊的表,他又命名為FlightList。這個命名又與之前說的第2點相重複,表是行的集合,那麼自然是清單(List),加上List字尾顯得很多餘,命名為 Flight 不是很好麼?可見,他給自己都沒有訂立一個明确的命名規則,不然這兩個表一定是要麼命名為:GuestList、FlightList 要麼命名為 GuestInfo、FlightInfo,而不會是兩者的混合。

多對多關系中連接配接表的命名

大家知道,如果要實作兩個實體間的多對多關系,需要三張表,其中一張是解析表。考慮下面這樣一個多對多關系,這是一個經典的學生選課問題:一個學生可以選很多門課,一門課可以有很多學生。此時為了實作上面的關系,就需要一張解析表(這張表隻存儲學生ID和課程ID,而學生的資訊和課程資訊分别存在各自的表中),這個表的起名,建議的寫法是将兩個表的表名合并(如果表名比較長可做簡化),此處如 StudentCourse。這個表中字段分别命名為StudentId、CourseID(既是此表的複合主鍵,同時分别為連接配接Student表和Course表的外鍵,等下到主鍵和外鍵的命名處再說),這樣就實作了學生和課程之間的多對多關系,當然,這個關系還可以加點額外的東西,比如給StudentCourse表中加AccessLevel字段,值域D{隻讀,完全,禁止},就可以實作通路級别。

約定俗成的字段名前/字尾

資料庫開發的時間久了,慢慢就會摸索出一個規律來:就是很多的字段都有些共同的特性。比如說,有的字段是代表時間的(例如發帖時間,評論時間),有的是代表數量的(例如浏覽數,評論數),有的是代表真假類型的(例如是否将部落格随筆顯示在首頁)。對于這種同一類型的字段,應該使用統一的 字首 或者 字尾去辨別它。

我們來舉幾個例子看得更明白一點。

以大家都熟悉的論壇來說,需要記錄會員最後一次登入的時間,這時候一般人都會把這個字段命名為LoginTime 或者 LoginDate。這時候,已經産生了一個歧義:對于另一名開發者來說,如果僅看表的字段名稱,不去看表的内容,很容易将LoginTime了解成 登入的次數,因為,Time還有一個很常用的意思,就是次數。

為了避免這種情況發生,應該明确的規定:所有表示時間的字段,統一以 Date 來作為結尾。

我們經常需要統計發帖數、回帖數資訊,這時候,開發人員通常會這樣去命名字段:PostAmount、PostTime、PostCount,同樣,由于Time的歧義,我們首先排除掉不使用PostTime作為字段名。接下來,Amount 和 Count 都可以表示計數的意思,用哪個合适呢?這裡,我推薦使用Count。為什麼呢?如果你做過Asp開發,相信一定知道 RecordCount 這個屬性,命名的時候有一個原則:就是使用約定俗成的名稱,而不要去自創名稱。既然微軟都用Count字尾來表示數目,我們為什麼不呢?

于是,所有表示數目的字段,都應該以Count作為結尾。将這一概念做以推廣,很容易得出,浏覽次數為 ViewCount,登入次數為LoginCount 等等。

再舉一個例子,我們很少在資料庫裡直接儲存圖檔等二進制資料,通常是僅儲存圖檔的URL路徑;在文章管理系統中,如果是轉載文章,也會用到記錄文章出處的字段。個人建議所有代表連結的字段,均為Url結尾。于是,圖檔路徑的字段命名為 ImageUrl,文章出處字段的命名為SourceUrl。

最後一個例子,我們經常需要用到布爾值,比方說,這篇随筆要不要顯示到首頁,這篇随筆是不是儲存到草稿箱等等。同樣,按照微軟的建議,布爾類型的值均以 Is、Has 或者 Can開頭。

如果讓我來建表示是否将随筆放到首頁的字段,它的名字一定是這樣的:IsOnIndex

類似的例子是很多的,我在這裡僅舉出典型的幾個範例,大家可以自行拓展,如果我能起到一個抛磚引玉的作用就很滿足了。

字段命名時需注意的一個問題

我發現有很多開發人員喜歡給字段加上表名作為它的字首,舉個例子,如果有個表叫User,那麼他就會将這個表中的字段命名為:UserId、UserPassword、UserName、UserPhone 等等。個人認為,這是沒有必要的,因為你已經确切的知道了這個表存儲的是User的資訊,那麼其中的字段必然是針對于User的。而且,在Join連接配接操作中,你的SQL代碼看上去也會更加的精簡一些,諸如 [User].UserName = Aritcle.ArticleAuthor 這樣的代碼完全可以實作為 [User].Name = Article.Author。

這裡還存在一個特例,就是表的外鍵包含的字段。在這種情況下,我傾向于使用表名+ID 的方式,比如 CategoryId 、UserId 等。假設有表Article,那麼它的主鍵我會命名為Id,關聯使用者表User的外鍵包含的字段,我會命名為UserId。之是以這樣,是因為在語言(比如C#)中建立對象時,有時候會使用代碼生成器(根據資料庫的字段名生成對象的字段、屬性名),此時生成的代碼更規整一些。

文章來自學IT網:http://www.xueit.com/Mssql/show-5196-1.aspx

SQL資料庫設計規範參考之資料庫對象命名詳細文檔

時間:2009-12-16 13:23:29 來源:www.cnblogs.com 作者:

-

建表時需要注意的問題

資料庫不僅是用來儲存資料,還應負責維護資料的完整性和一緻性

我看過很多的開發人員設計出來的資料庫,給我的感覺就是:在他們眼裡,資料庫的作用就如同它的名稱一樣――僅僅是用來存放資料的,除了不得不建的主鍵以外,什麼都沒有...沒有 Check限制,沒有索引,沒有外鍵限制,沒有視圖,甚至沒有存儲過程。

在這裡,我提出如下資料庫設計的建議:

如果要寫代碼來確定表中的行都是唯一的,就為表添加一個主鍵。

如果要寫代碼來確定表中的一個單獨的列是唯一的,就為表添加一個限制。

如果要寫代碼确定表中的列的取值隻能屬于某個範圍,就添加一個Check限制。

如果要寫代碼來連接配接 父-子 表,就建立一個關系。

如果要寫代碼來維護“一旦父表中的一行發生變化,連帶變更子表中的相關行”,就啟用級聯删除和更新。

如果要調用大量的Join來進行一個查詢,就建立一個視圖。

如果要逐條的寫資料庫操作的語句來完成一個業務規則,就使用存儲過程。

NOTE:這裡我沒有提到觸發器,實踐證明觸發器會使資料庫迅速變得過于複雜,更重要的是觸發器難以調試,如果不小心建了個連環觸發器,就更讓人頭疼了,是以我更傾向于根本就不使用觸發器。

以Not Null的思路建表

我發現很多開發人員在建表的時候,如果要建立一個字段,他的思路是這樣的:預設這個字段是可以為Null的,然後去判斷是不是非要Not Null不可,如果不是這樣,OK,這個字段可以為Null,接着繼續進行下一個字段。結果往往是一張表除了主鍵以外所有的字段都可以為Null。

之是以會有這樣的思路,是因為Null好啊,程式不容易出錯啊,你插入記錄的時候如果不小心忘輸了一個字段,程式依然可以Run,而不會出現 “XX字段不能為Null”的錯誤消息。

但是,這樣做的結果卻是很嚴重的,也會使你的程式變得更加繁瑣,你不得不進行一些無謂的空值處理,以避免程式出錯。更糟的是,如果一些重要資料,比如說訂單的某一項值為Null了,那麼大家知道,任何值與Null相操作(比如加減乘除),結果都是Null,導緻的結果就是訂單的總金額也為Null。

你可以運作下面的代碼嘗試一下:

Select Null + 5 As Result

你可能會說,就算我将字段設定成Not Null,但是它依然可以接受空字元串,這樣一來在程式中還是要進行空值處理。請别忘了,資料庫還賦予你一個強力武器,就是 Check 限制,當你需要確定一個字段既不可以為Null,又不可以為空的時候,可以這麼寫:

ColumnName    Varchar(50)       Not Null Constraint ck_ColumnName Check(Len(ColumnName) > 0)

是以,合理的思維方式應該是這樣的:預設這個字段是 Not Null的,然後判斷這個字段是不是非為Null不可,如果不是這樣,OK,這個字段是Not Null的,進行下一個字段。

一個建表的範例腳本

我正在建立我自己的個人空間,其中的文章表是這樣寫的:

Create Table Article

(

    Id            Int Identity(1,1) Not Null,

    Title         Varchar(50)       Not Null Constraint uq_ArticleTitle Unique,

    Keywords      Varchar(50)       Not Null,

    Abstract      Varchar(500)      Not Null,

    Author        Varchar(50)       Not Null Default '張子陽',

    Type          TinyInt           Not Null Default 0 Constraint ck_ArticleType Check(Type in (0,1,2)),  -- 0,原創;1,編譯;2,翻譯

    IsOnIndex     Bit               Not Null Default 1,   -- 是否顯示在首頁

    Content       Text              Not Null,

    SourceCode    Varchar(100)      Null,  -- 程式源碼的下載下傳路徑

    Source        Varchar(50)       Not Null Default 'TraceFact',   -- 文章出處

    SrcUrl        Varchar(150)      Null,  -- 文章出處的URL

    PostDate      DateTime          Not Null Default GetDate(),

    ViewCount     Int               Not Null Default 0,

    ClassId       Int               Not Null   -- 外鍵包含的字段,文章類别

    Constraint pk_Article Primary Key(Id)   -- 建立主鍵

)

可以看到,在這裡我使用了 Check 限制,以確定文章類型隻能為 0,1,2。這裡,我想說的是Check 限制的命名規則:盡管Check限制是針對字段的,但在同一資料庫中,卻不能有同名的Check限制。是以,建議使用 ck_ + 表名 + 字段名 來命名它,比如這個範例腳本中的 ck_ArticleType。

除此以外,我還使用了Unique限制,以確定文章标題的唯一性。由于這是我的部落格文章表,不應該出現重複的題目,這樣可以避免在使用 Insert 語句時插入重複值。類似于Check限制,這裡的命名規則是:uq_ + 表名 + 字段名。

主鍵的命名

按照SQL Server 的預設規範(使用企業管理器建立主鍵時預設産生的主鍵名),主鍵的命名為 pk_TableName。主鍵是針對一個表的,而不是針對一個字段的,大家有時候在企業管理器中會見到一個表的兩個字段前面都會有鑰匙的圖示(比如SQL Server 2000自帶的NorthWind範例資料庫的EmployeeTerritories表),就會誤以為主鍵是針對字段的,即是說一個表上有兩個主鍵,其實錯了,隻有一個主鍵,但包含了兩個字段,這就是常說的複合主鍵。為了有個更生動的認識,看下建立複合主鍵的SQL語句,以上面說到的多對多連接配接表StudentCourse為例:

Alter Table StudentCourse

Add Constraint pk_StudentCourse Primary key(StudentId, CourseId)

可見,對于主鍵pk_StudentCourse,包含了兩個字段StudentId 和 CourseId。

外鍵的命名

外鍵的命名為 fk_外鍵所在的表名_外鍵引用的表名。因為外鍵所在的表為從表,是以上式可以寫為 fk_從表名_主表名。

外鍵包含的字段的命名,外鍵包含的字段和外鍵是完全不同的概念。外鍵包含字段的命名,建議為:外鍵所在的表名 + Id。

考慮這樣一個關系,表Hotel,字段Id, Name, CityId。表City,字段Id,Name。因為一個城市可能有好多家酒店,是以是一個一對多的關系,City是主表(1方),Hotel是從表(多方)。在Hotel表中,CityId是做為外鍵使用。

在實作外鍵的時候我們可以這樣寫:

Alter Table HotelInfo

Add Constraint fk_HotelInfo_City Foreign Key (CityID) References City(ID)

On Delete No Action On update No Action

很明顯,fk_HotelInfo_City是外鍵的名字,CityId是外鍵包含的字段的名字。

NOTE:在建立資料庫表的時候,一般需要寫成三個SQL腳本檔案。第一個檔案僅包含所有的建立表的SQL語句,即Create Table 語句。第二個檔案包含删除關系和表的語句,其中,所有删除關系的語句,即Drop Constraint 語句集中在這個檔案的上半部分,所有删除表的語句,Drop Table語句,集中在這個檔案的下半部分。第三個檔案包含建立表之間關系的語句。這種做法會在你移植資料庫的時候産生較大的便利,原因我就不解釋了,您一試便知。

而對于多對多關系中解析表的外鍵包含的字段,順理往下推,我們可以這樣寫(再次回到學生選課的多對多例子中):

建立解析表StudentCourse與Student表的外鍵關系:

Alter Table StudentCourse

Add Constraint fk_StudentCourse_Student Foreign Key (StudentId) References Student (Id)

On Delete No Action On Update No Action

建立解析表StudentCourse與Course 表的外鍵關系:

Alter Table StudentCourse

Add Constraint fk_StudentCourse_Course Foreign Key (CourseId) References Course(Id)

On Delete No Action On Update No Action

觸發器的命名

由三部分構成:

字首(tr),描述了資料庫對象的類型。

基本部分,描述觸發器所加的表。

字尾(_I、_U、_D),顯示了修改語句(Insert, Update及Delete)

存儲過程的命名

大家知道,系統存儲過程的字首是 sp_,為了避免将使用者存儲過程與系統存儲過程混淆,這裡我推薦大家使用 pr 作為自己定義的存儲過程的命名。

同時,命名的規則是:采用自解釋型的命名,比如:prGetItemById。

這裡,有個有意思的地方值得深思。我們按上面規則命名存儲過程的時候,可以用兩種方式:

動詞放前面,名詞放後面。

名詞放前面,動詞放後面。

我個人推薦使用方式2,現在說說原因:

以NorthWind 為例,假如對于 Employees 表你有4個存儲過程,分别命名為:prEmployeeInsert、prEmployeeUpdate、prEmployeeDelById、prEmployeeGetById

同時對于 Products 表你有類似的4個存儲過程,分别命名為:prProductInsert、prProductUpdate、prProductDelById、prProductGetById

這時,你用企業管理器檢視時,會發現存儲過程像下面這樣整整齊齊的排列:

prEmployeeDelById

prEmployeeGetById

prEmployeeInsert

prEmployeeUpdate

prProductDelById

prProductGetById

prProductInsert

prProductUpdate

很容易就會發現,當你的存儲過程越多時,這種命名方法的優勢就越明顯。

存儲過程中參數的命名

存儲過程中的入口參數,我建議與其對應的字段名相同,這裡,假設要寫一個更新Northwind資料庫Employees表的存儲過程(做了簡化),可以這麼寫:

Create Procedure prEmployeeUpdateById

    @EmployeeId       Int,

    @LastName     NVarchar(20),

    @FirstName    NVarchar(10)

As

    Update Employees Set

       LastName = @LastName,

       FirstName = @FirstName

    Where

       EmployeeId = @EmployeeId

    If @@error <> 0 or @@RowCount = 0

       Raiserror 16001 ‘更新使用者失敗’

總結

在這篇文章中,我首先提出了開發人員對資料庫對象命名不夠重視的問題,随後列出了一張資料對象命名的簡表。

接着我按照 表、字段、主鍵、外鍵、觸發器、存儲過程的順序,詳細講述了資料庫對象命名的規則。

其間,我還穿插着講述了在資料庫開發中常見的一些問題,包括建表時需要注意的問題,以及在管理存儲過程時可以采取的技巧。

文章來自學IT網:http://www.xueit.com/Mssql/show-5196-2.aspx

資料庫設計規範(命名規範)時間:2009-12-15 11:21:16來源:網絡 作者:未知 點選:101次 1 目的

規範資料庫設計。

2 概述

從資料庫的設計原則 設計文檔幾方面論述資料庫設計的規範思想及命名規則。

3 資料庫應用結構

根據對一般業務系統的分析,将資料庫和程式系統統一進行整體描述,展示資料庫的表之間以及與

1 目的

規範資料庫設計。

2 概述

從資料庫的設計原則 設計文檔幾方面論述資料庫設計的規範思想及命名規則。

3 資料庫應用結構

根據對一般業務系統的分析,将資料庫和程式系統統一進行整體描述,展示資料庫的表之間以及與程式子產品間的關系。

3.1 資料表和程式子產品的分類

根據“處理特點”,将資料表和程式子產品進行分類如下:

資料表分類:業務資料表、基本編碼表、輔助編碼表、系統資訊表、累計資料表、結算資料表、決策資料表。

程式子產品分類:初始化、業務處理、完整性檢測與修正、結算處理、統計處理。

3.1.1 資料表分類說明

業務資料表:記錄業務發生的過程和結果。如,合同、出倉單、申請單、憑證。

基本編碼表:描述業務實體的基本資訊和編碼。如,産品、客戶、供應商、雇員。

輔助編碼表:描述屬性的清單值。如,合同類型、職稱、民族、付款方式。

系統資訊表:存放與系統操作、業務控制有關的參數。如,使用者資訊、權限、使用者配置資訊、成本核算方式。

累計資料表:存放業務的目前值和累計值。如,目前庫存、目前存款、累計銷售、累計支出、應收賬款。

結算資料表:存放各個時期末的結存數。如,月末庫存、月末銀行存款、應收賬款月結。

決策資料表:存放各個時期内發生的統計值。如,月銷售統計、月回款統計、出入庫統計。

3.1.2 程式子產品分類說明

初始化:系統運作前對系統進行資料的初始化。如,庫存初始化。

業務處理:業務過程的控制和結果記錄。如,合同錄入、費用審批、出入庫。

完整性檢測與修正:對累計資料表進行檢查并自動修正。如對目前庫存、目前存款、累計銷售的檢查和重新計算。

結算處理:計算并記錄各個時期末的結存數。庫存月結、應收賬款月結。

統計處理:計算并記錄各個時期内發生的統計數。如,統計月銷售、統計月回款、統計出入庫。

3.2 資料表間的關系

業務資料表<-->基本編碼表 主-外鍵關系。如,合同表<-->客戶編碼表;

業務資料表<-->輔助編碼表 主-外鍵關系。如,合同表<-->付款方式;

業務資料表、累計資料表、結算資料表:累計資料表=結算資料表(上期末) + 業務數

據表(本期内發生)。如目前庫存=上月末庫存數+(本月入庫數-本月出庫數);

決策資料表<-->業務資料表 決策資料表的資料是由業務資料表中資料導出(統計)的;

3.3 資料表與程式子產品間的關系

由一個例子(倉庫管理)來說明資料表與程式子產品之間的關系:

. 系統使用前,由初始化子產品對庫存數(累計資料表)和上月末庫存數(結存資料表)進行初始化;. 當有入庫業務發生時,由入庫子產品(業務處理)将入庫單錄入并儲存到入庫單明細帳( 業務資料表)中,同時将入庫數累加到庫存數(累計資料表)中;. 定期或不定期,庫存數核算子產品(檢查完整性檢測與修正)根據上月末的庫存數(結存資料表)、本月已發生數(業務資料表)檢查目前的庫存數(累計資料表)是否符合,不符合則給出提示,可手工或自動進行更正(目前庫存數=上月末庫存數+本月入庫數-本月出庫數); . 每月初,進行上月的月結處理。月結子產品(結算處理)根據上月初的庫存數(結存資料表)、上月發生數(業務資料表)計算出上月末的庫存數(累計資料表)。公式為:上月末庫存數=上月初庫存數+上月入庫數-上月出庫數;. 每個月月結後,庫存業務月統計子產品(統計處理)統計上月的各種庫存商品的入庫和出庫數,便于查詢和生成報表,也作為決策支援的資料基礎。

3.4 資料表命名時對資料表分類的考慮

. 業務資料表:t_d_<系統辨別>_<表辨別>。如銷售系統的合同表 t_d_SH_Contract或 t_d_SH_合同; . 基本編碼表:t_b_[<系統辨別>]_<表辨別>。如客戶編碼表t_b_Customer 或 t_b_客戶; . 輔助編碼表:t_a_[<系統辨別>]_<表辨別>。如合同類别t_a_ContType 或 t_a_合同類别; . 系統資訊表:t_s_[<系統辨別>]_<表辨別>。如使用者表t_s_User 或 t_s_使用者;. 累計資料表:t_t_<系統辨別>_<表辨別>。如目前庫存表t_t_SO_Stock 或 t_t_SO_庫存; . 結算資料表:t_c_<系統辨別>_<表辨別>。如庫存月結表t_c_SO_StockMonth 或t_c_SO_庫存月結; . 決策資料表:t_w_<系統辨別>_<表辨別>。如月銷售統計表t_w_SH_SellMonth 或t_w_SH_月銷售統計; 注:[]内的内容表示可選。如“t_s_[<系統辨別>]_<表辨別>”表示t_s_SH_User 和t_s_User 都是符合規則的。

4 資料庫結構原則

規定除資料庫設計所遵循的範式外的一些适用原則,在遵循資料庫設計範式的基礎上,合理地劃分表,添加狀态和控制字段等。

4.1 輔助編碼表

為了使輔助編碼表能起到預期的效能,又不因過多的輔助編碼表難以管理,故對輔助編碼表的使用作如下規定:

1. 當某輔助編碼表的編碼允許使用者添加時,應設計成“獨立”的資料表;否則,将不允許使用者添加編碼的各輔助編碼表合并成一個“通用”的輔助編碼表。

2. “獨立”的輔助編碼表與主表的列采用主-外限制保證列資料完整性。

3. “通用”的輔助編碼表與各主表間沒有限制關系,主表列的資料完整性由列說明的“域”來保證。

4. “通用”的輔助編碼表除編碼和名稱列外,還有一個辨別列,用來辨別合并前的各碼表,該辨別列+編碼列作為該表的主鍵。

5. 對于“獨立”的輔助編碼表,使用者隻可添加新的編碼和改變名稱,并且不能改變一個編碼所代表的意義;對于“通用”的輔助編碼表,原則上不允許使用者修改,或隻有限地允許修改名稱。

4.2 基本編碼表

1. 基本編碼表可以有如下的辨別列:内編碼、外編碼、助記碼、簡稱、全稱。内編碼(唯一編碼)作為主鍵有程式自動生成,使用者不可見;外編碼(唯一編碼)由使用者按某種規則自行定義,使用者可見;助記碼為拼音縮,友善錄入,不唯一,重碼時由清單選擇;簡稱用于清單顯示和報表,以便縮短行寬。以上的列在實作時可視情況和習慣加以删減。

2. 當碼表的列較多且也行較多時,可将上述的辨別列和常用的資訊存于一個表,将其它的資訊另表存儲。

4.3 業務資料表

1. 設有‘錄入人’和‘錄入日期’列,由系統自動記錄。

2. 記錄單據的表中設定“自動單據号”,由兩個字元開始以區分單據類型,後跟一數字序清單示序号。‘自動單據号’由系統自動生成,作為主表的主鍵,不允許使用者修改。

當有對應的紙質單據時,設定“單據号”用于記錄紙質單據的單據号。

3. 明細表中設有行序号,自動記錄行的錄入順序。

4. 設定“存檔标記”列,用于抽取資料到決策資料庫時的更新标記。插入新行或修改已有行時設定該标記;資料抽取後清除該标記。

5. 對于用于查詢過濾條件的列,不可為空,以免行“丢失”。

6. 對于數值列,不可為空,“0”作為預設值。

7. 對于必要的“備援”列,如客戶名稱,應有相應的程式保持各“備援”列的同一性,以免出現異議。

8. 設定“過程狀态”列和“記錄狀态”列。過程狀态列用于記錄如建立、稽核、記賬、沖紅等狀态;記錄狀态用于記錄如有效、删除等狀态。

5 資料庫命名原則

5.1 表名

. 業務資料表:t_d_<系統辨別>_<表辨別>。

. 基本編碼表:t_b_[<系統辨別>]_<表辨別>。

. 輔助編碼表:t_a_[<系統辨別>]_<表辨別>。

. 系統資訊表:t_s_[<系統辨別>]_<表辨別>。

. 累計資料表:t_t_<系統辨別>_<表辨別>。

. 結算資料表:t_c_<系統辨別>_<表辨別>。

. 決策資料表:t_w_<系統辨別>_<表辨別>。

5.2 視圖

v_<視圖類型>_[<系統辨別>]_<視圖示識>。視圖類型參見《表的分類》。

5.3 存儲過程

p_[<系統辨別>]_<存儲過程辨別>

5.4 函數

f_[<系統辨別>]_<函數辨別>

5.5 觸發器

tr_<表名>_<i,u,d的任意組合> (after)

ti_<表名>_<i,u,d的任意組合> (instead)

5.6 自定義資料類型

ud_<自定義資料類型辨別>_<資料類型>

5.7 Default

df_<Default辨別>

5.8 Rule

ru_<Rule辨別>

5.9 主鍵

pk_<表名>_<主鍵辨別>

5.10 外鍵

fk_<表名>_<主表名>_<外鍵辨別>

本篇文章來源于:開發學院 http://edu.codepub.com   原文連結:http://edu.codepub.com/2009/1215/18753.php

小龜MR

123456MINGr

一、資料庫設計過程

資料庫技術是資訊資源管理最有效的手段。資料庫設計是指對于一個給定的應用環境,構造最優的資料庫模式,建立資料庫及其應用系統,有效存儲資料,滿足使用者資訊要求和處理要求。

資料庫設計中需求分析階段綜合各個使用者的應用需求(現實世界的需求),在概念設計階段形成獨立于機器特點、獨立于各個DBMS産品的概念模式(資訊世界模型),用E-R圖來描述。在邏輯設計階段将E-R圖轉換成具體的資料庫産品支援的資料模型如關系模型,形成資料庫邏輯模式。然後根據使用者處理的要求,安全性的考慮,在基本表的基礎上再建立必要的視圖(VIEW)形成資料的外模式。在實體設計階段根據DBMS特點和處理的需要,進行實體存儲安排,設計索引,形成資料庫内模式。

1. 需求分析階段

需求收集和分析,結果得到資料字典描述的資料需求(和資料流圖描述的處理需求)。

需求分析的重點是調查、收集與分析使用者在資料管理中的資訊要求、處理要求、安全性與完整性要求。

需求分析的方法:調查組織機構情況、調查各部門的業務活動情況、協助使用者明确對新系統的各種要求、确定新系統的邊界。

常用的調查方法有: 跟班作業、開調查會、請專人介紹、詢問、設計調查表請使用者填寫、查閱記錄。

分析和表達使用者需求的方法主要包括自頂向下和自底向上兩類方法。自頂向下的結構化分析方法(Structured Analysis,簡稱SA方法)從最上層的系統組織機構入手,采用逐層分解的方式分析系統,并把每一層用資料流圖和資料字典描述。

資料流圖表達了資料和處理過程的關系。系統中的資料則借助資料字典(Data Dictionary,簡稱DD)來描述。

資料字典是各類資料描述的集合,它是關于資料庫中資料的描述,即中繼資料,而不是資料本身。資料字典通常包括資料項、資料結構、資料流、資料存儲和處理過程五個部分(至少應該包含每個字段的資料類型和在每個表内的主外鍵)。

資料項描述={資料項名,資料項含義說明,别名,資料類型,長度,

         取值範圍,取值含義,與其他資料項的邏輯關系}

資料結構描述={資料結構名,含義說明,組成:{資料項或資料結構}}

資料流描述={資料流名,說明,資料流來源,資料流去向,

         組成:{資料結構},平均流量,高峰期流量}

資料存儲描述={資料存儲名,說明,編号,流入的資料流,流出的資料流,   

        組成:{資料結構},資料量,存取方式}

處理過程描述={處理過程名,說明,輸入:{資料流},輸出:{資料流},

          處理:{簡要說明}}

2. 概念結構設計階段

通過對使用者需求進行綜合、歸納與抽象,形成一個獨立于具體DBMS的概念模型,可以用E-R圖表示。

概念模型用于資訊世界的模組化。概念模型不依賴于某一個DBMS支援的資料模型。概念模型可以轉換為計算機上某一DBMS支援的特定資料模型。

概念模型特點:

(1) 具有較強的語義表達能力,能夠友善、直接地表達應用中的各種語義知識。

(2) 應該簡單、清晰、易于使用者了解,是使用者與資料庫設計人員之間進行交流的語言。

概念模型設計的一種常用方法為IDEF1X方法,它就是把實體-聯系方法應用到語義資料模型中的一種語義模型化技術,用于建立系統資訊模型。

    使用IDEF1X方法建立E-R模型的步驟如下所示:

2.1 第零步——初始化工程

這個階段的任務是從目的描述和範圍描述開始,确定模組化目标,開發模組化計劃,組織模組化隊伍,收集源材料,制定限制和規範。收集源材料是這階段的重點。通過調查和觀察結果,業務流程,原有系統的輸入輸出,各種報表,收集原始資料,形成了基本資料資料表。

2.2 第一步——定義實體

實體內建員都有一個共同的特征和屬性集,可以從收集的源材料——基本資料資料表中直接或間接辨別出大部分實體。根據源材料名字表中表示物的術語以及具有“代碼”結尾的術語,如客戶代碼、代理商代碼、産品代碼等将其名詞部分代表的實體辨別出來,進而初步找出潛在的實體,形成初步實體表。

2.3 第二步——定義聯系

IDEF1X模型中隻允許二進制聯系,n元聯系必須定義為n個二進制聯系。根據實際的業務需求和規則,使用實體聯系矩陣來辨別實體間的二進制關系,然後根據實際情況确定出連接配接關系的勢、關系名和說明,确定關系類型,是辨別關系、非辨別關系(強制的或可選的)還是非确定關系、分類關系。如果子實體的每個執行個體都需要通過和父實體的關系來辨別,則為辨別關系,否則為非辨別關系。非辨別關系中,如果每個子實體的執行個體都與而且隻與一個父實體關聯,則為強制的,否則為非強制的。如果父實體與子實體代表的是同一現實對象,那麼它們為分類關系。

2.4 第三步——定義碼

通過引入交叉實體除去上一階段産生的非确定關系,然後從非交叉實體和獨立實體開始辨別侯選碼屬性,以便唯一識别每個實體的執行個體,再從侯選碼中确定主碼。為了确定主碼和關系的有效性,通過非空規則和非多值規則來保證,即一個實體執行個體的一個屬性不能是空值,也不能在同一個時刻有一個以上的值。找出誤認的确定關系,将實體進一步分解,最後構造出IDEF1X模型的鍵基視圖(KB圖)。

2.5 第四步——定義屬性

從源資料表中抽取說明性的名詞開發出屬性表,确定屬性的所有者。定義非主碼屬性,檢查屬性的非空及非多值規則。此外,還要檢查完全依賴函數規則和非傳遞依賴規則,保證一個非主碼屬性必須依賴于主碼、整個主碼、僅僅是主碼。以此得到了至少符合關系理論第三範式的改進的IDEF1X模型的全屬性視圖。

2.6 第五步——定義其他對象和規則

    定義屬性的資料類型、長度、精度、非空、預設值、限制規則等。定義觸發器、存儲過程、視圖、角色、同義詞、序列等對象資訊。

3. 邏輯結構設計階段

    将概念結構轉換為某個DBMS所支援的資料模型(例如關系模型),并對其進行優化。設計邏輯結構應該選擇最适于描述與表達相應概念結構的資料模型,然後選擇最合适的DBMS。

将E-R圖轉換為關系模型實際上就是要将實體、實體的屬性和實體之間的聯系轉化為關系模式,這種轉換一般遵循如下原則:

1)一個實體型轉換為一個關系模式。實體的屬性就是關系的屬性。實體的碼就是關系的碼。

2)一個m:n聯系轉換為一個關系模式。與該聯系相連的各實體的碼以及聯系本身的屬性均轉換為關系的屬性。而關系的碼為各實體碼的組合。

3)一個1:n聯系可以轉換為一個獨立的關系模式,也可以與n端對應的關系模式合并。如果轉換為一個獨立的關系模式,則與該聯系相連的各實體的碼以及聯系本身的屬性均轉換為關系的屬性,而關系的碼為n端實體的碼。

4)一個1:1聯系可以轉換為一個獨立的關系模式,也可以與任意一端對應的關系模式合并。

5)三個或三個以上實體間的一個多元聯系轉換為一個關系模式。與該多元聯系相連的各實體的碼以及聯系本身的屬性均轉換為關系的屬性。而關系的碼為各實體碼的組合。  

6)同一實體集的實體間的聯系,即自聯系,也可按上述1:1、1:n和m:n三種情況分别處理。

7)具有相同碼的關系模式可合并。

為了進一步提高資料庫應用系統的性能,通常以規範化理論為指導,還應該适當地修改、調整資料模型的結構,這就是資料模型的優化。确定資料依賴。消除備援的聯系。确定各關系模式分别屬于第幾範式。确定是否要對它們進行合并或分解。一般來說将關系分解為3NF的标準,即:

表内的每一個值都隻能被表達一次。

· 表内的每一行都應該被唯一的辨別(有唯一鍵)。

表内不應該存儲依賴于其他鍵的非鍵資訊。  

4. 資料庫實體設計階段

為邏輯資料模型選取一個最适合應用環境的實體結構(包括存儲結構和存取方法)。根據DBMS特點和處理的需要,進行實體存儲安排,設計索引,形成資料庫内模式。

5. 資料庫實施階段

運用DBMS提供的資料語言(例如SQL)及其宿主語言(例如C),根據邏輯設計和實體設計的結果建立資料庫,編制與調試應用程式,組織資料入庫,并進行試運作。 資料庫實施主要包括以下工作:用DDL定義資料庫結構、組織資料入庫 、編制與調試應用程式、資料庫試運作  

6. 資料庫運作和維護階段

資料庫應用系統經過試運作後即可投入正式運作。在資料庫系統運作過程中必須不斷地對其進行評價、調整與修改。包括:資料庫的轉儲和恢複、資料庫的安全性、完整性控制、資料庫性能的監督、分析和改進、資料庫的重組織和重構造。

模組化工具的使用

為加快資料庫設計速度,目前有很多資料庫輔助工具(CASE工具),如Rational公司的Rational Rose,CA公司的Erwin和Bpwin,Sybase公司的PowerDesigner以及Oracle公司的Oracle Designer等。

ERwin主要用來建立資料庫的概念模型和實體模型。它能用圖形化的方式,描述出實體、聯系及實體的屬性。ERwin支援IDEF1X方法。通過使用ERwin模組化工具自動生成、更改和分析IDEF1X模型,不僅能得到優秀的業務功能和資料需求模型,而且可以實作從IDEF1X模型到資料庫實體設計的轉變。ERwin工具繪制的模型對應于邏輯模型和實體模型兩種。在邏輯模型中,IDEF1X工具箱可以友善地用圖形化的方式建構和繪制實體聯系及實體的屬性。在實體模型中,ERwin可以定義對應的表、列,并可針對各種資料庫管理系統自動轉換為适當的類型。

設計人員可根據需要選用相應的資料庫設計模組化工具。例如需求分析完成之後,設計人員可以使用Erwin畫ER圖,将ER圖轉換為關系資料模型,生成資料庫結構;畫資料流圖,生成應用程式。

二、資料庫設計技巧

1. 設計資料庫之前(需求分析階段)

1) 了解客戶需求,詢問使用者如何看待未來需求變化。讓客戶解釋其需求,而且随着開發的繼續,還要經常詢問客戶保證其需求仍然在開發的目的之中。

2) 了解企業業務可以在以後的開發階段節約大量的時間。

3) 重視輸入輸出。

在定義資料庫表和字段需求(輸入)時,首先應檢查現有的或者已經設計出的報表、查詢和視圖(輸出)以決定為了支援這些輸出哪些是必要的表和字段。

舉例:假如客戶需要一個報表按照郵政編碼排序、分段和求和,你要保證其中包括了單獨的郵政編碼字段而不要把郵政編碼糅進位址字段裡。

4) 建立資料字典和ER 圖表

ER 圖表和資料字典可以讓任何了解資料庫的人都明确如何從資料庫中獲得資料。ER圖對表明表之間關系很有用,而資料字典則說明了每個字段的用途以及任何可能存在的别名。對SQL 表達式的文檔化來說這是完全必要的。

5) 定義标準的對象命名規範

資料庫各種對象的命名必須規範。

2. 表和字段的設計(資料庫邏輯設計)

表設計原則

1) 标準化和規範化

資料的标準化有助于消除資料庫中的資料備援。标準化有好幾種形式,但Third Normal Form(3NF)通常被認為在性能、擴充性和資料完整性方面達到了最好平衡。簡單來說,遵守3NF 标準的資料庫的表設計原則是:“One Fact in One Place”即某個表隻包括其本身基本的屬性,當不是它們本身所具有的屬性時需進行分解。表之間的關系通過外鍵相連接配接。它具有以下特點:有一組表專門存放通過鍵連接配接起來的關聯資料。

舉例:某個存放客戶及其有關定單的3NF 資料庫就可能有兩個表:Customer 和Order。Order 表不包含定單關聯客戶的任何資訊,但表内會存放一個鍵值,該鍵指向Customer 表裡包含該客戶資訊的那一行。

事實上,為了效率的緣故,對表不進行标準化有時也是必要的。

2) 資料驅動

采用資料驅動而非寫死的方式,許多政策變更和維護都會友善得多,大大增強系統的靈活性和擴充性。

舉例,假如使用者界面要通路外部資料源(檔案、XML 文檔、其他資料庫等),不妨把相應的連接配接和路徑資訊存儲在使用者界面支援表裡。還有,如果使用者界面執行工作流之類的任務(發送郵件、列印信箋、修改記錄狀态等),那麼産生工作流的資料也可以存放在資料庫裡。角色權限管理也可以通過資料驅動來完成。事實上,如果過程是資料驅動的,你就可以把相當大的責任推給使用者,由使用者來維護自己的工作流過程。

3) 考慮各種變化

在設計資料庫的時候考慮到哪些資料字段将來可能會發生變更。

舉例,姓氏就是如此(注意是西方人的姓氏,比如女性結婚後從夫姓等)。是以,在建立系統存儲客戶資訊時,在單獨的一個資料表裡存儲姓氏字段,而且還附加起始日和終止日等字段,這樣就可以跟蹤這一資料條目的變化。

字段設計原則

4) 每個表中都應該添加的3 個有用的字段

· dRecordCreationDate,在VB 下預設是Now(),而在SQL Server 下預設為GETDATE()

· sRecordCreator,在SQL Server 下預設為NOT NULL DEFAULT USER

· nRecordVersion,記錄的版本标記;有助于準确說明記錄中出現null 資料或者丢失資料的原因

5) 對位址和電話采用多個字段

描述街道位址就短短一行記錄是不夠的。Address_Line1、Address_Line2 和Address_Line3 可以提供更大的靈活性。還有,電話号碼和郵件位址最好擁有自己的資料表,其間具有自身的類型和标記類别。

6) 使用角色實體定義屬于某類别的列

在需要對屬于特定類别或者具有特定角色的事物做定義時,可以用角色實體來建立特定的時間關聯關系,進而可以實作自我文檔化。

舉例:用PERSON 實體和PERSON_TYPE 實體來描述人員。比方說,當John Smith, Engineer 提升為John Smith, Director 乃至最後爬到John Smith, CIO 的高位,而所有你要做的不過是改變兩個表PERSON 和PERSON_TYPE 之間關系的鍵值,同時增加一個日期/時間字段來知道變化是何時發生的。這樣,你的PERSON_TYPE 表就包含了所有PERSON 的可能類型,比如Associate、Engineer、Director、CIO 或者CEO 等。還有個替代辦法就是改變PERSON 記錄來反映新頭銜的變化,不過這樣一來在時間上無法跟蹤個人所處位置的具體時間。

7) 選擇數字類型和文本類型盡量充足

在SQL 中使用smallint 和tinyint 類型要特别小心。比如,假如想看看月銷售總額,總額字段類型是smallint,那麼,如果總額超過了$32,767 就不能進行計算操作了。

而ID 類型的文本字段,比如客戶ID 或定單号等等都應該設定得比一般想象更大。假設客戶ID 為10 位數長。那你應該把資料庫表字段的長度設為12 或者13 個字元長。但這額外占據的空間卻無需将來重構整個資料庫就可以實作資料庫規模的增長了。

8) 增加删除标記字段

在表中包含一個“删除标記”字段,這樣就可以把行标記為删除。在關系資料庫裡不要單獨删除某一行;最好采用清除資料程式而且要仔細維護索引整體性。

3. 選擇鍵和索引(資料庫邏輯設計)

鍵選擇原則:

1) 鍵設計4 原則

· 為關聯字段建立外鍵。

· 所有的鍵都必須唯一。

· 避免使用複合鍵。

· 外鍵總是關聯唯一的鍵字段。

2) 使用系統生成的主鍵

設計資料庫的時候采用系統生成的鍵作為主鍵,那麼實際控制了資料庫的索引完整性。這樣,資料庫和非人工機制就有效地控制了對存儲資料中每一行的通路。采用系統生成鍵作為主鍵還有一個優點:當擁有一緻的鍵結構時,找到邏輯缺陷很容易。

3) 不要用使用者的鍵(不讓主鍵具有可更新性)

在确定采用什麼字段作為表的鍵的時候,可一定要小心使用者将要編輯的字段。通常的情況下不要選擇使用者可編輯的字段作為鍵。

4) 可選鍵有時可做主鍵

把可選鍵進一步用做主鍵,可以擁有建立強大索引的能力。

索引使用原則:

索引是從資料庫中擷取資料的最高效方式之一。95%的資料庫性能問題都可以采用索引技術得到解決。

1)      邏輯主鍵使用唯一的成組索引,2)      對系統鍵(作為存儲過程)采用唯一的非成組索引,3)      對任何外鍵列采用非成組索引。考慮資料庫的空間有多大,4)      表如何進行通路,5)      還有這些通路是否主要用作讀寫。

6)      大多數資料庫都索引自動建立的主鍵字段,7)      但是可别忘了索引外鍵,8)      它們也是經常使用的鍵,9)      比如運作查詢顯示主表和所有關聯表的某條記錄就用得上。

10)      不11)      要索引memo/note 字段,12)      不13)      要索引大型字段(有很多字元),14)      這樣作會讓索引占用太多的存儲空間。

15)      不16)      要索引常用的小型表

不要為小型資料表設定任何鍵,假如它們經常有插入和删除操作就更别這樣作了。對這些插入和删除操作的索引維護可能比掃描表空間消耗更多的時間。

4. 資料完整性設計(資料庫邏輯設計)

1)      完整性實作機制:

實體完整性:主鍵

參照完整性:

父表中删除資料:級聯删除;受限删除;置空值

父表中插入資料:受限插入;遞歸插入

父表中更新資料:級聯更新;受限更新;置空值

DBMS對參照完整性可以有兩種方法實作:外鍵實作機制(限制規則)和觸發器實作機制

使用者定義完整性:

    NOT NULL;CHECK;觸發器

2) 用限制而非商務規則強制資料完整性

采用資料庫系統實作資料的完整性。這不但包括通過标準化實作的完整性而且還包括資料的功能性。在寫資料的時候還可以增加觸發器來保證資料的正确性。不要依賴于商務層保證資料完整性;它不能保證表之間(外鍵)的完整性是以不能強加于其他完整性規則之上。

3) 強制訓示完整性

在有害資料進入資料庫之前将其剔除。激活資料庫系統的訓示完整性特性。這樣可以保持資料的清潔而能迫使開發人員投入更多的時間處理錯誤條件。

4) 使用查找控制資料完整性

控制資料完整性的最佳方式就是限制使用者的選擇。隻要有可能都應該提供給使用者一個清晰的價值清單供其選擇。這樣将減少鍵入代碼的錯誤和誤解同時提供資料的一緻性。某些公共資料特别适合查找:國家代碼、狀态代碼等。

5) 采用視圖

為了在資料庫和應用程式代碼之間提供另一層抽象,可以為應用程式建立專門的視圖而不必非要應用程式直接通路資料表。這樣做還等于在處理資料庫變更時給你提供了更多的自由。

5. 其他設計技巧

1) 避免使用觸發器

觸發器的功能通常可以用其他方式實作。在調試程式時觸發器可能成為幹擾。假如你确實需要采用觸發器,你最好集中對它文檔化。

2) 使用常用英語(或者其他任何語言)而不要使用編碼

在建立下拉菜單、清單、報表時最好按照英語名排序。假如需要編碼,可以在編碼旁附上使用者知道的英語。

3) 儲存常用資訊

讓一個表專門存放一般資料庫資訊非常有用。在這個表裡存放資料庫目前版本、最近檢查/修複(對Access)、關聯設計文檔的名稱、客戶等資訊。這樣可以實作一種簡單機制跟蹤資料庫,當客戶抱怨他們的資料庫沒有達到希望的要求而與你聯系時,這樣做對非客戶機/伺服器環境特别有用。

4) 包含版本機制

在資料庫中引入版本控制機制來确定使用中的資料庫的版本。時間一長,使用者的需求總是會改變的。最終可能會要求修改資料庫結構。把版本資訊直接存放到資料庫中更為友善。

5) 編制文檔

對所有的快捷方式、命名規範、限制和函數都要編制文檔。

采用給表、列、觸發器等加注釋的資料庫工具。對開發、支援和跟蹤修改非常有用。

對資料庫文檔化,或者在資料庫自身的内部或者單獨建立文檔。這樣,當過了一年多時間後再回過頭來做第2 個版本,犯錯的機會将大大減少。

6) 測試、測試、反複測試

建立或者修訂資料庫之後,必須用使用者新輸入的資料測試資料字段。最重要的是,讓使用者進行測試并且同使用者一道保證選擇的資料類型滿足商業要求。測試需要在把新資料庫投入實際服務之前完成。

7) 檢查設計

在開發期間檢查資料庫設計的常用技術是通過其所支援的應用程式原型檢查資料庫。換句話說,針對每一種最終表達資料的原型應用,保證你檢查了資料模型并且檢視如何取出資料。

三、資料庫命名規範

1. 實體(表)的命名

1) 表以名詞或名詞短語命名,确定表名是采用複數還是單數形式,此外給表的别名定義簡單規則(比方說,如果表名是一個單詞,别名就取單詞的前4 個字母;如果表名是兩個單詞,就各取兩個單詞的前兩個字母組成4 個字母長的别名;如果表的名字由3 個單詞組成,從頭兩個單詞中各取一個然後從最後一個單詞中再取出兩個字母,結果還是組成4 字母長的别名,其餘依次類推)

對工作用表來說,表名可以加上字首WORK_ 後面附上采用該表的應用程式的名字。在命名過程當中,根據語義拼湊縮寫即可。注意,由于ORCLE會将字段名稱統一成大寫或者小寫中的一種,是以要求加上下劃線。

舉例:

定義的縮寫 Sales: Sal 銷售;

Order: Ord 訂單;

Detail: Dtl 明細;

則銷售訂單明細表命名為:Sal_Ord_Dtl;

2) 如果表或者是字段的名稱僅有一個單詞,那麼建議不使用縮寫,而是用完整的單詞。

舉例:

定義的縮寫 Material Ma 物品;

物品表名為:Material, 而不是 Ma.

但是字段物品編碼則是:Ma_ID;而不是Material_ID

3) 所有的存儲值清單的表前面加上字首Z

目的是将這些值清單類排序在資料庫最後。

4) 所有的備援類的命名(主要是累計表)前面加上字首X

備援類是為了提高資料庫效率,非規範化資料庫的時候加入的字段或者表

5) 關聯類通過用下劃線連接配接兩個基本類之後,再加字首R的方式命名,後面按照字母順序羅列兩個表名或者表名的縮寫。

關聯表用于儲存多對多關系。

如果被關聯的表名大于10個字母,必須将原來的表名的進行縮寫。如果沒有其他原因,建議都使用縮寫。

舉例:表Object與自身存在多對多的關系,則儲存多對多關系的表命名為:R_Object;

表 Depart和Employee;存在多對多的關系;則關聯表命名為R_Dept_Emp

2. 屬性(列)的命名

1) 采用有意義的列名,表内的列要針對鍵采用一整套設計規則。每一個表都将有一個自動ID作為主健,邏輯上的主健作為第一組候選主健來定義,如果是資料庫自動生成的編碼,統一命名為:ID;如果是自定義的邏輯上的編碼則用縮寫加“ID”的方法命名。如果鍵是數字類型,你可以用_NO 作為字尾;如果是字元類型則可以采用_CODE 字尾。對列名應該采用标準的字首和字尾。

舉例:銷售訂單的編号字段命名:Sal_Ord_ID;如果還存在一個資料庫生成的自動編号,則命名為:ID。

2) 所有的屬性加上有關類型的字尾,注意,如果還需要其它的字尾,都放在類型字尾之前。

注: 資料類型是文本的字段,類型字尾TX可以不寫。有些類型比較明顯的字段,可以不寫類型字尾。

3) 采用字首命名

給每個表的列名都采用統一的字首,那麼在編寫SQL表達式的時候會得到大大的簡化。這樣做也确實有缺點,比如破壞了自動表連接配接工具的作用,後者把公共列名同某些資料庫聯系起來。

3. 視圖的命名

1) 視圖以V作為字首,其他命名規則和表的命名類似;

2) 命名應盡量展現各視圖的功能。

4. 觸發器的命名

觸發器以TR作為字首,觸發器名為相應的表名加上字尾,Insert觸發器加'_I',Delete觸發器加'_D',Update觸發器加'_U',如:TR_Customer_I,TR_Customer_D,TR_Customer_U。

5. 存儲過程名

存儲過程應以'UP_'開頭,和系統的存儲過程區分,後續部分主要以動賓形式構成,并用下劃線分割各個組成部分。如增加代理商的帳戶的存儲過程為'UP_Ins_Agent_Account'。

6. 變量名

變量名采用小寫,若屬于詞組形式,用下劃線分隔每個單詞,如@my_err_no。

7. 命名中其他注意事項

1)  以上命名都不得超過30個字元的系統限制。變量名的長度限制為29(不包括辨別字元@)。

2)  資料對象、變量的命名都采用英文字元,禁止使用中文命名。絕對不要在對象名的字元之間留白格。

3) 小心保留詞,要保證你的字段名沒有和保留詞、資料庫系統或者常用通路方法沖突

17)      保持字段名18)      和類型的一緻性,19)      在命名20)      字段并為其指21)      定資料類型的時候一定要保證一緻性。假如資料類型在一個表裡是整數,22)      那在另一個表裡可就别變成字元型了。

資料庫設計規範化的五個要求

2009-05-19 14:05:15 來源:作者不詳 浏覽次數:513  [收藏此頁]  複制 分享到i貼吧

-

通常情況下,可以從兩個方面來判斷資料庫是否設計的比較規範。一是看看是否擁有大量的窄表,二是寬表的數量是否足夠的少。若符合這兩個條件,則可以說明這個資料庫的規範化水準還是比較高的。當然這是兩個泛泛而談的名額。為了達到資料庫設計規範化的要求,一般來說,需要符合以下五個要求。

  

要求一:表中應該避免可為空的列

  

雖然表中允許空列,但是,空字段是一種比較特殊的資料類型。資料庫在處理的時候,需要進行特殊的處理。如此的話,就會增加資料庫處理記錄的複雜性。當表中有比較多的空字段時,在同等條件下,資料庫處理的性能會降低許多。

  

是以,雖然在資料庫表設計的時候,允許表中具有空字段,但是,我們應該盡量避免。若确實需要的話,我們可以通過一些折中的方式,來處理這些空字段,讓其對資料庫性能的影響降低到最少。

  

一是通過設定預設值的形式,來避免空字段的産生。如在一個人事管理系統中,有時候身份證号碼字段可能允許為空。因為不是每個人都可以記住自己的身份證号碼。而在員工報到的時候,可能身份證沒有帶在身邊。是以,身份證号碼字段往往不能及時提供。為此,身份證号碼字段可以允許為空,以滿足這些特殊情況的需要。但是,在資料庫設計的時候,則可以做一些處理。如當使用者沒有輸入内容的時候,則把這個字段的預設值設定為0或者為N/A。以避免空字段的産生。

  

二是若一張表中,允許為空的列比較多,接近表全部列數的三分之一。而且,這些列在大部分情況下,都是可有可無的。若資料庫管理者遇到這種情況,筆者建議另外建立一張副表,以儲存這些列。然後通過關鍵字把主表跟這張副表關聯起來。将資料存儲在兩個獨立的表中使得主表的設計更為簡單,同時也能夠滿足存儲空值資訊的需要。

  

要求二:表不應該有重複的值或者列

  

如現在有一個進銷存管理系統,這個系統中有一張産品基本資訊表中U飧霾房⒂惺焙蚩梢允且桓鋈送瓿桑惺焙蛴中枰喔鋈撕獻鞑拍芄煌瓿傘K裕诓坊拘畔⒈聿房⒄哒飧鲎侄沃校惺焙蚩贍苄枰钊攵喔隹⒄叩拿幀?BR>  如進銷存管理中,還需要對客戶的聯系人進行管理。有時候,企業可能隻知道客戶一個采購員的姓名。但是在必要的情況下,企業需要對客戶的采購代表、倉庫人員、财務人員共同進行管理。因為在訂單上,可能需要填入采購代表的名字;可是在出貨單上,則需要填入倉庫管理人員的名字等等。

  

為了解決這個問題,有多種實作方式。但是,若設計不合理的話在,則會導緻重複的值或者列。如我們也可以這麼設計,把客戶資訊、聯系人都放入同一張表中。為了解決多個聯系人的問題,可以設定第一聯系人、第一聯系人電話、第二聯系人、第二聯系人電話等等。若還有第三聯系人、第四聯系人等等,則往往還需要加入更多的字段。

  

可是這麼設計的話,會産生一系列的問題。如客戶的采購員流動性比較大,在一年内換了六個采購員。此時,在系統中該如何管理呢?難道就建立六個聯系人字段?這不但會導緻空字段的增加,還需要頻繁的更改資料庫表結構。明顯,這麼做是不合理的。也有人說,可以直接修改采購員的名字呀。可是這麼處理的話,會把原先采購訂單上采購員的名字也改變了。因為采購單上客戶采購員資訊在資料庫中存儲的不是采購員的名字,而隻是采購員對應的一個編号。在編号不改而名字改變了的情況下,采購訂單上顯示的就是更改後的名字。這不利于時候的追蹤。

  

是以,在資料庫設計的時候要盡量避免這種重複的值或者列的産生。筆者建議,若資料庫管理者遇到這種情況,可以改變一下政策。如把客戶聯系人另外設定一張表。然後通過客戶ID把供應商資訊表跟客戶聯系人資訊表連接配接起來。也就是說,盡量将重複的值放置到一張獨立的表中進行管理。然後通過視圖或者其他手段把這些獨立的表聯系起來。

  

要求三:表中記錄應該有一個唯一的辨別符

在資料庫表設計的時候,資料庫管理者應該養成一個好習慣,用一個ID号來

唯一的辨別行記錄,而不要通過名字、編号等字段來對紀錄進行區分。每個表都應該有一個ID列,任何兩個記錄都不可以共享同一個ID值。另外,這個ID值最好有資料庫來進行自動管理,而不要把這個任務給前台應用程式。否則的話,很容易産生ID值不統一的情況。

  

另外,在資料庫設計的時候,最好還能夠加入行号。如在銷售訂單管理中,ID号是使用者不能夠維護的。但是,行号使用者就可以維護。如在銷售訂單的行中,使用者可以通過調整行号的大小來對訂單行進行排序。通常情況下,ID列是以1為機關遞進的。但是,行号就要以10為機關累進。如此,正常情況下,行号就以10、20、30依次擴充下去。若此時使用者需要把行号為30的紀錄調到第一行顯示。此時,使用者在不能夠更改ID列的情況下,可以更改行号來實作。如可以把行号改為1,在排序時就可以按行号來進行排序。如此的話,原來行号為30的紀錄現在行号變為了1,就可以在第一行中顯示。這是在實際應用程式設計中對ID列的一個有效補充。這個内容在教科書上是沒有的。需要在實際應用程式設計中,才會掌握到這個技巧。

  

要求四:資料庫對象要有統一的字首名

  

一個比較複雜的應用系統,其對應的資料庫表往往以千計。若讓資料庫管理者看到對象名就了解這個資料庫對象所起的作用,恐怕會比較困難。而且在資料庫對象引用的時候,資料庫管理者也會為不能迅速找到所需要的資料庫對象而頭疼。

  

為此,筆者建立,在開發資料庫之前,最好能夠花一定的時間,去制定一個資料庫對象的字首命名規範。如筆者在資料庫設計時,喜歡跟前台應用程式協商,确定合理的命名規範。筆者最常用的是根據前台應用程式的子產品來定義背景資料庫對象字首名。如跟物料管理子產品相關的表可以用M為字首;而以訂單管理相關的,則可以利用C作為字首。具體采用什麼字首可以以使用者的愛好而定義。但是,需要注意的是,這個命名規範應該在資料庫管理者與前台應用程式開發者之間達成共識,并且嚴格按照這個命名規範來定義對象名。

  

其次,表、視圖、函數等最好也有統一的字首。如視圖可以用V為字首,而函數則可以利用F為字首。如此資料庫管理者無論是在日常管理還是對象引用的時候,都能夠在最短的時間内找到自己所需要的對象。

  

要求五:盡量隻存儲單一實體類型的資料

  

這裡将的實體類型跟資料類型不是一回事,要注意區分。這裡講的實體類型是指所需要描述對象的本身。筆者舉一個例子,估計大家就可以明白其中的内容了。如現在有一個圖書館裡系統,有圖書基本資訊、作者資訊兩個實體對象。若使用者要把這兩個實體對象資訊放在同一張表中也是可以的。如可以把表設計成圖書名字、圖書作者等等。可是如此設計的話,會給後續的維護帶來不少的麻煩。

  

如當後續有圖書出版時,則需要為每次出版的圖書增加作者資訊,這無疑會增加額外的存儲空間,也會增加記錄的長度。而且若作者的情況有所改變,如住址改變了以後,則還需要去更改每本書的記錄。同時,若這個作者的圖書從資料庫中全部删除之後,這個作者的資訊也就蕩然無存了。很明顯,這不符合資料庫設計規範化的需求。

  

遇到這種情況時,筆者建議可以把上面這張表分解成三種獨立的表,分别為圖書基本資訊表、作者基本資訊表、圖書與作者對應表等等。如此設計以後,以上遇到的所有問題就都引刃而解了。

  

以上五條是在資料庫設計時達到規範化水準的基本要求。除了這些另外還有很多細節方面的要求,如資料類型、存儲過程等等。而且,資料庫規範往往沒有技術方面的嚴格限制,主要依靠資料庫管理者日常工作經驗的累積