對象數據庫 |
前綴編程 |
數據庫緩存 |
無安全 |
表服務器 |
無微信 |
視圖網絡 |
VI併發 |
索引負載均衡 |
IX分佈式 |
存儲過程 |
SP |
函數 |
FN |
觸發器 |
TR |
自定義數據類型 |
ud |
Default |
DF |
主鍵 |
pct. |
外鍵 |
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
1.表名使用單數名
例如:對用戶信息的表(User)不使用Users
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.名稱應該清晰明瞭,可以準確表達事物的含義,最好可讀,遵循「見名知意」的原則。
爲避免沒法達到「見名知意」的效果,表和字段的都須要添加備註(MS_Description)
9.爲避免關鍵詞衝突,全部字段使用f開頭。例如 用戶Id(fUserId)
數據庫名稱不須要簡寫,根據實際意義來命名。例如: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
注意:避免全部數據庫的邏輯名稱使用相同的名稱。
注意字段名不能使用保留關鍵字:如action,avg等
一、不使用tab或tbl做爲表前綴(原本就是一個表,爲何還要說明)
二、表名以表明表內的內容的一個和多個名詞組成,如下劃線分隔,每一個名詞的第一個字母大寫,例如:User、UserLogin,UserGroupRelation等
三、使用表的內容分類做爲表名的前綴:如,與用戶信息相關的表使用前綴User,與內容相關的信息使用前綴Content。
四、表的前綴之後,是表的具體內容的描述。如:用戶登陸信息的表名爲:UserLogin,用戶在論壇中的信息的表名爲:UserBBSInfo
五、一些做爲多對多鏈接的表,可使用兩個表的前綴做爲表名:
如:用戶登陸表UserLogin,用戶分組表GroupInfo,這兩個表創建多對多關係的表名爲:UserGroupRelation
1. 字段名不要存在無用前綴,例如表‘WeiXinConfig’,既然我已經知道這張表是關於微信的表,裏面的名稱字段可使用Name,不須要添加無用的前綴相似‘WeiXinName’,‘WeiXinGuanZhuMsg’,‘WeiXinUpImgMsg’等
2. 字段使用實際英文翻譯做爲命名字段,見名知意,不要使用讓人看了半天都不知道是啥意思的字段(相似:lev1,lev2…)
存儲過程名=[SP_]+[表名]+[操做名字]
[操做名字]=[insert|delete|update|calculate|confirm]
例如:SP_community_update
只容許應用程序經過存儲過程訪問數據庫,而不容許直接在代碼中寫SQL語句訪問數據庫。
在數據庫開發項目中,大量使用存儲過程有不少的好處,首先看微軟提供信息:
使用 SQL Server 中的存儲過程而不使用存儲在客戶計算機本地的 Transact-SQL 程序的優點有: 容許模塊化程序設計: 只需建立過程一次並將其存儲在數據庫中,之後便可在程序中調用該過程任意次。存儲過程可由在數據庫編程方面有專長的人員建立,並可獨立於程序源代碼而單獨修改。 容許更快執行: 若是某操做須要大量 Transact-SQL 代碼或需重複執行,存儲過程將比 Transact-SQL 批代碼的執行要快。將在建立存儲過程時對其進行分析和優化,並可在首次執行該過程後使用該過程的內存中版本。每次運行 Transact-SQL 語句時,都要從客戶端重複發送,而且在 SQL Server 每次執行這些語句時,都要對其進行編譯和優化。 減小網絡流量: 一個須要數百行 Transact-SQL 代碼的操做由一條執行過程代碼的單獨語句就可實現,而不須要在網絡中發送數百行代碼。 可做爲安全機制使用: 即便對於沒有直接執行存儲過程當中語句的權限的用戶,也可授予他們執行該存儲過程的權限。
|
除此之外,使用存儲過程的好處還有:
一、 在邏輯上,存儲過程將應用程序層和數據庫物理結構分離開來。存儲過程造成了一個應用程序和數據庫之間的接口。這樣的接口抽象了複雜的數據庫結構,符合極限編程中「基於接口編程」的思想。
二、 將主要的業務邏輯封裝在存儲過程當中,可以避免在應用程序層寫大量的代碼(在應用程序中經過字符串插入太長的SQL語句影響效率,並且維護困難)。有助於提升開發效率,而且直接在查詢分析器中調試存儲過程,可以更早的發現系統中的邏輯問題,從而提升代碼的質量。
三、 在網站一類的應用系統中,SQL注入式漏洞一直是難以徹底杜絕的漏洞。若是隻經過存儲過程來訪問數據庫,可以大大減小這類安全性問題。(所以,就算是簡單的只有一句的SQL語句,也應該寫成存儲過程。)
四、 因爲採用存儲過程,應用程序的層面能夠不關心具體的數據庫結構,而只關心存儲過程的接口調用。所以,在如下一些狀況,存儲過程的優點很是明顯:
·需求變動,表的結構必需要改變。使用存儲過程,只要參數不變,咱們就只須要修改相應的存儲過程,而不須要修改應用程序的代碼。這樣的設計將減少需求變動對項目的影響。
·爲提升效率,使部分字段冗餘:一些常常性訪問的字段,咱們能夠在相關的表中進行冗餘存儲。這樣既提升了效率,又經過存儲過程屏蔽了冗餘細節。
·爲提升效率,使用冗餘表(拆分表):一些大的表,爲了提升查詢效率,可能須要將記錄分別保存到多個表中去。使用存儲過程,有存儲過程來決定從哪些拆分的表中獲取或插入數據。這樣提升了效率,又沒必要在應用程序層面關心具體的拆分規則。
五、 使用存儲過程,便於在項目後期或者運行中集中優化系統性能。在項目開發過程當中,因爲各類緣由,每每沒法編寫高效的代碼,這個問題經常在項目後期或者在運行期體現出來。經過存儲過程來封裝對數據庫的訪問,能夠在項目集成之後,經過試運行觀察系統的運行效率,從而很容易找出系統的瓶頸,並可以經過優化存儲過程的代碼來提升系統的運行效率。這樣的優化,比在運用程序中優化更有效,更容易。
同時,過多的使用存儲過程,也存在如下一些疑慮:
問題一:存儲過程編譯後,將做爲數據庫的全局對象保存,太多的存儲過程將佔用大量的數據庫服務器的內存。
問題二:在存儲過程當中實現大量的邏輯,將使大量的運算在數據庫服務器上完成,而不是在應用服務器上完成。當訪問量很大的時候,會大大消耗數據庫服務器的CPU佔用率。
在此還存在這個一個案例:有一個訪問量巨大的網站,有多臺WEB服務器構成一個負載均衡的服務器羣集,可是隻有一臺中心的數據庫服務器。當訪問量持續增長的時候,接入更多的WEB服務器來知足高併發量的訪問;可是數據庫服務器卻沒辦法一直增長。所以,就須要儘可能在WEB服務器上完成業務邏輯,儘可能避免消耗數據庫服務器的資源。
對於這兩個擔憂,個人想法是:
問題一的解決:存儲過程是通過編譯後的SQL語句,在內存中是二進制的代碼,並不會消耗太多內存。而且,存儲過程比起直接使用SQL語句來講,效率大大提升。換個角度來講,這是一個「以空間換時間」的方案,多消耗一點內存來換取效率的提升,是值得的。
問題二的解決:首先,在實現業務邏輯的問題上,在存儲過程當中實現比在應用程序中實現更容易;其次,從開發效率上,存儲過程的開發比應用程序更簡單(就完成相同邏輯而言)。在高訪問量的系統中,應用服務器和數據庫服務器的資源分配的問題,應該從成本的角度來開率:軟件開發中的成本,人工支出的費用遠遠高於硬件支出的成本。咱們能夠很容易花錢購買更好的服務器,可是很難花錢讓開發人員使程序有大幅度的提升。
使用存儲過程來封裝業務邏輯,首先節省的是大量的開發時間和調試時間,並可以大大提升代碼的質量。所以,從成原本說,應該使用存儲過程。
對於大訪問量的狀況,最簡單的辦法是投入更多的硬件成本:更快的硬盤,更大的內存和更多的CPU,還有更好的網卡…………等等。
其次,在應用程序的層面,能夠大量的使用靜態文件緩存的辦法來減輕數據庫的壓力。如:不常常變化的信息,能夠從數據庫服務器中讀取,保存爲應用服務器上的XML靜態文件等。
實在不行的話,應該在系統設計之初,考慮可能的訪問量,將系統設計成分佈式的。這樣就能從根本上解決大訪問量的問題。
一、存儲過程的前綴和表名的前綴相似:把一系列表當作一個對象,字段爲對象的屬性,存儲過程則爲訪問對象的方法。如:添加用戶的存儲過程取名爲:User_AddUser
二、存儲過程使用模塊的前綴來命名。如,用戶管理的存儲過程使用前綴user_。
三、存儲過程的前綴以後,是動詞+名詞形式的存儲過程名(也能夠是動詞短語)。
一、參數名採用匈牙利命名法,使用類型的前綴
二、每一個存儲過程都有:@errno int和@errmsg varchar(255)兩個輸出參數。應用程序中能夠根據這兩個參數獲得存儲過程執行的狀況。(這兩個參數使用默認值,能夠忽略)
errno爲整型的錯誤信息代碼,執行成功返回0。Errno的值的具體含義經過errmsg參數說明,或者經過代碼中的註釋或文檔。
Errmsg爲錯誤信息的字符串描述,這個參數主要用於調試期做爲說明,避免在應用程序中使用該值。同時,要注意英文版系統和中文版系統中,信息的語言選擇對程序的影響。
一、存儲過程的輸出記錄集:爲程序的結構清晰,存儲過程最好只返回一個記錄集。但在某些爲了提升性能的場合,仍是能夠輸出多個記錄集
二、記錄集中,每一個輸出的字段最後都指定字段的別名,以面真實的字段名信息流失到客戶端,從而加大黑客找到系統漏洞的可能。
一、 全部SQL關鍵字大寫
二、 使用良好的變量命名規範
三、 保持良好的結構,包括空行、縮進和空格等。
四、 塊狀的語句,必定要寫上BEGIN…END
五、 在每一個存儲過程的開頭加上詳細的註釋:包括存儲過程名稱、參數說明、功能說明、返回數據集說明、以及做者和版權聲明。
六、 每一個存儲過程內的代碼先後必須加上SET NOCOUNT ON 和SET NOCOUNT OFF。
七、 存儲過程格式的示例以下:
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
一個數據庫中的視圖名不能重複
視圖名=VI(前綴)+[表名]..[表名]+[描述]
一個數據庫中的主鍵名不能重複
主鍵名=PK_(前綴)+[表名]
例如:PK_Community
一個數據庫中的外鍵名不能重複
外鍵名=FK_(前綴)+[主表名]+[從表名]+[字段名]
考慮這樣一個關係,表Hotel,字段fId, fName, fCityId。表fCity,字段fId,fName。由於一個城市可能有好多家酒店,因此是一個一對多的關係,fCity是主表(1方),fHotel是從表(多方)。在fHotel表中,fCityId是作爲外鍵使用。
在實現外鍵的時候咱們能夠這樣寫:
ALTER TABLE HotelInfo
ADD CONSTRAINT FK_Hotel_City_Cityid FOREIGN KEY (CityID) REFERENCES City(ID)
1. 前綴(tr),描述了數據庫對象的類型。
2. 基本部分,描述觸發器所加的表。
3. 後綴(_I、_U、_D),顯示了修改語句(Insert, Update及Delete)
觸發器名=TR_(前綴)+[表名]+[ _I、_U、_D]+[字段\描述]
例如:TR _Communtiy_u_name(對錶community的字段name進行更新)
使用格式如:DF_[表名]_[列名]
例如:DF _Community_Age
格式:CK_[表名]_[列名]
例如:CK_Community_Number
格式:UQ_[表名]_[列名]
例如:UQ_Community_Name
一、字段不使用任何前綴(表名錶明瞭一個名稱空間,字段前面再加前綴顯得羅嗦)
二、字典名也避免採用過於廣泛過於簡單的名稱:例如,用戶表中,用戶名的字段爲UserName比Name更好。
三、布爾型的字段,以一些助動詞開頭,更加直接生動:如,用戶是否有留言HasMessage,用戶是否經過檢查IsChecked等。
四、字段名爲英文短語、形容詞+名詞或助動詞+動詞時態的形式表示,大小寫混合,遵循「見名知意」的原則。
一、不容許寫SELECT * FROM ……,必須指明須要讀取的具體字段。
二、不容許在應用程序代碼中直接寫SQL語句訪問數據庫。
三、避免在一行內寫太長的SQL語句,在SQL關鍵字的地方將SQL語句分紅多行會更加清晰。
如:SELECT fUserID,fUserName,fUserPwd FROM User_Login WHERE fAreaID=20
修改爲:
SELECT fUserID,fUserName,fUserPwd
FROM User_Login
WHERE fAreaID=20
更加直觀
四、在一些塊形式的SQL語句中,就算只有一行代碼,也要加上BEGIN…END塊。
如:IF EXISTS(…)
SET @nVar = 100
應該寫成:
IF EXISTS(…)
BEGIN
SET @nVar = 100
END
五、SQL批處理語句的空行和縮進與通常的結構化程序語言一致,應該保持良好的代碼格式。
六、全部的SQL關鍵字大寫
一、 若無必要,不要使用遊標
二、 包含遊標的存儲過程,必須對性能進行認真測試。
對於數據庫的維護建索引是很日常的事情,可是若是沒有一個規範化的命名,咱們對於一個表的諸多索引可能須要花上一段時間的瞭解。
1. 若是表中存在主鍵默認狀況下,表的彙集性索引也就是主鍵列,主鍵的命名前面已經有提到過,索引名也跟主鍵名同樣,(PK_表名)
2. 對於表上的非彙集索引,建議使用(IX_表名_字段簡寫),對於不少命名文章上提到的須要詳細表達出具體的列,我我的以爲沒有必要,首先非彙集索引常常涉及多列,很難羅列出全部列;還有影響美觀
當你執行SELECT fNAME FROM SYS.COLUMNS 查詢索引時,你根據NAME名很快就知道索引來自那張表,是不是非彙集索引,而不用根據OBJECTID列去跟對象表關聯。
函數命名分兩類:1.針對對象的函數,2.用做輔助功能操做的函數(不針對具體的數據庫對象)
1. 第一類命名:FN_+[User]+_+[對象名] 例如:FN_User_Student(對於Student進行操做函數)
2. 第二類命名:FN_[具體函數解釋] 例如:FN_Spit(對字段進行拆分函數)