數據庫設計注意事項和原則

引言數據庫設計是信息系統設計的基礎,一個好的數據庫設計在滿足了軟件需求之外,還要易維護、易擴充等等要求。當然,對專家們反復強調的數據的一致性、冗余性、訪問效率等問題的解決,很大程度上取決于數據庫設計者的經驗和專業水平。但這不妨礙我們根據過去的經驗,從實用的角度給出數據庫設計所要要考慮的問題并盡可能給出相應的解決方案,從而給信息系統的數據庫設計者一些有益的啟示。(注:這里的數據庫設計主要指數據庫中表和視圖的schema設計,不涉足數據庫系統中其他方面的設計)那么怎樣才算是一個好的數據庫設計呢?以下給出一個一般性的標準。

一、一個好的數據庫設計首先要滿足用戶的需求

所有信息系統最后都將提交給最終用戶使用,對于這一點,相信大家都已經達成共識。但是準確地把握用戶的需求是很難的,雖然各方面的專家已經從不同方面給出了解決方案,但是用戶需求仍然是軟件工程中最不確定的因素之一。

二、一個好的數據庫設計要便于維護和擴充

為了應對用戶需求的修改和添加,也為了滿足各種不同的軟硬件環境下系統的使用,大部分信息系統都不得不在其生命期中進行升級和調整。在這些升級、調整中,又有相當部分會涉及到數據庫設計的修改,因此,數據庫設計最好從一開始就能在易維護、可擴充的角度多加斟酌。

1、不要為各種編號字段的設定固定的意義
而是最好通過對照表來建立這種編號和意義的對照關系。舉例來說,很多設計者習慣給部門信息給出固定的編號,這種設計有個致命的缺陷:那就是由于這種對照關系既然不體現在數據庫中,就必然要用業務邏輯來進行解釋,這樣一來,一有新的調整就不得不更新業務邏輯代碼,也就非常容易不一致的錯誤。

2、枚舉信息要體現在相應在對照表中
而不是體現在使用該信息的表中的值字段,這樣做的好處是當用戶希望用該枚舉信息作為查詢條件的時候,通過參照表的方式可以很容易的建立這些信息,另外也避免了當多個表格中都含有該枚舉信息有可能引起的不一致。

3、用關聯表建立表和表之間的多對多關系
而不要用一個字段解析的方式進行,舉例來說,為了描述用戶(UserInfo)和角色(RoleInfo)之間的關聯關系,我們要建立對照表UserInfo_RoleInfo,而不要試圖在用戶表中建立一個較長的字段,如Roles(用RoleID1;RoleID2…的形式構成)來代替,因為這樣一來字段解釋需要在業務代碼相應的解析代碼,二來由于Roles定長,無法滿足用戶角色的擴充。

三、一個好的數據庫設計要具有“可讀性”

如同編程書籍中反復強調的程序員一定要在代碼的可讀性方面下功夫一樣,考慮到信息系統將來的升級和維護可能要要由另外一批人來進行,因此數據庫設計必然也要具有可理解性。對此,我們參照提高代碼可讀性的常用方法,給出一些建議:

1、用設計文檔來提高數據庫設計的可讀性
這點基本對應于“可讀性”代碼里面的注釋。在一個合格的數據庫設計文檔中必須給出數據庫中的每個表、每個字段、表間的關聯關系以及各種約束的意義以及由來,從而有可能讓開發者根據用戶需求和設計文檔就能理解正確數據庫的設計。

2、給表和視圖起一個有意義的名字
這點對應于coding規范中的變量和函數的命名,很顯然,CustomerInfo的名字很容易聯想到該表中含有客戶信息,而把它命名為Table0001只能讓人感到費解外。另外,如果DBMS提供表和視圖名的大小寫支持,該名稱最好由每個構成單詞(首字母大寫)拼接而成。

3、用前綴給出表和視圖內容之外的其他信息
如給參照表Ref_前綴,這樣就可以讓業務邏輯實現人員根據表的名字知道他所要操作的是不是張參照表,從而幫助他更快地理解詳細設計,并有可能及早發現里面的錯誤。同樣,給所有視圖加上V_前綴,就可以讓業務邏輯編程者很容易地知道他現在面臨的是一個表還是視圖,從而避免了對視圖進行更新操作這種低級的錯誤。

4、給每一個字段起一個有意義的名字
如給CustomerInfo表中的電子郵件字段起名EMail讓人很容易明白它的準確含義,而Field05則讓人不知所云。基于同樣的道理,數據庫設計中也不能給字段起一個張冠李戴的名字。

5、字段命名要考慮上下文
舉例來說,在UserInfo表中,用UserName來表示用戶名字段就不如Name來的更加合適。這種情況畫蛇添足的情況在對照表的設計中體現得尤為明顯,如把部門對照表(Ref_Department)中的部門ID字段命名為DepartmentID,把部門名稱字段命名為DepartmentName等等。

6、視圖的設計不要牽扯到其他視圖
與代碼設計中函數調用最好不要嵌套過多層次相對應,為了便于數據庫設計的閱讀人能夠很好地理解設計,視圖最好直接建立在表上。

