自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

寫給開發(fā)者看的關(guān)系型數(shù)據(jù)庫(kù)設(shè)計(jì)

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

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

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

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

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

  1. 信息法則 關(guān)系數(shù)據(jù)庫(kù)中的所有信息都用唯一的一種方式表示——表中的值。
  2. 保證訪問法則 依靠表名、主鍵值和列名的組合,保證能訪問每個(gè)數(shù)據(jù)項(xiàng)。
  3. 空值的系統(tǒng)化處理 支持空值(NULL),以系統(tǒng)化的方式處理空值,空值不依賴于數(shù)據(jù)類型。
  4. 基于關(guān)系模型的動(dòng)態(tài)聯(lián)機(jī)目錄 數(shù)據(jù)庫(kù)的描述應(yīng)該是自描述的,在邏輯級(jí)別上和普通數(shù)據(jù)采用同樣的表示方式,即數(shù)據(jù)庫(kù)必須含有描述該數(shù)據(jù)庫(kù)結(jié)構(gòu)的系統(tǒng)表或者數(shù)據(jù)庫(kù)描述信息應(yīng)該包含在用戶可以訪問的表中。
  5. 統(tǒng)一的數(shù)據(jù)子語言法則 一個(gè)關(guān)系數(shù)據(jù)庫(kù)系統(tǒng)可以支持幾種語言和多種終端使用方式,但必須至少有一種語言,它的語句能夠一某種定義良好的語法表示為字符串,并能全面地支持以下所有規(guī)則:數(shù)據(jù)定義、視圖定義、數(shù)據(jù)操作、約束、授權(quán)以及事務(wù)。(這種語言就是SQL)
  6. 視圖更新法則 所有理論上可以更新的視圖也可以由系統(tǒng)更新。
  7. 高級(jí)的插入、更新和刪除操作 把一個(gè)基礎(chǔ)關(guān)系或派生關(guān)系作為單個(gè)操作對(duì)象處理的能力不僅適應(yīng)于數(shù)據(jù)的檢索,還適用于數(shù)據(jù)的插入、修改個(gè)刪除,即在插入、修改和刪除操作中數(shù)據(jù)行被視作集合。
  8. 數(shù)據(jù)的物理獨(dú)立性 不管數(shù)據(jù)庫(kù)的數(shù)據(jù)在存儲(chǔ)表示或訪問方式上怎么變化,應(yīng)用程序和終端活動(dòng)都保持著邏輯上的不變性。
  9. 數(shù)據(jù)的邏輯獨(dú)立性 當(dāng)對(duì)表做了理論上不會(huì)損害信息的改變時(shí),應(yīng)用程序和終端活動(dòng)都會(huì)保持邏輯上的不變性。
  10. 數(shù)據(jù)完整性的獨(dú)立性 專用于某個(gè)關(guān)系型數(shù)據(jù)庫(kù)的完整性約束必須可以用關(guān)系數(shù)據(jù)庫(kù)子語言定義,而且可以存儲(chǔ)在數(shù)據(jù)目錄中,而非程序中。
  11. 分布獨(dú)立性 不管數(shù)據(jù)在物理是否分布式存儲(chǔ),或者任何時(shí)候改變分布策略,RDBMS的數(shù)據(jù)操縱子語言必須能使應(yīng)用程序和終端活動(dòng)保持邏輯上的不變性。
  12. 非破壞性法則 如果一個(gè)關(guān)系數(shù)據(jù)庫(kù)系統(tǒng)支持某種低級(jí)(一次處理單個(gè)記錄)語言,那么這個(gè)低級(jí)語言不能違反或繞過更高級(jí)語言(一次處理多個(gè)記錄)規(guī)定的完整性法則或約束,即用戶不能以任何方式違反數(shù)據(jù)庫(kù)的約束。

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

(一)規(guī)劃階段

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

