[转]SQL Server 数据库规范
SQL Server 數(shù)據(jù)庫(kù)規(guī)范
一、 命名規(guī)范
常用對(duì)象命名規(guī)范,使用帕斯卡命名法(Pascal,單詞首字母大寫(xiě)),統(tǒng)一使用英文。
1. 表。英文單數(shù)名詞,盡量寫(xiě)完整單詞名稱一般不超過(guò)3個(gè)英文單詞都可表達(dá)出表的意思。使用帕斯卡命名法。
如:User,UserRole,Role,Group,Family,SalesOrderDetail
錯(cuò)誤例子:Users,UserTable
注意:特殊意義的表
自定義的元數(shù)據(jù)表,使用前綴Sys開(kāi)頭:SysDictionary,SysParameter,SysModel,SysRegion
業(yè)務(wù)同類表:WeChatCompany,WeChatUser,WeChatMember,SMSSend,SMSReceive
縮寫(xiě)表,普遍認(rèn)知的縮寫(xiě): US_User,EN_User,CN_User,WTO_Member,WTO_ Country
單詞過(guò)多的表:User_ ZGYH(中國(guó)銀行中文縮寫(xiě)),User_ GSYH(工商銀行中文縮寫(xiě))
2. 字段。與表命名雷同。
對(duì)于主鍵字段,統(tǒng)一為:ID
外鍵引用的字段,統(tǒng)一為:外鍵表名+ID
如 UserID,UserRoleID,SalesOrderDetailID,SysDictionaryID
3. 視圖(不要使用)。
與表命名雷同。大寫(xiě)“V_”作為前綴,格式:V_視圖名稱
如:V_User,V_SysDictionary
4. 存儲(chǔ)過(guò)程(業(yè)務(wù)處理不要使用,報(bào)表可用)。獲取或執(zhí)行數(shù)據(jù)的過(guò)程。
要求動(dòng)名詞組合。大寫(xiě)“USP_”作為前綴,格式:USP_存儲(chǔ)過(guò)程名稱
如:P_GetUser,P_UpdateUserByUsername,P_CleanDeletedUser,P_GetMyRecord
5. 標(biāo)量函數(shù)(查詢到表的不要使用)。返回單個(gè)值。
要求動(dòng)名詞組合,大寫(xiě)“FN_”作為前綴,格式:FN_函數(shù)名稱
如: FN_GetUserName,FN_GetUserNameByUserID
6. 表值函數(shù)(查詢到表的不要使用)。返回表。
要求動(dòng)名詞組合,寫(xiě)“TF_”作為前綴,格式:TF_函數(shù)名稱
如:TF_ SplitChar,TF_ SplitCharByComma,TF_GetUserByCity
7. 觸發(fā)器(不要使用)。
大寫(xiě)“TR_”作為前綴,觸發(fā)操作為后綴,格式:TR_表/視圖名稱_Insert/Delete/Update
如:TR_User_Insert,TR_User_Update,TR_User_Delete
8. 索引。盡量寫(xiě)完涉及的字段
大寫(xiě)“IX_”作為前綴,格式:IX_表名稱_字段名稱_字段名稱_……
如:IX_User_ID,IX_User_UserName_Mobile
唯一索引: UIX_表名稱_字段名稱
包含列索引:IX_表名稱_字段名稱_Include
篩選索引:IX_表名稱_字段名稱_Where
9. 約束。
主鍵約束:PK_表名稱_字段名稱
外鍵約束:FK_表名稱_字段名_主表名稱_主表字段(禁用外鍵約束!)
唯一約束:UIX_表名稱_字段名稱(唯一約束默認(rèn)是創(chuàng)建唯一索引來(lái)約束)
默認(rèn)值約束:DF_表名稱_字段名稱
Check約束:CK_表名稱_字段名稱
10. 臨時(shí)對(duì)象。大小寫(xiě)不要求,其他與表名稱規(guī)范相同。聲明使用會(huì)話級(jí)別。
臨時(shí)表:#user (不要使用 ##user)
(表)變量:@name (不要使用@@name)
二、 設(shè)計(jì)規(guī)范
對(duì)象級(jí)規(guī)范:
? 數(shù)據(jù)庫(kù)表設(shè)計(jì)必須滿足第三范式(特殊情況再討論)
? 業(yè)務(wù)表都設(shè)置自增主鍵ID!(主鍵不一定是聚集索引)
? 禁止使用外鍵約束!(操作數(shù)據(jù)慢;維護(hù)數(shù)據(jù)困難)
? 禁止使用觸發(fā)器!(程序中控制操作)
? 禁止使用視圖!(維護(hù)不便,多表關(guān)聯(lián)可能有字段沒(méi)用。報(bào)表可用)
? 禁止使用函數(shù)訪問(wèn)表、視圖等數(shù)據(jù)(函數(shù)只作為輔助計(jì)算工具,不參與訪問(wèn)數(shù)據(jù)!)
? 禁止使用存儲(chǔ)過(guò)程處理業(yè)務(wù)邏輯(先在程序計(jì)算好再去讀寫(xiě)數(shù)據(jù)庫(kù)!)
? 禁止使用游標(biāo)!(少用遍歷,用集合概念來(lái)操作)
? 禁止使用臨時(shí)表!(業(yè)務(wù)操作頻繁會(huì)不可控)
? 禁止使用同義詞!(維護(hù)易被忽略)
? (報(bào)表可用存儲(chǔ)過(guò)程、視圖、臨時(shí)表,視圖中的結(jié)果集不要有排序)
? (若必要使用,視圖、存儲(chǔ)過(guò)程、函數(shù)、觸發(fā)器、游標(biāo)等不要多層調(diào)用2 次以上!)
? 不要使用數(shù)據(jù)庫(kù)關(guān)鍵字作為表名、字段名等(尤其系統(tǒng)對(duì)象名稱,如:getdate、sum 等)
? 創(chuàng)建約束、索引等,手動(dòng)設(shè)置名稱,不用系統(tǒng)自動(dòng)生成!
? 索引盡量不超過(guò)5個(gè),尤其那些頻繁更改和插入的表!
? 表和字段在數(shù)據(jù)庫(kù)中須添加詳細(xì)注釋!(參考:sp_addextendedproperty)
? 視圖、存儲(chǔ)過(guò)程、函數(shù)、觸發(fā)器等,須填寫(xiě)創(chuàng)建信息及每個(gè)操作的描述!
? 禁止在數(shù)據(jù)庫(kù)中存儲(chǔ)文件。
? 插入字符數(shù)據(jù)時(shí),須去掉左右空格!
? 插入表時(shí)所有字段必須全部列出!(如: insert
into tab(name,phone)
select name, mobile
from user)
? 存儲(chǔ)過(guò)程、函數(shù)等,模塊語(yǔ)句加上 BEGIN……END;去掉多余的空行和空格。
? 程序操作表的權(quán)限只允許select、insert、update、delete!
? 對(duì)于可能刪除的業(yè)務(wù)數(shù)據(jù),數(shù)據(jù)庫(kù)不實(shí)際刪除數(shù)據(jù),增加字段 IsDeleted 來(lái)判斷是否刪除!
? 操作日志、系統(tǒng)日志等表,只允許插入,不能再修改!
? 對(duì)約束較強(qiáng)的枚舉選項(xiàng),程序應(yīng)設(shè)置選項(xiàng)而不要用戶手動(dòng)隨意填寫(xiě)!
? 業(yè)務(wù)表都添加一個(gè)時(shí)間字段:addTime
datetime not null
constraint DF_表名稱_datetime
default(getdate())
字段規(guī)范:
? 盡量設(shè)置使用 “not null”約束,數(shù)值默認(rèn)0,字符默認(rèn)為空’’。否則查詢時(shí) null 是不參與比較的!
? 禁用 ntext、text 和 image,用nvarchar(max)、varchar(max)和 varbinary(max)替代,盡量不用max!
? 非英文重要數(shù)據(jù)使用unicode類型保存,如nvarchar ,nchar,其他可以varchar;
? 日期時(shí)間字段統(tǒng)一用 datetime,精確到毫秒;
? 金額、小數(shù)類型使用 decimal,不用int、float、double(int可存儲(chǔ)21億,float、double精度不準(zhǔn))
? 狀態(tài)字段統(tǒng)一用State(可枚舉的),不用status
? 不允許明文存儲(chǔ)密碼!
三、 查詢規(guī)范
u 定義的參數(shù)、變量類型要參考與字段類型和長(zhǎng)度相同。
Declare @name
varchar(50)
--類型要與 User(Name)相同
Select *
from User
where Name = @name
u 少用游標(biāo)遍歷,用集合概念來(lái)處理數(shù)據(jù)。
u 操作使用 IN 內(nèi)的常量不要過(guò)百,盡量少!應(yīng)用其他方式改為表連接。
錯(cuò)誤示例:select
* from [User] whereName
in('AA','BB','CC','DD','EE','FF',………)
u 若須用“IN”,嵌套子查詢不要超過(guò)3個(gè)。
Select *
from User
where Name
in(
select Name
from Manager
where Sex
in(Select Sex from
User where Name='kk')
)
u 子查詢“IN”都改為“innerjoin”方式,注意是否有一對(duì)多或多對(duì)多情況,有則先連接鍵分組再連接。
上面的 IN 查詢可改為如下:
Select distinct t1.*
from User t1
inner join Manager t2
on t1.Name=t2.Name
inner join
User t3 on t2.Sex=t3.Sex
where t3.Name='kk'
u 能用“EXISTS ”就不用“IN”,exists 可以避免可能的錯(cuò)誤。
--表 TestRole
不存在字段 Mobile,但是查詢不會(huì)報(bào)錯(cuò)!
select *
from User
where name in(select Mobile
fromTestRole)
select *
from User
where name not in(select Mobile
from TestRole)
改為:
select *
from User a
where exists(select 1
fromTestRole b where a.name=b.RoleName)
--表 TestRole
字段 RoleName
只要存在一個(gè) Null ,查詢則沒(méi)有結(jié)果
select *
from User
where name not in(select RoleName
from TestRole)
改為:
select *
from User
where name not in(select RoleName
from TestRole whereRoleName
is notnull)
select *
from User a
where not exists(select 1
from TestRole b wherea.name=b.name)
u 存儲(chǔ)過(guò)程中首行添加:set nocount on ,主要是將執(zhí)行結(jié)果顯示的打印信息不返回客戶端,減少網(wǎng)絡(luò)IO。
CREATE PROC dbo.TestPro
AS
BEGIN
SET NOCOUNT
ON --此處添加
…………
END
GO
u 存儲(chǔ)過(guò)程內(nèi)不要打印(print)信息,理由同上。
u 查詢不用星號(hào),哪怕字段再多也寫(xiě)完整,并非所有字段都用的上的。且星號(hào)不能建立合適的索引。
u Where篩選中,不要在字段上使用函數(shù),否則整表都掃描來(lái)進(jìn)行函數(shù)處理。
Select *
from User
where left(Name)
= '黃'
改為:
Select *
from User
where Name like '黃%'
Select *
from User
where convert(varchar(10),AddTime,120)='2018-01-01'
改為:
Select *
from User
where AddTime>='2018-01-01'
andAddTime<'2018-01-02'
u 模糊匹配like不用講 % 放在首位。(同上)
u 時(shí)間比較注意,不必手寫(xiě)那么詳細(xì)
Select *
from User where addTime<='2017-12-31 23:59:59'
改為:
Select *
from User
where addTime<'2018-01-01'
u 一致性不強(qiáng)或需要粗略統(tǒng)計(jì)的大表數(shù)據(jù)或報(bào)表,可以加上Nolock 允許臟讀。
Select *
from User
with(nolock)
Select *
from User
as U with(nolock)
u Count 是不統(tǒng)計(jì)null 的。計(jì)數(shù)使用 count(*),MSSQL中count(*) 默認(rèn)走索引長(zhǎng)度最小的來(lái)統(tǒng)計(jì)。
COUNT(*)
= COUNT(1)
= COUNT('A')
Select
COUNT(*) from
User --統(tǒng)計(jì)表總行數(shù)
Select
COUNT(Mobile)
from User
--統(tǒng)計(jì)手機(jī)不為NULL的總行數(shù)
u SQL Server 中,默認(rèn) null 加上任何字符都為null,所以注意!
SELECT 'A'+NULL --結(jié)果為 NULL
SELECT 100+NULL --結(jié)果為 NULL
—正常寫(xiě)法,如果字段有 NULL
值,使用 ISNULL
判斷更改。
Select Name
+ ISNULL(Mobile,'')
from User
注意:集合函數(shù) sum、avg、max、min
是忽略 NULL 的。
u 除了數(shù)據(jù)需要大量導(dǎo)出,任何查詢一定要使用分頁(yè)查詢。
u 一個(gè)事務(wù)中不用頻繁重復(fù)讀取表數(shù)據(jù)或操作數(shù)據(jù)
u 查詢盡量參數(shù)化,即先聲明參數(shù),后賦值,再把參數(shù)帶入執(zhí)行腳本(如: where name = @name)
Select Name,Mobile
from User
where Name ='AA'
Select Name,Mobile
from User
where Name ='BB'
改為:
Declare @name
varchar(50)
Set @name
= 'AA'
Select Name,Mobile
from User
where Name =@name
go
Declare @name
varchar(50)
Set @name
= 'BB'
Select Name,Mobile
from User
where Name =@name
go
u 多表關(guān)聯(lián)情況且結(jié)果集在滿足情況下,盡量使用左連接(left join)而不使用內(nèi)連接( inner join)
Select t1.Name
from User t1
inner join Manager t2
on t1.ManagerID=t2.ID
where t1.Mobile='13000000000'
改為:
Select t1.Name
from User t1
left join Manager t2
on t1.ManagerID=t2.ID
where t1.Mobile='13000000000'
因?yàn)?Mobile
唯一,第二種情況只查詢 User
表。所以當(dāng)條件不確定的時(shí)候、且不影響結(jié)果,使用第二種。
u 按添加時(shí)間排序時(shí),性能不好可以用主鍵聚集索引ID排序,因?yàn)镮D也是遞增的。
Select top(10) Name,Mobile
from User
order by AddTime
desc
改為:
Select top(10) Name,Mobile
from User
order by ID desc
u 多表連接查詢,使用簡(jiǎn)短別名,字段都加上別名且別名要統(tǒng)一!
Select t1.Name
from User t1
inner join Manager t2on t1.ManagerID=t2.ID
Select a.Name
from User a
inner join Manager b
on a.ManagerID=b.ID
Select u.Name
from User u
inner join Manager m
on u.ManagerID=m.ID
u 編寫(xiě)腳本不要寫(xiě)在一行上面,注意縮進(jìn),每行長(zhǎng)度盡量不超過(guò)120個(gè)字符。
u 腳本中的系統(tǒng)關(guān)鍵字保持統(tǒng)一,可全部大寫(xiě)或全部小寫(xiě)或首字母大寫(xiě)。
u 不在數(shù)據(jù)庫(kù)中使用鏈接服務(wù)器來(lái)跨服務(wù)器查詢,程序中應(yīng)從一節(jié)點(diǎn)讀取數(shù)據(jù)后再傳遞到另一節(jié)點(diǎn)操作。
u 多表連接中,“on”后面若有 “or”,則改為 union 取連接:
Select a.name,b.name
From User a
Inner Join Manager b
On a.ManagerID=b.ID
or a.Mobile=b.Mobile
改為:
Select a.name,b.name
From User a
Inner Join Manager b
On a.ManagerID=b.ID
Union
Select a.name,b.name
From User a
Inner Join Manager b
On a.Mobile=b.Mobile
u 不要在生產(chǎn)庫(kù)查詢大量數(shù)據(jù),占用有效數(shù)據(jù)的IO和內(nèi)存。若須查詢則加 nolock。
Select *
from User
with(nolock)
Select *
from User
as U with(nolock)
u 對(duì)于復(fù)雜分頁(yè)查詢,可以先按照條件找出主表ID(在非聚集索引中找出ID),通過(guò)ID再關(guān)聯(lián)找出分頁(yè)全部數(shù)據(jù)(通過(guò)聚集索引找出所有數(shù)據(jù))
四、 維護(hù)規(guī)范
生產(chǎn)庫(kù)使用完整模式,測(cè)試、開(kāi)發(fā)庫(kù)可用簡(jiǎn)單模式
操作日志表,ID通常只做主鍵,沒(méi)什么用。可將字段“AddTime”作為聚集索引字段和分區(qū)字段。
每次修改函數(shù)、存儲(chǔ)過(guò)程等,備份舊的副本,記錄修改信息。
數(shù)據(jù)庫(kù)級(jí)別的變動(dòng),先備份數(shù)據(jù)庫(kù)
大量更新、刪除數(shù)據(jù)時(shí),先備份事務(wù)日志
刪除、更新數(shù)據(jù)時(shí),把需要操作的數(shù)據(jù)存儲(chǔ)到另一個(gè)專門的數(shù)據(jù)庫(kù)中作臨時(shí)備份。
刪除、更新數(shù)據(jù)時(shí),小批量操作。建議每次不超過(guò)5000行,減少了事務(wù)的粒度,也防止鎖升級(jí)為表鎖。
定期分批重建索引,不要一次性全部重建。
其他: Disk IO、CPU、Memery、NetWork IO、遷移、擴(kuò)展等性能問(wèn)題,找DBA!~
SQL Server 的最大容量規(guī)范:https://msdn.microsoft.com/zh-cn/library/ms143432(v=sql.100).aspx
---------------------
本文來(lái)自 Huang-ZC 的CSDN 博客 ,全文地址請(qǐng)點(diǎn)擊:https://blog.csdn.net/kk185800961/article/details/78866259?utm_source=copy
總結(jié)
以上是生活随笔為你收集整理的[转]SQL Server 数据库规范的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: STM32开发项目:定时器预装载寄存器(
- 下一篇: 当初的愿望实现了么?