7、同一表中的記錄最好不要相互引用
這種引用關系不僅讓數據庫設計的閱讀人云里霧里,也不便于業務邏輯代碼的編寫。

8、關聯表的命名用關聯的表名中間加下劃線連接構成
如學生(StudentInfo)和課程(CourseInfo)的關聯表起名StudentInfo_CourseInfo。

四、一個好的數據庫設計能夠滿足空間和效率的要求

對于一個信息系統來說,在實現用戶需求的基礎之上,保證一個較低的空間占用以及短的響應時間都是理智的客戶所愿意看到的。那么在這一方面,數據庫設計又要做些什么工作呢?

1、使用varchar而不要使用char字段
對于不定長信息如用戶的簡介信息,varchar的使用可以減少近一半的空間占用。當然這點不能一概而論,如用相應長度的char存儲定長文本數據就比varchar來的合適。

2、不要使用BLOB字段存放“大數據”
BLOB字段誠如其名,本身是為存儲二進制大數據而出現的,同樣的道理也適用于某些DBMS所引入的TEXT字段。因為對于一般信息系統而言,最長的字段往往是一些描述文本信息,而DBMS對char/varchar的長度基本能滿足這種需求。因此積極建議設計者對一些貌似很長的文本的最大允許長度進行確認,在此基礎上參照DBMS中的開發手冊來決定是否采用大字段。

3、不要使用設計器缺省的字段長度
這種做法一方面縱容了設計者對用戶需求的一知半解以及對設計敷衍了事的不良習慣,另外一方面也在數據的存儲上浪費了不少的空間,因為使用缺省字段長度的情況往往發生在字段上。

4、不要輕易使用unicode文本字段
DBMS對unicode的支持在幫助產品國際化的同時,也在一定程度上帶來空間上的浪費,尤其是在當要存儲的文本中的基本都是ASCII字符的情況下,這種浪費尤為明顯。因此,建議設計者在選擇unicode的理由,一定是出于國際化的考慮,而不是其他。因為大多數的大字符集和ASCII字符并存情況下所要碰到的問題基本上都已經由DBMS提供商解決。

5、使用預計算表來提高響應速度
跟數據倉庫里面的某些思路相似,當業務邏輯中需要用倒根據歷史信息得來的統計數據時,最好由獨立于系統的預計算模塊或相應的DW工具定期完成這些統計數據的預計算。

五、一個好的數據庫設計可以簡化業務邏輯的設計

所有的數據庫設計都不是孤立的,它通過相應的業務邏輯實現(三層結構中還有表現層)來形成最終的產品,因此一個好的數據庫設計應該能夠幫助降低業務邏輯的編寫難度,最起碼不要給業務邏輯的設計、編碼帶來額外工作。

1、所有允許為空的字段必須是基于用戶需求,而不是出于設計上方便的考慮。這樣帶來的好處是讓詳細設計中的某些錯誤和疏漏(如在設計中沒有考慮對非空字段的內容檢查)在編碼和單元測試階段就被發現,從而避免了進一步擴散,有助于提高軟件的質量。

2、不要業務邏輯代碼實現唯一性約束
對數據庫表中的某些字段(或者多個字段的組合)的唯一性約束應該盡可能地加到數據庫端。因為這種約束工作交給業務邏輯中去實現代價高昂而且不可靠。

3、關聯約束一定要建立在數據庫端
分析出設計中所涉及的主外鍵引用關系并體現在數據庫設計中。這一條出于兩點考慮:降低業務邏輯的編寫難度和數據關聯性約束的要求。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/249485.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/249485.shtml
英文地址,請注明出處:http://en.pswp.cn/news/249485.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

【AtCoder】ARC078

C - Splitting Pile 枚舉從哪里開始分的即可 #include <bits/stdc.h> #define fi first #define se second #define pii pair<int,int> #define mp make_pair #define pb push_back #define space putchar( ) #define enter putchar(\n) #define MAXN 200005 #defi…

20172325 2018-2019-1 《Java程序設計》第二周學習總結

20172325 2018-2019-1 《Java程序設計》第二周學習總結 教材學習內容總結 3.1集合 集合是一種聚集、組織了其他對象的對象。集合可以分為兩大類&#xff1a;線性集合和非線性集合。線性集合&#xff1a;一種其元素按照直線方式組織的集合。非線性集合&#xff1a;一種其元素按某…

數據庫視圖

測試表:user有id&#xff0c;name&#xff0c;age&#xff0c;sex字段 測試表:goods有id&#xff0c;name&#xff0c;price字段 測試表:ug有id&#xff0c;userid&#xff0c;goodsid字段 視圖的作用實在是太強大了&#xff0c;以下是我體驗過的好處&#xff1a; 作用一&…

題解 luogu P2568 GCD

題解 luogu P2568 GCD 時間&#xff1a;2019.3.11 歐拉函數前綴和 題目描述 給定整數\(N\)&#xff0c;求\(1\le x,y \le N\)且\(\gcd(x,y)\)為素數的數對\((x,y)\)有多少對. 分析 枚舉素數\(p\), 先求出\(1\le x,y \le \left \lfloor \dfrac n p \right \rfloor\)且\(\gcd(x, …

