[轉(zhuǎn)]關(guān)系型數(shù)據(jù)庫設(shè)計

數(shù)據(jù)庫設(shè)計,一個軟件項目成功的基石。很多從業(yè)人員都認(rèn)為,數(shù)據(jù)庫設(shè)計其實不那么重要。現(xiàn)實中的情景也相當(dāng)雷同,開發(fā)人員的數(shù)量是數(shù)據(jù)庫設(shè)計人員的數(shù)倍。多數(shù)人使用數(shù)據(jù)庫中的一部分,所以也會把數(shù)據(jù)庫設(shè)計想的如此簡單。其實不然,數(shù)據(jù)庫設(shè)計也是門學(xué)問。

從筆者的經(jīng)歷看來,筆者更zan成在項目早期由開發(fā)者進行數(shù)據(jù)庫設(shè)計(后期調(diào)優(yōu)需要DBA)。根據(jù)筆者的項目經(jīng)驗,一個精通OOP和ORM的開發(fā)者,設(shè)計的數(shù)據(jù)庫往往更為合理,更能適應(yīng)需求的變化,如果追其原因,筆者個人猜測是因為數(shù)據(jù)庫的規(guī)范化,與OO的部分思想雷同(如內(nèi)聚)。而DBA,設(shè)計的數(shù)據(jù)庫的優(yōu)勢是能將DBMS的能力發(fā)揮到極致,能夠使用SQL和DBMS實現(xiàn)很多程序?qū)崿F(xiàn)的邏輯,與開發(fā)者相比,DBA優(yōu)化過的數(shù)據(jù)庫更為高效和穩(wěn)定。如標(biāo)題所示,本文旨在分享一名開發(fā)者的數(shù)據(jù)庫設(shè)計經(jīng)驗,并不涉及復(fù)雜的SQL語句或DBMS使用,因此也不會局限到某種DBMS產(chǎn)品上。真切地希望這篇文章對開發(fā)者能有所幫助,也希望讀者能幫助筆者查漏補缺。

一 Codd的RDBMS12法則——RDBMS的起源

Edgar Frank Codd(埃德加·弗蘭克·科德)被譽為“關(guān)系數(shù)據(jù)庫之父”,并因為在數(shù)據(jù)庫管理系統(tǒng)的理論和實踐方面的杰出貢獻于1981年獲圖靈獎。在1985年,Codd 博士發(fā)布了12條規(guī)則,這些規(guī)則簡明的定義出一個關(guān)系型數(shù)據(jù)庫的理念,它們被作為所有關(guān)系數(shù)據(jù)庫系統(tǒng)的設(shè)計指導(dǎo)性方針。

1.信息法則 關(guān)系數(shù)據(jù)庫中的所有信息都用唯一的一種方式表示——表中的值。

2.保證訪問法則 依靠表名、主鍵值和列名的組合,保證能訪問每個數(shù)據(jù)項。

3.空值的系統(tǒng)化處理 支持空值(NULL),以系統(tǒng)化的方式處理空值,空值不依賴于數(shù)據(jù)類型。

4.基于關(guān)系模型的動態(tài)聯(lián)機目錄 數(shù)據(jù)庫的描述應(yīng)該是自描述的,在邏輯級別上和普通數(shù)據(jù)采用同樣的表示方式,即數(shù)據(jù)庫必須含有描述該數(shù)據(jù)庫結(jié)構(gòu)的系統(tǒng)表或者數(shù)據(jù)庫描述信息應(yīng)該包含在用戶可以訪問的表中。

5.統(tǒng)一的數(shù)據(jù)子語言法則 一個關(guān)系數(shù)據(jù)庫系統(tǒng)可以支持幾種語言和多種終端使用方式,但必須至少有一種語言,它的語句能夠一某種定義良好的語法表示為字符串,并能全面地支持以下所有規(guī)則:數(shù)據(jù)定義、視圖定義、數(shù)據(jù)操作、約束、授權(quán)以及事務(wù)。(這種語言就是SQL)

6.視圖更新法則 所有理論上可以更新的視圖也可以由系統(tǒng)更新。

7.高級的插入、更新和刪除操作 把一個基礎(chǔ)關(guān)系或派生關(guān)系作為單個操作對象處理的能力不僅適應(yīng)于數(shù)據(jù)的檢索,還適用于數(shù)據(jù)的插入、修改個刪除,即在插入、修改和刪除操作中數(shù)據(jù)行被視作集合。

