athrunwang
紀元
BlogJava
首頁
新隨筆
聯系
聚合
管理
數據加載中……
11 個重要的數據庫設計規則
簡介
在您開始閱讀這篇文章之前,我得明確地告訴您,我并不是一個數據庫設計領域的大師。以下列出的11點是我對自己在平時項目實踐和閱讀中學習到的經驗總結出來的個人見解。我個人認為它們對我的數據庫設計提供了很大的幫助。實屬一家之言,歡迎拍磚 : )
我之所以寫下這篇這么完整的文章是因為,很多開發者一參與到數據庫設計,就會很自然地把 “三范式” 當作銀彈一樣來使用。他們往往認為遵循這個規范就是數據庫設計的唯一標準。由于這種心態,他們往往盡管一路碰壁也會堅持把項目做下去。
如果你對 “三范式” 不清楚,請
點擊這里
(FQ)一步一步的了解什么是“三范式”。
大家都說標準規范是重要的指導方針并且也這么做著,但是把它當作石頭上的一塊標記來記著(死記硬背)還是會帶來麻煩的。以下11點是我在數據庫設計時最優先考慮的規則。
規則 1:弄清楚將要開發的應用程序是什么性質的(OLTP 還是 OPAP)?
當你要開始設計一個數據庫的時候,你應該首先要分析出你為之設計的應用程序是什么類型的,它是 “
事務處理型
”(
Transactional
) 的還是 “
分析型
” (
Analytical
)的?你會發現許多開發人員采用標準化做法去設計數據庫,而不考慮目標程序是什么類型的,這樣做出來的程序很快就會陷入性能、客戶定制化的問題當中。正如前面所說的,這里有兩種應用程序類型, “基于事務處理” 和 “基于分析”,下面讓我們來了解一下這兩種類型究竟說的是什么意思。
事務處理型:
這種類型的應用程序,你的最終用戶更關注數據的增查改刪(CRUD,Creating/Reading/Updating/Deleting)。這種類型更加官方的叫法是 “
OLTP
” 。
分析型:
這種類型的應用程序,你的最終用戶更關注數據分析、報表、趨勢預測等等功能。這一類的數據庫的 “插入” 和 “更新” 操作相對來說是比較少的。它們主要的目的是更加快速地查詢、分析數據。這種類型更加官方的叫法是 “
OLAP
” 。
那么換句話說,如果你認為插入、更新、刪除數據這些操作在你的程序中更為突出的話,那就設計一個規范化的表否則的話就去創建一個扁平的、不規范化的數據庫結構。
以下這個簡單的圖表顯示了像左邊Names和Address這樣的簡單規范化的表,怎么通過應用不規范化結構來創建一個扁平的表結構。
規則 2:將你的數據按照邏輯意義分成不同的塊,讓事情做起來更簡單
這個規則其實就是 “三范式” 中的第一范式。違反這條規則的一個標志就是,你的查詢使用了很多字符串解析函數
例如 substring、charindex等等。若真如此,那就需要應用這條規則了。
比如你看到的下面圖片上有一個有學生名字的表,如果你想要查詢學生名字中包含“Koirala”,但不包含“Harisingh”的記錄,你可以想象一下你將會得到什么樣的結果。
所以更好的做法是將這個字段拆分為更深層次的邏輯分塊,以便我們的表數據寫起來更干凈,以及優化查詢。
規則 3:不要過度使用 “規則 2”
開發者都是一群很可愛的生物。如果你告訴他們這是一條解決問題的正路,他們就會一直這么做下去,做到過了頭導致了一些不必要的后果。這也可以應用于我們剛剛在前面提到的規則2。當你考慮字段分解時,先暫停一下,并且問問你自己是否真的需要這么做。正如所說的,分解應該是要符合邏輯的。
例如,你可以看到電話號碼這個字段,你很少會把電話號碼的ISD代碼單獨分開來操作(除非你的應用程序要求這么做)。所以一個很明智的決定就是讓它保持原樣,否則這會帶來更多的問題。
規則 4:把重復、不統一的數據當成你最大的敵人來對待
集中那些重復的數據然后重構它們。我個人更加擔心的是這些重復數據帶來的混亂而不是它們占用了多少磁盤空間。
例如下面這個圖表,你可以看到 "5th Standard" 和 "Fifth standard" 是一樣的意思,它們是重復數據。現在你可能會說是由于那些錄入者錄入了這些重復的數據或者是差勁的驗證程序沒有攔住,讓這些重復的數據進入到了你的系統。現在,如果你想導出一份將原本在用戶眼里十分困惑的數據顯示為不同實體數據的報告,該怎么做呢?
解決方法之一是將這些數據完整地移到另外一個主表,然后通過外鍵引用過來。在下面這個圖表中你可以看到我們是如何創建一個名為 “Standards”(課程級別) 的主表,然后同樣地使用簡單的外鍵連接過去。
規則 5:當心被分隔符分割的數據,它們違反了“字段不可再分”
前面的規則2即“第一范式”說的是避免 “重復組” 。下面這個圖表作為其中的一個例子解釋了 “重復組”是什么樣子的。如果你仔細的觀察 syllabus(課程) 這個字段,會發現在這一個字段里實在是填充了太多的數據了。像這些字段就被稱為 “重復組” 了。如果我們又得必須使用這些數據,那么這些查詢將會十分復雜并且我也懷疑這些查詢會有性能問題。
這些被塞滿了分隔符的數據列需要特別注意,并且一個較好的辦法是將這些字段移到另外一個表中,使用外鍵連接過去,同樣地以便于更好的管理。
那么,讓我們現在就應用規則2(第一范式) “避免重復組” 吧。你可以看到上面這個圖表,我創建了一個單獨的 syllabus(課程) 表,然后使用 “多對多” 關系將它與 subject(科目) 表關聯起來。
通過這個方法,主表(student表)的 syllabus(課程) 字段就不再有重復數據和分隔符了。
規則 6:當心那些僅僅部分依賴主鍵的列
留心注意那些僅僅部分依賴主鍵的列。例如上面這個圖表,我們可以看到這個表的主鍵是 Roll No.+Standard
。現在請仔細觀察 syllabus 字段,可以看到 syllabus(課程) 字段僅僅關聯(依賴) Standard(課程級別) 字段而不是直接地關聯(依賴)某個學生(Roll No. 字段)。
Syllabus(課程) 字段關聯的是學生正在學習的哪個課程級別(Standard字段)而不是直接關聯到學生本身。那如果明天我們要更新教學大綱(課程)的話還要痛苦地為每個同學也修改一下,這明顯是不符合邏輯的(不正常的做法)。更有意義的做法是將這些字段從這個表移到另外一個表,然后將它們與 Standard(課程級別)表關聯起來。
你可以看到我們是如何移動 syllabus(課程)字段并且同樣地附上 Standard 表。
這條規則只不過是 “三范式” 里的 “第二范式”:“所有字段都必須完整地依賴主鍵而不是部分依賴”。
規則 7:仔細地選擇派生列
如果你正在開發一個
OLTP
型的應用程序,那強制不去使用派生字段會是一個很好的思路,除非有迫切的性能要求,比如經常需要求和、計算的
OLAP
程序,為了性能,這些派生字段就有必要存在了。
通過上面的這個圖表,你可以看到 Average 字段是如何依賴 Marks 和 Subjects 字段的。這也是冗余的一種形式。因此對于這樣的由其他字段得到的字段,需要思考一下它們是否真的有必要存在。
這個規則也被稱為 “三范式” 里的第三條:“不應該有依賴于非主鍵的列” 。 我的個人看法是不要盲目地運用這條規則,應該要看實際情況,冗余數據并不總是壞的。如果冗余數據是計算出來的,看看實際情況再來決定是否應用這第三范式。
規則 8:如果性能是關鍵,不要固執地去避免冗余
不要把 “避免冗余” 當作是一條絕對的規則去遵循。如果對性能有迫切的需求,考慮一下打破常規。常規情況下你需要做多個表的連接操作,而在非常規的情況下這樣的多表連接是會大大地降低性能的。
規則 9:多維數據是各種不同數據的聚合
OLAP
項目主要是解決多維數據問題。比如你可以看看下面這個圖表,你會想拿到每個國家、每個顧客、每段時期的銷售額情況。簡單的說你正在看的銷售額數據包含了三個維度的交叉。
為這種情況做一個實際的設計是一個更好的辦法。簡單的說,你可以創建一個簡單的主要銷售表,它包含了銷售額字段,通過外鍵將其他所有不同維度的表連接起來。
規則 10:將那些具有“名值表”特點的表統一起來設計
很多次我都遇到過這種 “名值表” 。 “名值表” 意味著它有一些鍵,這些鍵被其他數據關聯著。比如下面這個圖表,你可以看到我們有 Currency(貨幣型)和 Country(國家)這兩張表。如果你仔細觀察你會發現實際上這些表都只有鍵和值。
對于這種表,創建一個主要的表,通過一個 Type(類型)字段來區分不同的數據將會更有意義。
規則 11:無限分級結構的數據,引用自己的主鍵作為外鍵
我們會經常碰到一些無限父子分級結構的數據(樹形結構?)。例如考慮一個多級銷售方案的情況,一個銷售人員之下可以有多個銷售人員。注意到都是 “銷售人員” 。也就是說數據本身都是一種。但是層級不同。這時候我們可以引用自己的主鍵作為外鍵來表達這種層級關系,從而達成目的。
這篇文章的用意不是叫大家不要遵循范式,而是叫大家不要盲目地遵循范式。根據你的項目性質和需要處理的數據類型來做出正確的選擇。
英文原文
,OSChina原創翻譯。
posted on 2012-04-18 21:57
AthrunWang
閱讀(207)
評論(0)
編輯
收藏
新用戶注冊
刷新評論列表
只有注冊用戶
登錄
后才能發表評論。
網站導航:
博客園
IT新聞
Chat2DB
C++博客
博問
管理
Powered by:
BlogJava
Copyright © AthrunWang
<
2012年4月
>
日
一
二
三
四
五
六
25
26
27
28
29
30
31
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
1
2
3
4
5
統計
隨筆 - 72
文章 - 0
評論 - 15
引用 - 0
常用鏈接
我的隨筆
我的評論
我的參與
最新評論
留言簿
給我留言
查看公開留言
查看私人留言
隨筆檔案
2014年2月 (8)
2013年9月 (2)
2013年3月 (1)
2013年1月 (1)
2012年10月 (1)
2012年9月 (3)
2012年6月 (2)
2012年5月 (2)
2012年4月 (1)
2012年3月 (6)
2012年2月 (1)
2012年1月 (9)
2011年12月 (18)
2011年11月 (14)
2011年10月 (2)
2011年9月 (1)
搜索
最新評論
1.?re: myeclipse優化方案 myeclipse 10 優化 [未登錄]
123
--123
2.?re: [筆記]war,jar包是啥
解釋得很詳細,很經典,學到東西了!
--smiling
3.?re: Java 生成視頻縮略圖(ffmpeg)
評論內容較長,點擊標題查看
--最代碼
4.?re: Java驗證碼
評論內容較長,點擊標題查看
--最代碼
5.?re: java播放mp3
怎么暫停?close直接就關掉了
--vh
閱讀排行榜
1.?StringUtils詳細介紹(27299)
2.?myeclipse優化方案 myeclipse 10 優化 (26807)
3.?[導入][轉載]java中用URLConnection 類post方式提交表單(11183)
4.?[筆記]war,jar包是啥(7436)
5.?用org.apache.tools.zip壓縮/解壓縮zip文件(5269)
評論排行榜
1.?StringUtils詳細介紹(3)
2.?Java驗證碼(3)
3.?myeclipse優化方案 myeclipse 10 優化 (2)
4.?新浪一道面試題:寫一個函數,計算兩個文件的相對路徑的遞歸算法(2)
5.?java播放mp3(1)
主站蜘蛛池模板:
91精品全国免费观看含羞草
|
久久国产精品免费
|
美女免费视频一区二区三区
|
免费一级做a爰片久久毛片潮
|
国产免费伦精品一区二区三区
|
18禁超污无遮挡无码免费网站
|
91香蕉国产线在线观看免费
|
性盈盈影院免费视频观看在线一区
|
国产精品极品美女免费观看
|
性做久久久久久久免费看
|
成年在线网站免费观看无广告
|
免费看国产一级片
|
国产V亚洲V天堂无码久久久
|
色偷偷女男人的天堂亚洲网
|
免费人成动漫在线播放r18
|
免费黄网站在线看
|
免费看无码自慰一区二区
|
亚洲综合激情另类专区
|
精品亚洲成a人片在线观看少妇
|
亚洲精品宾馆在线精品酒店
|
国产在线观看免费av站
|
国国内清清草原免费视频99
|
亚洲毛片av日韩av无码
|
亚洲国产精品成人精品小说
|
国产AV无码专区亚洲AV琪琪
|
91精品国产免费久久国语麻豆
|
国产免费黄色大片
|
亚洲高清资源在线观看
|
成a人片亚洲日本久久
|
一级毛片不卡片免费观看
|
国产免费卡一卡三卡乱码
|
亚洲午夜视频在线观看
|
久久久久亚洲精品无码网址色欲
|
成人免费无码大片A毛片抽搐
|
国产精品亚洲综合一区
|
亚洲youjizz
|
a级毛片高清免费视频
|
精品久久洲久久久久护士免费
|
亚洲高清在线观看
|
国产亚洲午夜精品
|
97在线观免费视频观看
|