解決前后臺發送請求或者接口之間發送請求亂碼的問題

前后臺傳中文亂碼&#xff1a; 前臺使用encodeURI 進行編碼 后臺使用decode進行解碼 如果接口之間調用出現亂碼.接收方是&#xff1f;&#xff1f;&#xff1f;&#xff1f;這種。傳送方式明文的處理方式&#xff1a; 發送方使用decode 進行編碼&#xff1a; 接收方使用的ecod…

MSDN幫助文檔 無法顯示該網頁 的問題解決方案(轉)

MSDN幫助文檔 "無法顯示該網頁" 的問題解決方案 以前就遇到過這樣的問題&#xff0c;還以為是IE7導致的。后來重新安裝了IE7也沒有解決。后來就重新安裝MSDN了&#xff0c;非常郁悶。今天終于知道原因了。因為開了HijackThis刪除了一些注冊協議&#xff0c;然后發現M…

.net Core發布至IIS完全手冊帶各種踩坑

服務器環境配置 和各位大爺報告一下我的服務器環境 : Windows Server 2012 iis 8 小插曲開始: 運維大哥在昨天給了我一臺新的server 0環境開始搭建 。 并且沒有安裝任何的系統補丁。 第一件事情請開始打 補丁 打完補丁之后有時補丁會不完全 ,所以需要去官網獲取補丁: KB2919355…

Unity --- MeshRenderer之網格合并

創建如圖所示的對象結構,parent為空對象&#xff0c;然后將下面的代碼掛載到parent對象上運行即可。 1 using UnityEngine;2 using System.Collections;3 4 public class CombineMeshAndMaterials : MonoBehaviour5 {6 void Start()7 {8 CombineMesh();9 }…

css 盒模型的屬性

1、盒模型 2、display 3、浮動轉載于:https://www.cnblogs.com/Tang854416/p/9676424.html

前后端分離

、前后端分離的好處 &#xff08;1&#xff09;徹底解放前端 &#xff08;2&#xff09;提高工作效率&#xff0c;分工更加明確。 &#xff08;3&#xff09;局部性能提升 &#xff08;4&#xff09;降低維護成本 2、前后端分離的概念 后臺只需要提供API接口&#xff0c;…

Win10還原被Windows Defender隔離的文件

Win10最新版本的Windows Defender隔離/刪除的文件沒有還原的選項&#xff0c;導致很多破解文件或是注冊機直接隔離&#xff0c;到威脅歷史記錄中去卻無法恢復。經過各個嘗試&#xff0c;到微軟官方論壇中也嘗試了很多方法&#xff0c;后來發現竟然恢復啦。各位小伙伴可以試試這…

AtCoder Grand Contest 013 題解

A - Sorted Arrays 貪心&#xff0c;看看不下降和不上升最長能到哪&#xff0c;直接轉移過去即可。 1 //waz2 #include <bits/stdc.h>3 4 using namespace std;5 6 #define mp make_pair7 #define pb push_back8 #define fi first9 #define se second 10 #define ALL(x…

servlet架構解析

https://www.jianshu.com/p/d433b5fb87e2

(Review cs231n) Backpropagation and Neural Network

損失由兩部分組成&#xff1a; 數據損失正則化損失&#xff08;data loss regularization&#xff09; 想得到損失函數關于權值矩陣W的梯度表達式&#xff0c;然后進性優化操作&#xff08;損失相當于海拔&#xff0c;你在山上的位置相當于W&#xff0c;你進行移動&#xff0c…

springboot restful

https://www.jianshu.com/p/733d788ea94d

【計算機算法設計與分析】——排序

一.排序 二.插入排序 &#xff08;1&#xff09;算法描述 &#xff08;2&#xff09;性能分析 &#xff08;3&#xff09;尋求優化 三.歸并排序 &#xff08;1&#xff09;算法思想 &#xff08;2&#xff09;性能分析 &#xff08;2&#xff09;示例 &#xff08;3&#xff09…

QT 隨機數生成

下面總結了QT中隨機生成的方法&#xff08;僅供學習參考&#xff09;&#xff0c;分為舊方法和新方法&#xff0c;一般來說&#xff0c;舊的方法已經被拋棄&#xff0c;在開發新的應用中推薦使用新方法。 C Code 123456789101112131415161718192021222324#include <QCoreApp…

獲取/設置IFRAME內對象元素的幾種JS方法

獲取/設置IFRAME內對象元素的幾種JS方法 iframe瀏覽器ie文檔微軟&#xff11;。IE專用(通過frames索引形象定位)&#xff1a; document.frames[i].document.getElementById(元素的ID); &#xff12;。IE專用(通過IFRAME名稱形象定位)&#xff1a; document.frames[iframe的name…

高并發

https://blog.csdn.net/java_xth/article/details/81162088

多人游戲服務器

https://www.getmangos.eu/轉載于:https://www.cnblogs.com/aibox222/p/9682697.html