8.數(shù)據(jù)的物理獨立性 不管數(shù)據(jù)庫的數(shù)據(jù)在存儲表示或訪問方式上怎么變化,應(yīng)用程序和終端活動都保持著邏輯上的不變性。

9.數(shù)據(jù)的邏輯獨立性 當(dāng)對表做了理論上不會損害信息的改變時,應(yīng)用程序和終端活動都會保持邏輯上的不變性。

10.數(shù)據(jù)完整性的獨立性 專用于某個關(guān)系型數(shù)據(jù)庫的完整性約束必須可以用關(guān)系數(shù)據(jù)庫子語言定義,而且可以存儲在數(shù)據(jù)目錄中,而非程序中。

11.分布獨立性 不管數(shù)據(jù)在物理是否分布式存儲,或者任何時候改變分布策略,RDBMS的數(shù)據(jù)操縱子語言必須能使應(yīng)用程序和終端活動保持邏輯上的不變性。

12.非破壞性法則 如果一個關(guān)系數(shù)據(jù)庫系統(tǒng)支持某種低級(一次處理單個記錄)語言,那么這個低級語言不能違反或繞過更高級語言(一次處理多個記錄)規(guī)定的完整性法則或約束,即用戶不能以任何方式違反數(shù)據(jù)庫的約束。

二 關(guān)系型數(shù)據(jù)庫設(shè)計階段

(一)規(guī)劃階段

規(guī)劃階段的主要工作是對數(shù)據(jù)庫的必要性和可行性進行分析。確定是否需要使用數(shù)據(jù)庫,使用哪種類型的數(shù)據(jù)庫,使用哪個數(shù)據(jù)庫產(chǎn)品。

(二)概念階段

概念階段的主要工作是收集并分析需求。識別需求,主要是識別數(shù)據(jù)實體和業(yè)務(wù)規(guī)則。對于一個系統(tǒng)來說,數(shù)據(jù)庫的主要包括業(yè)務(wù)數(shù)據(jù)和非業(yè)務(wù)數(shù)據(jù),而業(yè)務(wù)數(shù)據(jù)的定義,則依賴于在此階段對用戶需求的分析。需要盡量識別業(yè)務(wù)實體和業(yè)務(wù)規(guī)則,對系統(tǒng)的整體有初步的認(rèn)識,并理解數(shù)據(jù)的流動過程。理論上,該階段將參考或產(chǎn)出多種文檔,比如“用例圖”,“數(shù)據(jù)流圖”以及其他一些項目文檔。如果能夠在該階段產(chǎn)出這些成果,無疑將會對后期進行莫大的幫助。當(dāng)然,很多文檔已超出數(shù)據(jù)庫設(shè)計者的考慮范圍。而且,如果你并不精通該領(lǐng)域以及用戶的業(yè)務(wù),那么請放棄自己獨立完成用戶需求分析的想法。用戶并不是技術(shù)專家,而當(dāng)你自身不能扮演“業(yè)務(wù)顧問”的角色時,請你選擇與項目組的相關(guān)人員合作,或者將其視為風(fēng)險呈報給PM。再次強調(diào),大多數(shù)情況,用戶只是行業(yè)從業(yè)者,而非職業(yè)技術(shù)人員,我們僅僅從用戶那里收集需求,而非依賴于用戶的知識。

記錄用戶需求時,可以使用一些技巧,當(dāng)然這部分內(nèi)容有些可能會超出數(shù)據(jù)庫設(shè)計人員的職責(zé):

努力維護一系列包含了系統(tǒng)設(shè)計和規(guī)格說明信息的文檔,如會議記錄、訪談記錄、關(guān)鍵用戶期望、功能規(guī)格、技術(shù)規(guī)格、測試規(guī)格等。

頻繁與干系人溝通并收集反饋。

標(biāo)記出你自己添加的,不屬于客戶要求的,未決內(nèi)容。

與所有關(guān)鍵干系人盡快確認(rèn)項目范圍,并力求凍結(jié)需求。

此外,必須嚴(yán)謹(jǐn)處理業(yè)務(wù)規(guī)則,并詳細記錄。在之后的階段,將會根據(jù)這些業(yè)務(wù)規(guī)則進行設(shè)計。

當(dāng)該階段結(jié)束時,你應(yīng)該能夠回答以下問題:

