標籤:style blog http os 使用 io strong ar for
資料庫設計規範1.簡介
資料庫設計是指對一個給定的應用環境,構造最優的資料庫模式,建立資料庫及其他應用系統,使之能有效地儲存資料,滿足各種使用者的需求。資料庫設計過程中命名規範很是重要,命名規範合理的設計能夠省去開發人員很多時間去區別資料庫實體。
最近也因為工作需要所以整理出了這個word文檔,望大家指正。
2資料庫設計
資料庫規劃→需求分析→資料庫設計→應用程式設計→實現→測試→運行於維護
2.1資料庫規劃
定義資料庫應用系統的主要目標,定義系統特定任務,包括工作量的估計、使用資源、和需求經費,定義系統的範圍以及邊界。
2.2需求分析2.1.1需求分析步驟與成果
涉及人員:使用者和分析人員
任務:對現實世界要處理的對象進行詳細的調查,收集基礎資料及處理方法,在使用者調查的基礎上通過分析,逐步明確使用者對系統的需求,包括資訊的要求及處理的要求。
方法與步驟:1.通過與使用者的調查,對使用者的資訊需求進行收集。
2.在收集資料的同時,設計人員要對其進行加工和整理,以資料字典和資料流圖的形式描述出來,並以設計人員的角度向使用者講述資訊,根據使用者的反饋加以修改並確定(該過程是反覆的過程)
成果:資料流圖,資料字典,各種說明性表格,統計輸出表以及系統功能結構圖。
2.1.2資料流圖基本元素與資料流圖
外部實體:存在於軟體系統之外的人員或組織(正方形或立方體表示)。
加工:資料處理,表示輸入資料在此進行變換,產生輸出資料(圓角巨型或圓形表示)。
資料流:表示流動著的資料(箭頭線表示)。
資料存放區:用來表示要儲存的資料(開門矩形或兩條平行橫線表示)。
訂單處理系統頂層流程圖:
0層資料流圖:
2.3資料庫設計2.3.1概念結構設計
- 對事務加以抽象以E-R圖的形式描述出來
- E-R圖(實體聯絡圖):包括實體,聯絡,屬性
實體:現實中的事物例如,學生,老師
聯絡:兩個實體之間的關係,1:1、1:N、M:N三種關係
屬性:實體所具有的屬性,例如 學生的學號、姓名、性別等
例如:一個學生屬於一個班級,一個班級擁有多名學生,E-R圖如下
網上購物系統E-R圖,該系統資料之間存在下列約束
- 一個客戶(編號唯一)可以擁有多個訂單,每個訂單僅屬於一個客戶。
- 一個訂單(編號唯一)可以包含多個訂購細目,每個訂購細目只屬於一個訂單。
- 一個商品可以出現多個訂購細目中,一個訂購細目只包含多個商品。
- 一個商品類別可以包含多種商品,一種商品只屬於一個商品類別。
圖2.2
2.3.2邏輯結構設計2.3.2.1E-R圖轉換成關係模式
將每個實體轉換成一個關係模式,實體的屬性即關係模式的屬性,實體的標識即關係模式的鍵。
- 根據規則合并E-R圖中的1:1,1:N,M:N之間的聯絡
- 若實體的聯絡是(1:1),則可以將兩個實體轉換成兩個關係模式,任意一個關係模式的屬性中加入另一個關係模式的主鍵(作為外鍵)和聯絡自身的屬性
- 若實體間的聯絡是一對多(1:n),則將n端的實體類型轉換成關係模式中加入1端實體類型的主鍵(作為外鍵)和聯絡類型的屬性。
- 若實體間的聯絡是多對多(m:n),則將聯絡類型也轉換成關係模式,其屬性為2實體類型的主鍵(作為外鍵)加上聯絡類型自身的屬性,而該關係模式的主鍵為2端實體主鍵的組合。
- 若關係模式是1:1:1的關係,轉換原則同1:1
- 若關係模式是1:1:n的聯絡,轉換原則同1:n
- 若關係模式是1:n:m的聯絡,則可以將聯絡類型也轉換成關係模式,其屬性為m端和n端實體類型的主鍵(作為外鍵)加上聯絡類型自身的屬性,而關係模式的主鍵為n和m端實體主鍵的組合
- 若關係模式是n:m:p的聯絡,轉換規則同m:n
根據E-R圖實體之間的聯絡可以轉換成以下關係模式:
客戶(客戶編碼,姓名,電話,E-mail)。關係的主鍵:客戶編碼;外鍵:無
訂單(訂單編號,訂購時間,客戶編碼)。關係的主鍵:訂單編號;外鍵:客戶編碼
訂購細目(訂購明細編號,訂購數量,支付金額,訂單編號)。關係主鍵:訂購明細編號;外鍵:訂單編號。
出現(訂購明細編號,商品編號,類型)。關係的主鍵:訂購明細編號,商品編號;外鍵:訂購明細編號,商品編號。
商品:(商品編號,商品名稱,單價,生產日期,商品類別號,商品類別名)。關係的主鍵:商品編號;外鍵:無
在關係模式設計中可能會出現以下幾個問題:資料冗餘、資料修改不一致、資料插入異常、資料刪除異常,所以提出範式的要求,目的就是最低限度地冗餘,避免插入、刪除、修改異常。
2.3.2.2範式
主屬性:包含鍵的所有屬性。
- 關係模式要求達到4NF (減少冗餘,消除操作異常)
第一範式(1NF):若關係模式R的每一個分量是不可分的資料項目,則關係模式屬於第一範式。即每個屬性都是不可拆分的.
第二範式(2NF):R屬於1NF,且每一個非主屬性完全依賴於鍵(沒有部分依賴),則R屬於2NF
例如:選課關係(學號,課程號,成績,學分)
該關係的主鍵是(學號,課程號),但是課程號→學分,所以學分屬性部分依賴於主鍵,即關係部滿足第二範式,可以拆分為(學號,課程號,成績),(課程號,學分)兩個關係
第三範式(3NF):R屬於2NF,且每個非主屬性即不部分依賴於碼,也不傳遞依賴於碼
例如:學生關係(學號,姓名,所屬系,系地址)
該關係的主鍵是:學號
學號→所屬系,所屬系→學號,所屬系→系地址;根據函數的依賴公理,系地址傳遞函數依賴於學號,即關係不滿足第三範式,可以拆分關係為(學號,姓名,所屬系),(所屬系,系地址)
如果不拆分會存在資料修改異常,比如該學生的換了系,修改了所屬系,但是系地址沒有修改,這樣就造成了修改異常
BCNF:R屬於3NF,且不存在主屬性對碼的部分和傳遞函數依賴
例如:關係R(零件號,零件名,廠商名),如果設定每種零件號只有一個零件名,但不同的的零件號可以有相同的零件名,每種零件可以有多個廠商生產,但每家廠商生產的零件應有不同的零件名。這樣可以得到:
零件號→零件名,(廠商名,零件名)→零件號
所以主屬性包括(零件號,廠商名,零件名),但是“零件名”傳遞依賴於碼“廠商名,零件名”,所以關係R不滿足BCNF,當一個零件由多個生產廠商生產時,由於零件號只有一個而零件名根據廠商不同而又多個,零件名與零件號之間的聯絡將多次重複,帶來資料冗餘和操作異常現象
可以將關係分解為(零件號,廠商名),(零件號,零件名)
4NF:關係模式R屬於1NF,若對於R的每個非平凡多值依賴X→→Y且Y不包含於X時,X必含碼,則R屬於4NF
5NF:對關係進行投影,消除關係中不是由候選碼所蘊含的串連依賴
對於上面的商品關係,由於關係的主鍵是商品編號,而商品類別號→商品類別名
所以商品關係部滿足第三範式,非主屬性商品類別名傳遞依賴於商品編號,會存在資料冗餘,資料修改異常問題。將商品關係分解為:
商品(商品編號,商品名稱,單價,生產日期,商品類別號)
商品類別(商品類別號,商品類別名)
2.3.3物理結構設計
為一個給定的邏輯資料模型設計一個最合適應用要求的物理結構的過程
- 資料庫的建立
- 資料表的建立
- 索引的建立
- 視圖的建立
- 觸發器的建立
- 預存程序設計
- 使用者自訂函數設計
- 對關係模式的資料項目加以約束,如檢查約束、主鍵約束、參照完整性條件約束以保證資料正確性
2.4應用程式設計
採用進階語言以結構化設計方法或物件導向方法進行設計
2.5系統實現
3.最佳化策略3.1.查詢最佳化策略
- 儘可能地減少多表查詢或建立物化視圖
- 只檢索需要的列
- 用帶IN的條件字句等級替換or字句
- 經常提交COMMIT,以儘早釋放鎖
3.2表設計
1.如果頻繁地訪問涉及的是對兩個相關的表進行串連操作,則考慮將其合并
2.如果頻繁地訪問只是在表中的某一部分欄位上進行,則考慮分解表,將該部分單獨作為一個表
3.對於很少更新的表,引入物化視圖
4. 當系統中有一些少量的,重複出現的值時,使用字典表來節約儲存空間和最佳化查詢。如地區、系統中使用者類型的代號等。這類值不會在程式的運行期變化,但是需要儲存在資料庫中。
就地區而言,如果我們要查詢某個地區的記錄,則資料庫需要通過字串匹配的方式來查詢;如果將地區改為一個地區的代號儲存在表中,查詢時通過地區的代號來查詢,則查詢的效率將大大提高。
程式中宜大量的使用字典表來表示這類值。字典表中儲存這類值的代號和實體的集合,以外鍵的方式關聯到使用這類值的表中。然而,在編碼階段,程式員並不使用字典表,因為首先查詢字典表中實體的代號,違背了提高查詢效率的初衷。程式員在資料字典的協助下,直接使用代號來代表實體,從而提高效率。
雖然字典表在實際上並不使用,但是仍應該保留在資料庫中(起碼是在開發期內保留)。字典表作為另一種形式上的“資料字典文檔”出現,以說明資料庫中哪些表的哪些欄位是使用了字典表的。
為了提高資料庫的資料完整性,在開發階段可以保留完整的字典表和普通表的外鍵約束。但是在資料庫的運行階段,應該將普通表和字典表的外鍵刪除,以提高運行效率,特別是某些表使用了很多字典表的情況。
案例:某資料庫中有百萬條使用者資訊,應用系統中常常需要按照地區要查詢使用者的資訊。使用者資訊表以前是按照具體的地區名稱來儲存的,現在將具體的名稱改為字典表中的地區代號,查詢效率大大提高。
3.3索引
- 如果查詢是瓶頸,則在關係上建立適當的索引;通常,作為查詢條件的屬性上建立索引可以提高查詢效率。
- 如果更新是瓶頸,因為每次更新都會重建表上的索引,引起效率降低,則考慮刪除某些索引。
- 選擇適當索引,如果經常使用範圍查詢,則B樹索引比散列索引更高效
- 將有利於大多數查詢和更新的索引設為聚集性索引。
3.4提高IO效率
- 索引檔案和資料檔案分開儲存,交易記錄檔儲存在高速裝置上
- 經常修改資料檔案和索引檔案的頁面大小
- 定期對資料進行排序
- 增加必要的索引項目
4.資料庫命名規範4.1資料庫物件
對象 |
首碼 |
資料庫 |
無 |
表 |
無 |
視圖 |
VI |
索引 |
IX |
預存程序 |
SP |
函數 |
FN |
觸發器 |
TR |
自訂資料類型 |
ud |
Default |
DF |
主鍵 |
pk |
外鍵 |
FK |
rule |
ru |
序列 |
Sq |
UNIQUE |
uq |
資料庫物件採用26個英文字母(區分大小寫)和0-9這十個自然數,加上底線_組成,共63個字元。不能出現其他字元(注釋除外)。
同一個資料庫中這些對象名都是不能重複
C CHECK_CONSTRAINT
D DEFAULT_CONSTRAINT
F FOREIGN_KEY_CONSTRAINT
IT INTERNAL_TABLE
P SQL_STORED_PROCEDURE
PK PRIMARY_KEY_CONSTRAINT
S SYSTEM_TABLE
SQ SERVICE_QUEUE
TR SQL_TRIGGER
U USER_TABLE
UQ UNIQUE_CONSTRAINT
V VIEW
4.2命名規範規定
1.表名使用單數名
例如:對儲存客人資訊的表(Customer)不使用Customers
2.避免無謂的表格尾碼
1、 表是用來儲存資料資訊的,表是行的集合。那麼如果表名已經能夠很好地說明其包含的資料資訊,就不需要再添加體現上面兩點的尾碼了。
2、 GuestInfo(儲存客戶資訊)應寫成Guest,FlightList(儲存航班資訊的表)應寫成Flight
3.所有表示時間的欄位,統一以 Date 來作為結尾(而不是有的使用Date,有的使用Time)
以大家都熟悉的論壇來說,需要記錄會員最後一次登入的時間,這時候一般人都會把這個欄位命名為LoginTime 或者 LoginDate。這時候,已經產生了一個歧義;如果僅看錶的欄位名稱,不去看錶的內容,很容易將LoginTime理解成登入的次數,因為,Time還有一個很常用的意思,就是次數
4.所有表示數目的欄位,都應該以Count作為結尾
5.所有代錶鏈接的欄位,均為Url結尾
6.所有名稱的字元範圍為:A-Z, a-z, 0-9 和_(底線)。不允許使用其他字元作為名稱。
7.採用英文單詞或英文短語(包括縮寫)作為名稱,不能使用無意義的字元或漢語拼音。
8.名稱應該清晰明了,能夠準確表達事物的含義,最好可讀,遵循“見名知意”的原則。
4.3資料庫命名規範
資料庫名稱不需要簡寫,根據實際意義來命名。例如:ReportServer
資料庫名:ReportServer
邏輯資料名:ReportServer;邏輯日誌名:ReportServer_log
物理資料名:ReportServer.mdf;物理日誌名:ReportServer_log.LDF
CREATE DATABASE [ReportServer] ON PRIMARY
( NAME = N‘ReportServer‘, FILENAME = N‘D:\Microsoft SQL Server\MSSQL10.MSSQLSERVER\MSSQL\useData\ReportServer.mdf‘ , SIZE = 3328KB , MAXSIZE = UNLIMITED, FILEGROWTH = 1024KB )
LOG ON
( NAME = N‘ReportServer_log‘, FILENAME = N‘D:\Microsoft SQL Server\MSSQL10.MSSQLSERVER\MSSQL\useData\ReportServer_log.LDF‘ , SIZE = 6400KB , MAXSIZE = 2048GB , FILEGROWTH = 10%)
GO
注意:避免所有資料庫的邏輯名稱使用相同的名稱。
4.4表設計命名規範
注意欄位名不能使用保留關鍵字:如action,avg等
1、不使用tab或tbl作為表首碼(本來就是一個表,為什麼還要說明)
2、表名以代表表內的內容的一個和多個名片語成,以底線分隔,每個名詞的第一個字母大寫,例如:User、UserLogin,UserGroupRelation等
3、使用表的內容分類作為表名的首碼:如,與使用者資訊相關的表使用首碼User,與內容相關的資訊使用首碼Content。
4、表的首碼以後,是表的具體內容的描述。如:使用者登入資訊的表名為:UserLogin,使用者在論壇中的資訊的表名為:UserBBSInfo
5、一些作為多對多串連的表,可以使用兩個表的首碼作為表名:
如:使用者登入表UserLogin,使用者分組表GroupInfo,這兩個表建立多對多關係的表名為:UserGroupRelation
4.4.1欄位命名規範
- 欄位名不要存在無用首碼,例如表‘WeiXinConfig’,既然我已經知道這張表是關於的表,裡面的名稱欄位可以可以使用Name,不需要添加無用的首碼類似‘WeiXinName’,‘WeiXinGuanZhuMsg’,‘WeiXinUpImgMsg’等
- 欄位使用實際英文翻譯作為命名欄位,見名知意,不要使用讓人看了半天都不知道是啥意思的欄位(類似:lev1,lev2…)
4.5預存程序命名
預存程序名=[SP_]+[表名]+[操作名字]
[操作名字]=[insert|delete|update|calculate|confirm]
例如:SP_community_update
4.5.1隻允許應用程式通過預存程序訪問資料庫
只允許應用程式通過預存程序訪問資料庫,而不允許直接在代碼中寫SQL語句訪問資料庫。
在資料庫開發項目中,大量使用預存程序有很多的好處,首先看微軟提供資訊:
使用 SQL Server 中的預存程序而不使用儲存在客戶電腦本地的 Transact-SQL 程式的優勢有: 允許模組化程式設計: 只需建立過程一次並將其儲存在資料庫中,以後即可在程式中調用該過程任意次。預存程序可由在資料庫編程方面有專長的人員建立,並可獨立於程式原始碼而單獨修改。 允許更快執行: 如果某操作需要大量 Transact-SQL 代碼或需重複執行,預存程序將比 Transact-SQL 批代碼的執行要快。將在建立預存程序時對其進行分析和最佳化,並可在首次執行該過程後使用該過程的記憶體中版本。每次運行 Transact-SQL 陳述式時,都要從用戶端重複發送,並且在 SQL Server 每次執行這些語句時,都要對其進行編譯和最佳化。 減少網路流量: 一個需要數百行 Transact-SQL 代碼的操作由一條執行過程代碼的單獨語句就可實現,而不需要在網路中發送數百行代碼。 可作為安全機制使用: 即使對於沒有直接執行預存程序中語句的許可權的使用者,也可授予他們執行該預存程序的許可權。 |
除此以外,使用預存程序的好處還有:
1、 在邏輯上,預存程序將應用程式層和資料庫物理結構分離開來。預存程序形成了一個應用程式和資料庫之間的介面。這樣的介面抽象了複雜的資料庫結構,符合極限編程中“基於介面編程”的思想。
2、 將主要的商務邏輯封裝在預存程序中,能夠避免在應用程式層寫大量的代碼(在應用程式中通過字串插入太長的SQL語句影響效率,而且維護困難)。有助於提高開發效率,並且直接在查詢分析器中調試預存程序,能夠更早的發現系統中的邏輯問題,從而提高代碼的品質。
3、 在網站一類的應用系統中,SQL注入式漏洞一直是難以完全杜絕的漏洞。如果只通過預存程序來訪問資料庫,能夠大大減少這類安全性問題。(因此,就算是簡單的只有一句的SQL語句,也應該寫成預存程序。)
4、 由於採用預存程序,應用程式的層面可以不關心具體的資料庫結構,而只關心預存程序的介面調用。因此,在以下一些情況,預存程序的優勢非常明顯:
·需求變更,表的結構必須要改變。使用預存程序,只要參數不變,我們就只需要修改相應的預存程序,而不需要修改應用程式的代碼。這樣的設計將減小需求變更對項目的影響。
·為提高效率,使部分欄位冗餘:一些經常性訪問的欄位,我們可以在相關的表中進行冗餘儲存。這樣既提高了效率,又通過預存程序屏蔽了冗餘細節。
·為提高效率,使用冗餘表(拆分表):一些大的表,為了提高查詢效率,可能需要將記錄分別儲存到多個表中去。使用預存程序,有預存程序來決定從哪些拆分的表中擷取或插入資料。這樣提高了效率,又不必在應用程式層面關心具體的拆分規則。
5、 使用預存程序,便於在項目後期或者運行中集中最佳化系統效能。在項目開發過程中,由於各種原因,往往無法編寫高效的代碼,這個問題常常在項目後期或者在運行期體現出來。通過預存程序來封裝對資料庫的訪問,可以在項目整合以後,通過試運行觀察系統的運行效率,從而很容易找出系統的瓶頸,並能夠通過最佳化預存程序的代碼來提高系統的運行效率。這樣的最佳化,比在運用程式中最佳化更有效,更容易。
同時,過多的使用預存程序,也存在以下一些疑慮:
問題一:預存程序編譯後,將作為資料庫的全域對象儲存,太多的預存程序將佔用大量的資料庫伺服器的記憶體。
問題二:在預存程序中實現大量的邏輯,將使大量的運算在資料庫伺服器上完成,而不是在應用伺服器上完成。當訪問量很大的時候,會大大消耗資料庫伺服器的CPU佔用率。
在此還存在這個一個案例:有一個訪問量巨大的網站,有多台WEB伺服器構成一個負載平衡的伺服器叢集,但是只有一台中心的資料庫伺服器。當訪問量持續增加的時候,接入更多的WEB伺服器來滿足高並發量的訪問;但是資料庫伺服器卻沒辦法一直增加。因此,就需要盡量在WEB伺服器上完成商務邏輯,盡量避免消耗資料庫伺服器的資源。
對於這兩個擔心,我的想法是:
問題一的解決:預存程序是經過編譯後的SQL語句,在記憶體中是二進位的代碼,並不會消耗太多記憶體。並且,預存程序比起直接使用SQL語句來說,效率大大提高。換個角度來說,這是一個“以空間換時間”的方案,多消耗一點記憶體來換取效率的提高,是值得的。
問題二的解決:首先,在實現商務邏輯的問題上,在預存程序中實現比在應用程式中實現更容易;其次,從開發效率上,預存程序的開發比應用程式更簡單(就完成相同邏輯而言)。在高訪問量的系統中,應用伺服器和資料庫伺服器的資源分派的問題,應該從成本的角度來開率:軟體開發中的成本,人工支出的費用遠遠高於硬體支出的成本。我們可以很容易花錢購買更好的伺服器,但是很難花錢讓開發人員使程式有大幅度的提高。
使用預存程序來封裝商務邏輯,首先節省的是大量的開發時間和調試時間,並能夠大大提高代碼的品質。因此,從成本來說,應該使用預存程序。
對於大訪問量的情況,最簡單的辦法是投入更多的硬體成本:更快的硬碟,更大的記憶體和更多的CPU,還有更好的網卡…………等等。
其次,在應用程式的層面,可以大量的使用靜態檔案快取的辦法來減輕資料庫的壓力。如:不經常變化的資訊,可以從資料庫伺服器中讀取,儲存為應用伺服器上的XML靜態檔案等。
實在不行的話,應該在系統設計之初,考慮可能的訪問量,將系統設計成分布式的。這樣就能從根本上解決大訪問量的問題。
4.5.2命名規範
1、預存程序的首碼和表名的首碼類似:把一系列表看成一個對象,欄位為對象的屬性,預存程序則為訪問對象的方法。如:添加使用者的預存程序取名為:User_AddUser
2、預存程序使用模組的首碼來命名。如,使用者管理的預存程序使用首碼user_。
3、預存程序的首碼之後,是動詞+名詞形式的預存程序名(也可以是動詞短語)。
4.5.3預存程序的參數命名
1、參數名採用匈牙利命名法,使用類型的首碼
2、每個預存程序都有:@errno int和@errmsg varchar(255)兩個輸出參數。應用程式中可以根據這兩個參數得到預存程序執行的情況。(這兩個參數使用預設值,可以忽略)
errno為整型的錯誤資訊代碼,執行成功返回0。Errno的值的具體含義通過errmsg參數說明,或者通過代碼中的注釋或文檔。
Errmsg為錯誤資訊的字串描述,這個參數主要用於調試期作為說明,避免在應用程式中使用該值。同時,要注意英文版系統和中文版系統中,資訊的語言選擇對程式的影響。
4.5.4預存程序返回的記錄集
1、預存程序的輸出記錄集:為程式的結構清晰,預存程序最好只返回一個記錄集。但在某些為了提高效能的場合,還是可以輸出多個記錄集
2、記錄集中,每個輸出的欄位最後都指定欄位的別名,以面真實的欄位名資訊流失到用戶端,從而加大駭客找到系統漏洞的可能。
4.5.5格式約定
1、 所有SQL關鍵字大寫
2、 使用良好的變數命名規範
3、 保持良好的結構,包括空行、縮排和空格等。
4、 塊狀的語句,一定要寫上BEGIN…END
5、 在每個預存程序的開頭加上詳細的注釋:包括預存程序名稱、參數說明、功能說明、返回資料集說明、以及作者和著作權聲明。
6、 每個預存程序內的代碼前後必須加上SET NOCOUNT ON 和SET NOCOUNT OFF。
7、 預存程序格式的樣本如下:
CREATE PROCEDURE SP_User_update
(
@Options VarChar(100),
@strUserName varchar(20),
@strPwd varchar(50),
@errno int = 0 OUTPUT,
@errmsg varchar(255)=NULL OUTPUT
)
AS
BEGIN
IF @Options=‘UP1‘
BEGIN
SET NOCOUNT ON
/*以下是預存程序的代碼*/
SET NOCOUNT OFF
END
IF @Options=‘UP2‘
BEGIN
SET NOCOUNT ON
/*以下是預存程序的代碼*/
SET NOCOUNT OFF
END
END
4.6視圖命名
一個資料庫中的視圖名不能重複
視圖名=VI(首碼)+[表名]..[表名]+[描述]
4.7主鍵命名
一個資料庫中的主鍵名不能重複
主鍵名=PK_(首碼)+[表名]
例如:pk_Community
4.8外鍵命名
一個資料庫中的外鍵名不能重複
外鍵名=FK_(首碼)+[主表名]+[從表名]+[欄位名]
考慮這樣一個關係,表Hotel,欄位Id, Name, CityId。表City,欄位Id,Name。因為一個城市可能有好多家酒店,所以是一個一對多的關係,City是主表(1方),Hotel是從表(多方)。在Hotel表中,CityId是做為外鍵使用。
在實現外鍵的時候我們可以這樣寫:
ALTER TABLE HotelInfo
ADD CONSTRAINT FK_Hotel_City_Cityid FOREIGN KEY (CityID) REFERENCES City(ID)
4.9觸發器命名
- 首碼(tr),描述了資料庫物件的類型。
- 基本部分,描述觸發器所加的表。
- 尾碼(_I、_U、_D),顯示了修改語句(Insert, Update及Delete)
觸發器名=TR_(首碼)+[表名]+[ _I、_U、_D]+[欄位\描述]
例如:TR _Communtiy_u_name(對錶community的欄位name進行更新)
4.10 default約束
使用格式如:DF_[表名]_[列名]
例如:DF _Community_Age
4.11CHECK 條件約束
格式:CK_[表名]_[列名]
例如:CK_Community_Number
4.12UNIQUE約束
格式:uq_[表名]_[列名]
例如:uq_Community_Name
4.13欄位命名規範
1、欄位不使用任何首碼(表名代表了一個名稱空間,欄位前面再加首碼顯得羅嗦)
2、字典名也避免採用過於普遍過於簡單的名稱:例如,使用者表中,使用者名稱的欄位為UserName比Name更好。
3、布爾型的欄位,以一些助動詞開頭,更加直接生動:如,使用者是否有留言HasMessage,使用者是否通過檢查IsChecked等。
4、欄位名為英文短語、形容詞+名詞或助動詞+動詞時態的形式表示,大小寫混合,遵循“見名知意”的原則。
4.14 SQL語句規範
1、不允許寫SELECT * FROM ……,必須指明需要讀取的具體欄位。
2、不允許在應用程式代碼中直接寫SQL語句訪問資料庫。
3、避免在一行內寫太長的SQL語句,在SQL關鍵字的地方將SQL語句分成多行會更加清晰。
如:SELECT UserID,UserName,UserPwd FROM User_Login WHERE AreaID=20
修改成:
SELECT UserID,UserName,UserPwd
FROM User_Login
WHERE AreaID=20
更加直觀
4、在一些塊形式的SQL語句中,就算只有一行代碼,也要加上BEGIN…END塊。
如:IF EXISTS(…)
SET @nVar = 100
應該寫成:
IF EXISTS(…)
BEGIN
SET @nVar = 100
END
5、SQL批處理語句的空行和縮排與一般的結構化程式語言一致,應該保持良好的代碼格式。
6、所有的SQL關鍵字大寫
4.15遊標使用約定
1、 若無必要,不要使用遊標
2、 包含遊標的預存程序,必須對效能進行認真測試。
4.16索引命名規範
對於資料庫的維護建索引是很平常的事情,但是如果沒有一個正常化的命名,我們對於一個表的諸多索引可能需要花上一段時間的瞭解。
- 如果表中存在主鍵預設情況下,表的聚集性索引也就是主鍵列,主鍵的命名前面已經有提到過,索引名也跟主鍵名一樣,(Pk_表名)
- 對於表上的非叢集索引,建議使用(IX0_表名,IX1_表名)….,這樣下去,這樣也很清晰地表達了索引,對於很多命名文章上提到的需要詳細表達出具體的列,我個人覺得沒有必要,首先叢集索引經常涉及多列,很難羅列出所有列;還有影響美觀
當你執行SELECT NAME FROM SYS.COLUMNS 查詢索引時,你根據NAME名很快就知道索引來自那張表,是否是非叢集索引,而不用根據OBJECTID列去跟對象表關聯。
4.17函數命名規範
函數命名分兩類:1.針對對象的函數,2.用作協助工具功能操作的函數(不針對具體的資料庫物件)
- 第一類命名:FN_+[User]+_+[對象名] 例如:FN_User_Student(對於Student進行操作函數)
- 第二類命名:FN_[具體函數解釋] 例如:FN_Spit(對欄位進行拆分函數)
SQL Server資料庫設計規範