(二)概念階段

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

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

  • 努力維護(hù)一系列包含了系統(tǒng)設(shè)計(jì)和規(guī)格說明信息的文檔,如會(huì)議記錄、訪談?dòng)涗?、關(guān)鍵用戶期望、功能規(guī)格、技術(shù)規(guī)格、測(cè)試規(guī)格等。
  • 頻繁與干系人溝通并收集反饋。
  • 標(biāo)記出你自己添加的,不屬于客戶要求的,未決內(nèi)容。
  • 與所有關(guān)鍵干系人盡快確認(rèn)項(xiàng)目范圍,并力求凍結(jié)需求。

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

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

  • 需要哪些數(shù)據(jù)?
  • 數(shù)據(jù)該被怎樣使用?
  • 哪些規(guī)則控制著數(shù)據(jù)的使用?
  • 誰會(huì)使用何種數(shù)據(jù)?
  • 客戶想在核心功能界面或者報(bào)表上看到哪些內(nèi)容?
  • 數(shù)據(jù)現(xiàn)在在哪里?
  • 數(shù)據(jù)是否與其他系統(tǒng)有交互、集成或同步?
  • 主題數(shù)據(jù)有哪些?
  • 核心數(shù)據(jù)價(jià)值幾何,對(duì)可靠性的要求程度?

并且得到如下信息:

  • 實(shí)體和關(guān)系
  • 屬性和域
  • 可以在數(shù)據(jù)庫(kù)中強(qiáng)制執(zhí)行的業(yè)務(wù)規(guī)則
  • 需要使用數(shù)據(jù)庫(kù)的業(yè)務(wù)過程

(三)邏輯階段

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

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

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

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

(五)物理階段

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

#p#

三 設(shè)計(jì)原則

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

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

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

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

  • 牽涉到的實(shí)體 識(shí)別出關(guān)系所涉及的所有實(shí)體。
  • 所有權(quán) 考慮一個(gè)實(shí)體“擁有”另一個(gè)實(shí)體的情況。
  • 基數(shù) 考量一個(gè)實(shí)體的實(shí)例和另一個(gè)實(shí)體實(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個(gè)列中。

(四)列的順序

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

(五)定義主鍵和外鍵

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

(六)選擇鍵

1 人工鍵與自然鍵

人工健——實(shí)體的非自然屬性,根據(jù)需要由人強(qiáng)加的,如GUID,其對(duì)實(shí)體毫無意義;自然健——實(shí)體的自然屬性,如身份證編號(hào)。

人工鍵的好處:

  • 鍵值永遠(yuǎn)不變
  • 永遠(yuǎn)是單列存儲(chǔ)

人工鍵的缺點(diǎn):

  • 因?yàn)槿斯ゆI是沒有實(shí)際意義的唯一值,所以不能通過人工鍵來避免重復(fù)行。

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

  • 在設(shè)計(jì)階段我們無法預(yù)測(cè)到代碼真正需要的值,所以干脆放棄猜測(cè)鍵,而使用人工鍵。
  • 人工鍵復(fù)雜處理實(shí)體關(guān)系,而不負(fù)責(zé)任何屬性描述,這樣的設(shè)計(jì)使得實(shí)體關(guān)系與實(shí)體內(nèi)容得到高度解耦,這樣做的設(shè)計(jì)思路更加清晰。

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

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

  • 自增值類型 由于類型輕巧查詢效率更好,但取值有限。
  • GUID 查詢效率不如值類型,但是取值無限,且對(duì)開發(fā)人員更加親切。

2 智能健與非智能鍵

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

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

(七)是否允許NULL

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

  • 任何值和NULL拼接后都為NULL。
  • 所有與NULL進(jìn)行的數(shù)學(xué)操作都返回NULL。
  • 引入NULL后,邏輯不易處理。

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

(八)屬性切割

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