需要哪些數(shù)據(jù)?

數(shù)據(jù)該被怎樣使用?

哪些規(guī)則控制著數(shù)據(jù)的使用?

誰會使用何種數(shù)據(jù)?

客戶想在核心功能界面或者報表上看到哪些內(nèi)容?

數(shù)據(jù)現(xiàn)在在哪里?

數(shù)據(jù)是否與其他系統(tǒng)有交互、集成或同步?

主題數(shù)據(jù)有哪些?

核心數(shù)據(jù)價值幾何,對可靠性的要求程度?

并且得到如下信息:

實體和關(guān)系

屬性和域

可以在數(shù)據(jù)庫中強制執(zhí)行的業(yè)務(wù)規(guī)則

需要使用數(shù)據(jù)庫的業(yè)務(wù)過程

(三)邏輯階段

邏輯階段的主要工作是繪制E-R圖,或者說是建模。建模工具很多,有不同的圖形表示方法和軟件。這些工具和軟件的使用并非關(guān)鍵,筆者也不建議讀者花大量時間在建模方法的選擇上。對于大多數(shù)應(yīng)用來說,E-R圖足以描述實體間的關(guān)系。建模關(guān)鍵是思想而不是工具,軟件只是起到輔助作用,識別實體關(guān)系才是本階段的重點。

除了實體關(guān)系,我們還應(yīng)該考慮屬性的域(值類型、范圍、約束)

(四)實現(xiàn)階段

實現(xiàn)階段主要針對選擇的RDBMS定義E-R圖對應(yīng)的表,考慮屬性類型和范圍以及約束。

(五)物理階段

物理階段是一個驗證并調(diào)優(yōu)的階段,是在實際物理設(shè)備上部署數(shù)據(jù)庫,并進行測試和調(diào)優(yōu)。

三 設(shè)計原則

(一)降低對數(shù)據(jù)庫功能的依賴

功能應(yīng)該由程序?qū)崿F(xiàn),而非DB實現(xiàn)。原因在于,如果功能由DB實現(xiàn)時,一旦更換的DBMS不如之前的系統(tǒng)強大,不能實現(xiàn)某些功能,這時我們將不得不去修改代碼。所以,為了杜絕此類情況的發(fā)生,功能應(yīng)該有程序?qū)崿F(xiàn),數(shù)據(jù)庫僅僅負責(zé)數(shù)據(jù)的存儲,以達到最低的耦合。

(二)定義實體關(guān)系的原則

當(dāng)定義一個實體與其他實體之間的關(guān)系時,需要考量如下:

牽涉到的實體 識別出關(guān)系所涉及的所有實體。

所有權(quán) 考慮一個實體“擁有”另一個實體的情況。

基數(shù) 考量一個實體的實例和另一個實體實例關(guān)聯(lián)的數(shù)量。

關(guān)系與表數(shù)量

描述1:1關(guān)系最少需要1張表。

描述1:n關(guān)系最少需要2張表。

描述n:n關(guān)系最少需要3張表。

(三)列意味著唯一的值

如果表示坐標(biāo)(0,0),應(yīng)該使用兩列表示,而不是將“0,0”放在1個列中。

(四)列的順序

列的順序?qū)τ诒韥碚f無關(guān)緊要,但是從習(xí)慣上來說,采用“主鍵+外鍵+實體數(shù)據(jù)+非實體數(shù)據(jù)”這樣的順序?qū)α羞M行排序顯然能得到比較好的可讀性。

(五)定義主鍵和外鍵

數(shù)據(jù)表必須定義主鍵和外鍵(如果有外鍵)。定義主鍵和外鍵不僅是RDBMS的要求,同時也是開發(fā)的要求。幾乎所有的代碼生成器都需要這些信息來生成常用方法的代碼(包括SQL文和引用),所以,定義主鍵和外鍵在開發(fā)階段是必須的。之所以說在開發(fā)階段是必須的是因為,有不少團隊出于性能考慮會在進行大量測試后,在保證參照完整性不會出現(xiàn)大的缺陷后,會刪除掉DB的所有外鍵,以達到最優(yōu)性能。筆者認(rèn)為,在性能沒有出現(xiàn)問題時應(yīng)該保留外鍵,而即便性能真的出現(xiàn)問題,也應(yīng)該對SQL文進行優(yōu)化,而非放棄外鍵約束。

(六)選擇鍵

1 人工鍵與自然鍵

人工健——實體的非自然屬性,根據(jù)需要由人強加的,如GUID,其對實體毫無意義;自然健——實體的自然屬性,如身份證編號。

人工鍵的好處:

鍵值永遠不變

永遠是單列存儲

人工鍵的缺點:

因為人工鍵是沒有實際意義的唯一值,所以不能通過人工鍵來避免重復(fù)行。

筆者建議全部使用人工鍵。原因如下:

在設(shè)計階段我們無法預(yù)測到代碼真正需要的值,所以干脆放棄猜測鍵,而使用人工鍵。

人工鍵復(fù)雜處理實體關(guān)系,而不負責(zé)任何屬性描述,這樣的設(shè)計使得實體關(guān)系與實體內(nèi)容得到高度解耦,這樣做的設(shè)計思路更加清晰。

筆者的另一個建議是——每張表都需要有一個對用戶而言有意義的自然鍵,在特殊情況下也許找不到這樣一個項,此時可以使用復(fù)合鍵。這個鍵我在程序中并不會使用其作為唯一標(biāo)識,但是卻可以在對數(shù)據(jù)庫直接進行查詢時使用。

使用人工鍵的另一根弊端,主要源自對查詢性能的考量,因此選擇人工鍵的形式(列的類型)很重要:

自增值類型 由于類型輕巧查詢效率更好,但取值有限。

GUID 查詢效率不如值類型,但是取值無限,且對開發(fā)人員更加親切。

2 智能健與非智能鍵

智能鍵——鍵值包含額外信息,其根據(jù)某種約定好的編碼規(guī)范進行編碼,從鍵值本身可以獲取某些信息;非智能鍵,單純的無意義鍵值,如自增的數(shù)字或GUID。

智能鍵是一把雙刃劍,開發(fā)人員偏愛這種包含信息的鍵值,程序盼望著其中潛在的數(shù)據(jù);數(shù)據(jù)庫管理員或者設(shè)計者則討厭這種智能鍵,原因也是很顯然的,智能鍵對數(shù)據(jù)庫是潛在的風(fēng)險。前面提到,數(shù)據(jù)庫設(shè)計的原則之一是不要把具有獨立意義的值的組合實現(xiàn)到一個單一的列中,應(yīng)該使用多個獨立的列。數(shù)據(jù)庫設(shè)計者,更希望開發(fā)人員通過拼接多個列來得到智能鍵,即以復(fù)合主鍵的形式給開發(fā)人員使用,而不是將一個列的值分解后使用。開發(fā)人員應(yīng)該接受這種數(shù)據(jù)庫設(shè)計,但是很多開發(fā)者卻想不明白兩者的優(yōu)略。筆者認(rèn)為,使用單一列實現(xiàn)智能鍵存在這樣一個風(fēng)險,就是我們可能在設(shè)計階段無法預(yù)期到編碼規(guī)則可能會在后期發(fā)生變化。比如,構(gòu)成智能鍵的局部鍵的值用完而引起規(guī)則變化或者長度變化,這種編碼規(guī)則的變化對于程序的有效性驗證與智能鍵解析是破壞性的,這是系統(tǒng)運維人員最不希望看到的。所以筆者建議如果需要智能鍵,請在業(yè)務(wù)邏輯層封裝(使用只讀屬性),不要再持久化層實現(xiàn),以避免上述問題。

(七)是否允許NULL

關(guān)于NULL我們需要了解它的幾個特性:

任何值和NULL拼接后都為NULL。

所有與NULL進行的數(shù)學(xué)操作都返回NULL。

引入NULL后,邏輯不易處理。

那么我們是否應(yīng)該允許列為空呢?筆者認(rèn)為這個問題的答案受到我們的開發(fā)語言的影響。以C#為例,因為引入了可空類型來處理數(shù)據(jù)庫值類型為NULL的情形,所以是否允許為空對開發(fā)者來說意義并不大。但有一點必須注意,就是驗證非空必須要在程序集進行處理,而不該依賴于DBMS的非空約束,必須確保完整數(shù)據(jù)(所有必須的屬性均被賦值)到達DB(所謂的“安全區(qū)”,我們必須定義在多層系統(tǒng)中那些區(qū)域得到的數(shù)據(jù)是安全而純凈的)。

(八)屬性切割