#p#

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

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

  • 消滅重復(fù)數(shù)據(jù)。
  • 避免編寫不必要的,用來使重復(fù)數(shù)據(jù)同步的代碼。
  • 保持表的瘦身,以及減從一張表中讀取數(shù)據(jù)時(shí)需要進(jìn)行的讀操作數(shù)量。
  • 最大化聚集索引的使用,從而可以進(jìn)行更優(yōu)化的數(shù)據(jù)訪問和聯(lián)結(jié)。
  • 減少每張表使用的索引數(shù)量,因?yàn)榫S護(hù)索引的成本很高。

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

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

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

需要考慮幾點(diǎn):

  • 屬性是原子性的 需要考慮熟悉是否分解的足夠徹底,使得每個(gè)屬性都表示一個(gè)單一的值。(和“(三)列意味著唯一的值”描述的原則相同。)分解原則為——當(dāng)你需要分開處理每個(gè)部分時(shí)才分解值,并且分解到足夠用就行。(即使當(dāng)前不需要徹底分解屬性,也應(yīng)該考慮未來可能的需求變更。)
  • 屬性的所有實(shí)例必須包含相同數(shù)量的值 實(shí)體有固定數(shù)量的屬性(表有固定數(shù)量的列)。設(shè)計(jì)實(shí)體時(shí),要讓每個(gè)屬性只有固定數(shù)量的值與其相關(guān)聯(lián)。
  • 實(shí)體中出現(xiàn)的所有實(shí)體類型都必須不同

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

  • 包含分隔符類字符的字符串?dāng)?shù)據(jù)。
  • 名字尾端有數(shù)字的屬性。
  • 沒有定義鍵或鍵定義不好的表。

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

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

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

  • 重復(fù)的鍵屬性名字前綴(設(shè)計(jì)之外的數(shù)據(jù)冗余) 表明這些值可能描述了某些額外的實(shí)體。
  • 有重復(fù)的數(shù)據(jù)組(設(shè)計(jì)之外的數(shù)據(jù)冗余) 這標(biāo)志著屬性間有函數(shù)依賴型。
  • 沒有外鍵的復(fù)合主鍵 這標(biāo)志著鍵中的鍵值可能標(biāo)識(shí)了多種事物,而不是一種事物。

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

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

  • 多個(gè)屬性有同樣的前綴。
  • 重復(fù)的數(shù)據(jù)組。
  • 匯總的數(shù)據(jù),所引用的數(shù)據(jù)在一個(gè)完全不同的實(shí)體中。(有些人傾向于使用視圖,我更傾向于使用對(duì)象集合,即由程序來完成。)

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

3 去除實(shí)體組合鍵中的冗余

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

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

  • 三元關(guān)系(實(shí)體:實(shí)體:實(shí)體)。
  • 潛伏的多值屬性。(如多個(gè)手機(jī)號(hào)。)
  • 臨時(shí)數(shù)據(jù)或歷史值。(需要將歷史數(shù)據(jù)的主體提出,否則將存在大量冗余。)

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

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

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

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

推薦做法:

  • 盡可能地遵守上述規(guī)范化原則。
  • 所有屬性描述的都應(yīng)該是體現(xiàn)被建模實(shí)體的本質(zhì)的內(nèi)容。
  • 至少必須有一個(gè)鍵,它唯一地標(biāo)識(shí)和描述了所建實(shí)體的本質(zhì)。
  • 主鍵要謹(jǐn)慎選擇。
  • 在邏輯階段能做多少規(guī)范化就做多少(性能不是邏輯階段考慮的范疇)。

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

MS SQL的常用類型:

精確數(shù)字 不會(huì)發(fā)生精度損失 bit tinyint smallint int bigint decimal
近似數(shù)字 對(duì)于極值可能發(fā)生精度損失 float(N) real
日期和時(shí)間   date time smalldatetime datetime datetime2 datetimeoffset
二進(jìn)制數(shù)據(jù)   bingary(N) varbinary(N) varbinary(max)
字符(串)數(shù)據(jù)   char(N) varchar(N) varchar(max) nchar(N) nvarchar(N) nvarchar(max)
存儲(chǔ)任意數(shù)據(jù)   sql_variant
時(shí)間戳   timestamp
GUID   uniqueidentifier
XML 不要試圖使用該類型規(guī)避1NF xml
空間數(shù)據(jù)   geometry geography
層次數(shù)據(jù)   heirarchyid

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

  • image:被varbinary(max)取代。
  • text和ntext:被varchar(max)和nvarchar(max)取代。
  • money和smallmoney:開發(fā)過程中不好用,建議使用decimal。