一種錯誤想法是,屬性與列是1:1的關(guān)系。對于開發(fā)者,我們公開屬性而非字段。舉個例子來說,對于實體“員工”有“名字”這一屬性,“名字”可以再被分解為“姓”和“名”,對于開發(fā)人員來說,顯然第二種數(shù)據(jù)結(jié)構(gòu)更受青睞(“姓”和“名”作為兩個字段)。所以,在設(shè)計時我們也應(yīng)該根據(jù)需要考慮是否切割屬性。

(九)規(guī)范化——范式

當(dāng)筆者還在大學(xué)時,范式是學(xué)習(xí)關(guān)系型數(shù)據(jù)庫時最頭疼的問題。我想也許會有讀者仍然不理解范式的價值,簡單來說——范式將幫助我們來保證數(shù)據(jù)的有效性和完整性。規(guī)范化的目的如下:

消滅重復(fù)數(shù)據(jù)。

避免編寫不必要的,用來使重復(fù)數(shù)據(jù)同步的代碼。

保持表的瘦身,以及減從一張表中讀取數(shù)據(jù)時需要進行的讀操作數(shù)量。

最大化聚集索引的使用,從而可以進行更優(yōu)化的數(shù)據(jù)訪問和聯(lián)結(jié)。

減少每張表使用的索引數(shù)量,因為維護索引的成本很高。

規(guī)范化旨在——挑出復(fù)雜的實體,從中抽取出簡單的實體。這個過程一直持續(xù)下去,直到數(shù)據(jù)庫中每個表都只代表一件事物,并且表中每個描述的都是這件事物為止。

1 規(guī)范化實體和屬性(去除冗余)

1NF:每個屬性都只應(yīng)表示一個單一的值,而非多個值。

需要考慮幾點:

屬性是原子性的 需要考慮熟悉是否分解的足夠徹底,使得每個屬性都表示一個單一的值。(和“(三)列意味著唯一的值”描述的原則相同。)分解原則為——當(dāng)你需要分開處理每個部分時才分解值,并且分解到足夠用就行。(即使當(dāng)前不需要徹底分解屬性,也應(yīng)該考慮未來可能的需求變更。)

屬性的所有實例必須包含相同數(shù)量的值 實體有固定數(shù)量的屬性(表有固定數(shù)量的列)。設(shè)計實體時,要讓每個屬性只有固定數(shù)量的值與其相關(guān)聯(lián)。

實體中出現(xiàn)的所有實體類型都必須不同

當(dāng)前設(shè)計不符合1NF的“臭味”:

包含分隔符類字符的字符串?dāng)?shù)據(jù)。

名字尾端有數(shù)字的屬性。

沒有定義鍵或鍵定義不好的表。

2 屬性間的關(guān)系(去除冗余)

2NF-實體必須符合1NF,每個屬性描述的東西都必須針對整個鍵(可以理解為oop中類型屬性的內(nèi)聚性)。

當(dāng)前設(shè)計不符合2NF的“臭味”:

重復(fù)的鍵屬性名字前綴(設(shè)計之外的數(shù)據(jù)冗余) 表明這些值可能描述了某些額外的實體。

有重復(fù)的數(shù)據(jù)組(設(shè)計之外的數(shù)據(jù)冗余) 這標(biāo)志著屬性間有函數(shù)依賴型。

沒有外鍵的復(fù)合主鍵 這標(biāo)志著鍵中的鍵值可能標(biāo)識了多種事物,而不是一種事物。

3NF-實體必須符合2NF,非鍵屬性不能描述其他非鍵屬性。(與2NF不同,3NF處理的是非鍵屬性和非鍵屬性之間的關(guān)系,而不是和鍵屬性之間的關(guān)系。

當(dāng)前設(shè)計不符合3NF的“臭味”:

多個屬性有同樣的前綴。

重復(fù)的數(shù)據(jù)組。

匯總的數(shù)據(jù),所引用的數(shù)據(jù)在一個完全不同的實體中。(有些人傾向于使用視圖,我更傾向于使用對象集合,即由程序來完成。)

BCNF-實體滿足第一范式,所有屬性完全依賴于某個鍵,如果所有的判定都是一個鍵,則實體滿足BCNF。(BCNF簡單地擴展了以前的范式,它說的是:一個實體可能有若干個鍵,所有屬性都必須依賴于這些鍵中的一個,也可以理解為“每個鍵必須唯一標(biāo)識實體,每個非鍵熟悉必須描述實體。”

3 去除實體組合鍵中的冗余

4NF-實體必須滿足BCNF,在一個屬性與實體的鍵之間,多值依賴(一條記錄在整個表的唯一性由多個值組合起來決定的)不能超過一個。

當(dāng)前設(shè)計不符合4NF的“臭味”:

三元關(guān)系(實體:實體:實體)。

潛伏的多值屬性。(如多個手機號。)

臨時數(shù)據(jù)或歷史值。(需要將歷史數(shù)據(jù)的主體提出,否則將存在大量冗余。)

4 盡量將所有關(guān)系分解為二元關(guān)系

5NF-實體必須滿足4NF,當(dāng)分解的信息無損的時候,確保所有關(guān)系都被分解為二元關(guān)系。

5NF保證在第四范式中存在的任何可以分解為實體的三元關(guān)系都被分解。有的三元關(guān)系可以在不丟失信息的前提下被分解為二元關(guān)系,當(dāng)分解為兩個二元關(guān)系的過程要丟失信息時,關(guān)系被宣稱為處于第四范式中。所以,第五范式建議是,最好把現(xiàn)有的三元關(guān)系都分解為3個二元關(guān)系。

需要注意的是,規(guī)范化的結(jié)果可能是更多的表,更復(fù)雜的查詢。因此,處理到何種程度,取決于性能和數(shù)據(jù)架構(gòu)的多方考量。建議規(guī)范化到第四范式,原因是5NF的判斷太過隱晦。例如:表X(老師,學(xué)生,課程)是一個三元關(guān)系,可以分解為表A(老師,學(xué)生),表B(學(xué)生,課程),表C(老師,課程)。表X表示某個老師是上某個學(xué)生的某個課程的老師;表A表示老師教學(xué)生;表B表示學(xué)生上課;表C表示老師教課。單獨看是無法發(fā)現(xiàn)問題的,但是從數(shù)據(jù)出發(fā),”表X=表A+表B+表C”并不一定成立,即不能通過連接構(gòu)建分解前的數(shù)據(jù)。因為可能有多種組合,喪失了表X反饋出的業(yè)務(wù)規(guī)則。這種現(xiàn)象,容易在設(shè)計階段被忽略,但好在在開放階段會被顯現(xiàn),而且并不經(jīng)常發(fā)生。

推薦做法:

盡可能地遵守上述規(guī)范化原則。

所有屬性描述的都應(yīng)該是體現(xiàn)被建模實體的本質(zhì)的內(nèi)容。

至少必須有一個鍵,它唯一地標(biāo)識和描述了所建實體的本質(zhì)。

主鍵要謹(jǐn)慎選擇。

在邏輯階段能做多少規(guī)范化就做多少(性能不是邏輯階段考慮的范疇)。

(十)選擇數(shù)據(jù)類型(MS SQL 2008)

MS SQL的常用類型:

MS SQL中不在支持的或糟糕的類型選擇

image:被varbinary(max)取代。

text和ntext:被varchar(max)和nvarchar(max)取代。

money和smallmoney:開發(fā)過程中不好用,建議使用decimal。

常用類型選擇:

類型選擇的最基本規(guī)則是選擇滿足需要的最輕的類型,因為這樣查詢更快。


(十一)優(yōu)化并行

設(shè)計DB時就應(yīng)該考慮到對并行進行優(yōu)化,比如,MS SQL中的timestamp類型就是極好的選擇。

四 命名規(guī)則

表——“模塊名_表名”。表名最好不要用復(fù)數(shù),原因是在使用ORM框架開發(fā)時,代碼生成器根據(jù)DB生成類定義,表生成了某個實例的類型定義,而不是實例集合。表名不要太長。原因之一,某些軟件對表名最大長度有限制;原因之二,使用代碼生成器往往會根據(jù)表名生產(chǎn)類型名稱,之后懶人會直接使用這一名稱,如果將太長的名稱跨網(wǎng)絡(luò)邊界顯然不是明智之舉。

字段——bool類型用“Is”、“Can”、“Has”等表示;日期類型命名必須包含“Date”;時間類型必須包含“Time”。

存儲過程——使用“proc_”前綴。

視圖——使用“view_”前綴。

觸發(fā)器——使用“trig_”前綴。

出自:

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

推薦閱讀更多精彩內(nèi)容