常用類型選擇:

類型選擇的最基本規(guī)則是選擇滿足需要的最輕的類型,因?yàn)檫@樣查詢更快。

bool 建議使用bit而非char(1),因?yàn)殚_發(fā)語言對(duì)其支持覺好,可以直接映射為bool或bool?。
大值數(shù)據(jù) 使用所有備選類型中最小的那種,類型越大,查詢?cè)铰?,?dāng)字節(jié)大于8000時(shí),應(yīng)使用max。
主鍵 自增主鍵根據(jù)預(yù)期范圍選擇int或bigint,GUID使用uniqueidentifier而非varchar(N)。

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

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

四 命名規(guī)則

  • 表——“模塊名_表名”。表名最好不要用復(fù)數(shù),原因是在使用ORM框架開發(fā)時(shí),代碼生成器根據(jù)DB生成類定義,表生成了某個(gè)實(shí)例的類型定義,而不是實(shí)例集合。表名不要太長(zhǎng)。原因之一,某些軟件對(duì)表名最大長(zhǎng)度有限制;原因之二,使用代碼生成器往往會(huì)根據(jù)表名生產(chǎn)類型名稱,之后懶人會(huì)直接使用這一名稱,如果將太長(zhǎng)的名稱跨網(wǎng)絡(luò)邊界顯然不是明智之舉。
  • 字段——bool類型用“Is”、“Can”、“Has”等表示;日期類型命名必須包含“Date”;時(shí)間類型必須包含“Time”。
  • 存儲(chǔ)過程——使用“proc_”前綴。
  • 視圖——使用“view_”前綴。
  • 觸發(fā)器——使用“trig_”前綴。

原文鏈接:http://www.cnblogs.com/MeteorSeed/archive/2013/03/27/2880054.html

責(zé)任編輯:林師授 來源: 博客園
相關(guān)推薦

2017-04-01 18:00:08

開發(fā)者數(shù)據(jù)庫(kù)

2014-12-24 09:51:22

WebNoSQL

2014-12-24 09:48:13

NoSQL關(guān)系數(shù)據(jù)庫(kù)

2022-12-27 08:38:45

關(guān)系型數(shù)據(jù)庫(kù)設(shè)計(jì)

2021-01-26 13:31:48

數(shù)據(jù)庫(kù)關(guān)系型數(shù)據(jù)庫(kù)冗余

2023-05-22 16:10:51

動(dòng)態(tài)共享包數(shù)據(jù)庫(kù)

2011-03-16 09:33:45

數(shù)據(jù)庫(kù)開發(fā)錯(cuò)誤

2011-03-16 09:38:05

2018-07-18 09:16:39

關(guān)系型非關(guān)系型數(shù)據(jù)庫(kù)

2011-02-22 14:07:52

2021-09-06 10:24:12

鴻蒙HarmonyOS應(yīng)用

2017-11-23 15:06:14

前端數(shù)據(jù)庫(kù)開發(fā)

2022-01-16 22:16:59

數(shù)據(jù)庫(kù)Sentry開發(fā)者

2013-11-26 09:43:36

開發(fā)日志博客

2016-08-23 14:25:19

MySQL約束數(shù)據(jù)庫(kù)

2016-09-08 23:28:06

2023-12-08 09:35:37

2022-05-01 21:43:38

SQL設(shè)計(jì)模式

2017-03-17 14:44:04

關(guān)系型數(shù)據(jù)庫(kù)原理

2022-06-13 08:30:01

數(shù)據(jù)庫(kù)管理系統(tǒng)
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)