數(shù)據(jù)庫開發(fā)規(guī)范

  • 數(shù)據(jù)庫開發(fā)規(guī)范

    1. 數(shù)據(jù)庫命名規(guī)范

    前綴

    • 對象前綴命名: 前綴命名一般用小寫
    • 表的前綴: 業(yè)務(wù)模塊組名前綴
    • 存儲過程前綴: udp 脱货,系統(tǒng)存儲過程(sp)
    • 自定義函數(shù)前綴: udf(User define function)
    • 視圖前綴: udv(User Define View)表示用戶自定義視圖
    • 自定義約束前綴: uck(User Checker)用戶自定義約束
    • 索引前綴: idx(Index)表示索引
    • 主鍵前綴: pk(primary keys)表示主鍵
    • 主鍵前綴: fk(foreign keys)表示主鍵

    常見命名約定

    • 表名使用單數(shù)名
      例如:對存儲客人信息的表(Customer)不使用Customers

    • 字段名不要存在無用前綴
      例如表‘WeiXinConfig’,既然我已經(jīng)知道這張表是關(guān)于微信的表火鼻,里面的名稱字段可以可以使用Name,不需要添加無用的前綴類似‘WeiXinName’隶垮,‘WeiXinGuanZhuMsg’藻雪,‘WeiXinUpImgMsg’等

    • 避免無謂的表名后綴

      • 表是用來存儲數(shù)據(jù)信息的,表是行的集合。那么如果表名已經(jīng)能夠很好地說明其包含的數(shù)據(jù)信 息狸吞,就不需要再添加體現(xiàn)上面兩點的后綴了勉耀。
      • GuestInfo(存儲客戶信息)應(yīng)寫成Guest指煎,F(xiàn)lightList(存儲航班信息的表)應(yīng)寫成Flight
    • 所有表示時間的字段,統(tǒng)一以 Date 來作為結(jié)尾(而不是有的使用Date,有的使用Time)

      以大家都熟悉的論壇來說便斥,需要記錄會員最后一次登錄的時間至壤,這時候一般人都會把這個字段命名為LoginTime 或者 LoginDate。這時候枢纠,已經(jīng)產(chǎn)生了一個歧義;如果僅看表的字段名稱像街,不去看表的內(nèi)容,很容易將LoginTime理解成登錄的次數(shù)晋渺,因為镰绎,Time還有一個很常用的意思,就是次數(shù)

    • 所有表示數(shù)目的字段木西,都應(yīng)該以Count作為結(jié)尾

    • 所有代表鏈接的字段畴栖,均為Url結(jié)尾

    • 所有名稱的字符范圍為:A-Z, a-z, 0-9 和_(下劃線)。不允許使用其他字符作為名稱

    • 采用英文單詞或英文短語(包括縮寫)作為名稱八千,不能使用無意義的字符或漢語拼音

    • 名稱應(yīng)該清晰明了吗讶,能夠準(zhǔn)確表達(dá)事物的含義,最好可讀叼丑,遵循“見名知意”的原則

    • 字段名不能使用保留關(guān)鍵字

    2. 數(shù)據(jù)庫設(shè)計規(guī)范

    范式設(shè)計與反范式設(shè)計

    • 關(guān)于范式 Normal Form

      范式是關(guān)系數(shù)據(jù)庫理論的基礎(chǔ)关翎,也是我們在設(shè)計數(shù)據(jù)庫結(jié)構(gòu)過程中所要遵循的規(guī)則和指導(dǎo)方法扛门。數(shù)據(jù)庫的設(shè)計范式是數(shù)據(jù)庫設(shè)計所需要滿足的規(guī)范鸠信。只有理解數(shù)據(jù)庫的設(shè)計范式,才能設(shè)計出高效率论寨、優(yōu)雅的數(shù)據(jù)庫星立,否則可能會設(shè)計出錯誤的數(shù)據(jù)庫。
      目前關(guān)系數(shù)據(jù)庫有六種范式:第一范式(1NF)葬凳、第二范式(2NF)绰垂、第三范式(3NF)、巴斯-科德范式(BCNF)火焰、第四范式(4NF)和第五范式(5NF劲装,還又稱完美范式)。滿足最低要求的叫第一范式昌简,簡稱1NF占业。在第一范式基礎(chǔ)上進一步滿足一些要求的為第二范式,簡稱2NF纯赎。其余依此類推谦疾。各種范式呈遞次規(guī)范,越高的范式數(shù)據(jù)庫冗余越小犬金。通常所用到的只是前三個范式念恍,即:第一范式(1NF)六剥,第二范式(2NF),第三范式(3NF)峰伙。

      • 第一范式(1NF): 強調(diào)的是列的原子性疗疟,即列不能夠再分成其他幾列。簡而言之瞳氓,第一范式就是無重復(fù)的列秃嗜。
      • 第二范式(2NF): 首先要滿足它是1NF,另外還需要包含兩部分內(nèi)容:一是表必須有一個主鍵顿膨;二是沒有包含在主鍵中的列必須完全依賴于主鍵锅锨,而不能只依賴于主鍵的一部分。
      • 第三范式(3NF) 在1NF基礎(chǔ)上恋沃,任何非主屬性不依賴于其它非主屬性[在2NF基礎(chǔ)上消除傳遞依賴]必搞。第三范式(3NF)是第二范式(2NF)的一個子集,即滿足第三范式(3NF)必須滿足第二范式(2NF)囊咏。
    • 關(guān)于范式的討論

      • 第二范式和第三范式如何區(qū)別恕洲?

        第二范式:非主鍵列是否依賴主鍵(包括一列通過某一列間接依賴主鍵),要是有依賴關(guān)系的就是第二范式梅割;</br>
        第三范式:非主鍵列是否是直接依賴主鍵霜第,不能是那種通過傳遞關(guān)系的依賴的。要是符合這種就是第三范式

      • 使用范式有哪些優(yōu)點和缺點户辞?

        范式可以避免數(shù)據(jù)冗余泌类,減少數(shù)據(jù)庫的空間,減輕維護數(shù)據(jù)完整性的麻煩底燎。
        范式再給我們帶來的上面的好處時刃榨,同時也伴隨著一些不好的地方:按照范式的規(guī)范設(shè)計出來的表,等級越高的范式設(shè)計出來的表越多双仍。

        如第一范式可能設(shè)計出來的表可能只有一張表而已枢希,再按照第二范式去設(shè)計這張表時就可能出來兩張或更多張表,如果再按第三范式或更高的范式去設(shè)計這張表會出現(xiàn)更多比第二范式多的表朱沃。表的數(shù)量越多苞轿,當(dāng)我們?nèi)ゲ樵円恍?shù)據(jù),必然要去多表中去查詢數(shù)據(jù)逗物,這樣查詢的時間要比在一張表中查詢中所用的時間要高很多搬卒。也就是說我們所用的范式越高,對數(shù)據(jù)操作的性能越低敬察。所以我們在利用范式設(shè)計表的時候秀睛,要根據(jù)具體的需求再去權(quán)衡是否使用更高范式去設(shè)計表。在一般的項目中莲祸,我們用的最多也就是第三范式蹂安,第三范式也就可以滿足我們的項目需求椭迎,性能好而且方便管理數(shù)據(jù);當(dāng)我們的業(yè)務(wù)所涉及的表非常多田盈,經(jīng)常會有多表發(fā)生關(guān)系畜号,并且我們對表的操作要時間上要盡量的快,這時可以考慮我們使用“反范式”允瞧。

    • 關(guān)于反范式

      不滿足范式的模型简软,就是反范式模型
      反范式跟范式所要求的正好相反,在反范式的設(shè)計模式述暂,我們可以允許適當(dāng)?shù)臄?shù)據(jù)的冗余痹升,用這個冗余去取操作數(shù)據(jù)時間的縮短。本質(zhì)上就是用空間來換取時間畦韭,把數(shù)據(jù)冗余在多個表中疼蛾,當(dāng)查詢時可以減少或者是避免表之間的關(guān)聯(lián)

    • 范式和反范式的對比

      模型 優(yōu)點 缺點
      范式化模型 數(shù)據(jù)無冗余艺配,便于更新 不利于查詢操作
      反范式化模型 便于查詢 數(shù)據(jù)冗余察郁,不利于更新

    RDBMS模型設(shè)計過程中,常常使用范式約束我們的模型转唉,但在NOSQL模型中則大量采用反范式皮钠,在設(shè)計的時候 結(jié)合讀寫的業(yè)務(wù)場景類分析 對比各項指標(biāo) 進行綜合考慮實施。

主鍵設(shè)計原則

  • 主鍵的數(shù)據(jù)類型

    最常見的主鍵數(shù)據(jù)類型是數(shù)字類型赠法、固定長度的字符類型和GUID類型麦轰。通常情況下,RDBMS會在主鍵上建立聚集索引(SQL Server默認(rèn)都這么做)期虾,由于我們使用B-Tree的數(shù)據(jù)結(jié)構(gòu)來存儲索引數(shù)據(jù)原朝,所以一般對主鍵有以下兩個要求:

    • 越短越好——越短在一個Page中存儲的節(jié)點越多驯嘱,檢索速度就越快镶苞。
    • 順序增長——如果每一條插入的數(shù)據(jù)的主鍵都比前面的主鍵大,那么B-Tree上的節(jié)點也是順序增長的鞠评,不會造成頻繁的B-Tree分割茂蚓。

    越短越好是為了查詢的速度快,順序增長是為了插入速度快剃幌。

    有了這兩個要求聋涨,我們再來分析下各個數(shù)據(jù)類型:

    • 數(shù)字類型:根據(jù)數(shù)據(jù)量決定是用Int16還是Int32或者Int64,能用Int32的就不需要使用Int64负乡。
    • 字符類型:基本不滿足前面提到的2點要求牍白,字符類型一般不會很短,而且也很可能不是順序增長的抖棘,所以不是特別推薦的主鍵類型茂腥。當(dāng)然如果確實業(yè)務(wù)需求使用字符類型狸涌,那么也盡量使用char(XX)而不要使用varchar(XX),因為在RDBMS中最岗,對于定長字符串和變成字符串的數(shù)據(jù)結(jié)構(gòu)和處理是不一樣的帕胆,varchar的性能更差。
    • GUID類型:這個類型并不是所有數(shù)據(jù)庫都有對應(yīng)的數(shù)據(jù)類型般渡,SQL Server有uniqueidentifier懒豹,MySQL沒有。GUID類型在SQL Server中是16個字節(jié)驯用,不算短脸秽,比4個字節(jié)的Int32長多了。在插入新數(shù)據(jù)時蝴乔,GUID一般都是使用NewId()這樣的生成隨機GUID的方式生成的豹储,所以也不是順序增長的,在插入速度上不會很快淘这。
      通過上面的比較剥扣,我們知道使用數(shù)字類型是更好的方式,那么我們?yōu)槭裁催€會有人使用GUID和字符串來當(dāng)主鍵呢铝穷?那是因為:

    相對于數(shù)字類型钠怯,字符類型更易讀易記,在檢索關(guān)聯(lián)的數(shù)據(jù)時曙聂,更方便直接晦炊。

    GUID的優(yōu)勢是全球唯一,也就是說同樣的系統(tǒng)宁脊,如果部署了多套環(huán)境断国,那么里面的數(shù)據(jù)的主鍵仍然是唯一的,這樣有助于數(shù)據(jù)的集成榆苞。典型的例子就是一個系統(tǒng)在全國每個省份都部署一套稳衬,每個省份的數(shù)據(jù)各種錄入,互不干擾坐漏,然后再把每個省的數(shù)據(jù)集成起來為總部做分析薄疚。

    • 數(shù)據(jù)庫主鍵與業(yè)務(wù)主鍵

    前面說到一個表可能有很多個唯一標(biāo)識的候選鍵,那么這么多候選鍵中赊琳,哪個應(yīng)該拿來做主鍵呢街夭?一種方案是再新建一個獨立的字段作為主鍵,該字段并沒有業(yè)務(wù)含義躏筏,只是一個自增列或者流水號板丽,用于唯一標(biāo)識每一行數(shù)據(jù),這是數(shù)據(jù)庫主鍵趁尼。另外一種方案是選擇其中較短較常用的屬性作為主鍵埃碱,這是業(yè)務(wù)主鍵碴卧。個人建議是不要使用任何有業(yè)務(wù)含義的字段作主鍵,而是使用一個自增的(或者系統(tǒng)生成的)沒有實際業(yè)務(wù)意義的字段作為主鍵乃正。為什么呢住册?主要是出于以下考慮:

    具有業(yè)務(wù)意義的字段很可能是用戶從系統(tǒng)錄入的,不要信任用戶的任何輸入瓮具,只要是用戶自己錄入的荧飞,那么就很有可能錄錯了,如果發(fā)現(xiàn)錄入錯誤名党,這個時候再對主鍵進行修改叹阔,將會涉及到大量關(guān)聯(lián)的外鍵表的修改,是很麻煩的一件事情传睹。比如在做人員表的時候耳幢,就不要使用員工號或者身份證號做主鍵。

    具有業(yè)務(wù)意義的字段雖然在當(dāng)前階段是唯一的欧啤,是不變的睛藻,但是并不能保證隨著公司政策變動、業(yè)務(wù)調(diào)整等原因邢隧,導(dǎo)致該業(yè)務(wù)字段需要修改店印,以滿足新的業(yè)務(wù)要求,這個時候要修改主鍵也是很麻煩的事情倒慧。比如部門表按摘,我們以部門Code作為主鍵,但是后來部門變動纫谅,Code修改炫贤,則系統(tǒng)部門表的主鍵也得更改。

    還有一個原因是業(yè)務(wù)主鍵在數(shù)據(jù)錄入的時候不一定是明確知道的付秕,有時我們會在不知道業(yè)務(wù)主鍵的情況下兰珍,就錄入其他相關(guān)信息,這個時候盹牧,如果使用業(yè)務(wù)主鍵做數(shù)據(jù)庫的主鍵俩垃,那么數(shù)據(jù)將無法錄入。比如員工表把員工號作為主鍵汰寓,那么員工還沒有入職,沒有員工號的時候苹粟,HR需要先維護一些該預(yù)入職員工的信息是不可能的有滑。

    • 聯(lián)合主鍵

    聯(lián)合主鍵就是以多個字段來唯一標(biāo)識每一行數(shù)據(jù)。前面已經(jīng)說到主鍵應(yīng)該越短越好嵌削,而且是建議是一個沒有意義的自增列毛好,那么是不是就不會再需要聯(lián)合主鍵呢望艺?答案是否定的,我們?nèi)匀豢赡軙褂玫铰?lián)合主鍵肌访。聯(lián)合主鍵主要使用在多對多的關(guān)系時找默,中間表就需要使用聯(lián)合主鍵。在簡單的多對多關(guān)系中吼驶,我們不需要為中間的關(guān)聯(lián)建立實體惩激,所以中間表可能就只需要兩列,分別是兩個實體表的主鍵蟹演。

  • 主鍵值的生成

    主鍵值的生成 主要有這么幾種生成方式:

    • 自增风钻,這是SQL Server常用的主鍵生成方式,完全由數(shù)據(jù)庫管理主鍵的值酒请。
    • Sequence對象骡技,這是Oracle常用的主鍵生成方式,現(xiàn)在SQL Server已支持羞反。主要是在數(shù)據(jù)庫中有一個Sequence對象布朦,通過該對象生成主鍵。
    • GUID昼窗,這是用于GUID類型的主鍵喝滞,可以使用newid()這種數(shù)據(jù)庫提供的函數(shù),或者使用程序生成Guid并賦值膏秫。
    • 其他程序賦值右遭,完全由程序根據(jù)自己的算法生成并賦值。
    • 主鍵與索引

    在概念和作用上缤削,主鍵與索引是完全兩個不同的東西窘哈,但是由于我們大部分情況下都是使用主鍵檢索數(shù)據(jù),所以大部分?jǐn)?shù)據(jù)庫的默認(rèn)實現(xiàn)亭敢,在建立主鍵時會自動建立對應(yīng)的索引滚婉。

    以SQL Server為例,默認(rèn)情況下帅刀,建立主鍵的列矢劲,就會建立聚集索引,但是實際上表鳍,我們可以在建立主鍵時不使用聚集索引镐确。另外還有一個唯一約束(索引)的概念,該索引中的數(shù)據(jù)必須是唯一不能重復(fù)的锥余,感覺和主鍵的意義一樣腹纳,但是還是有一點點區(qū)別。

    主鍵是只能由一個,而唯一約束(索引)在一個表中可以有多個嘲恍。

    主鍵不能為空足画,而唯一約束(索引)是可以為空的。

外鍵設(shè)計原則

>數(shù)據(jù)庫外鍵的主要作用是 保持?jǐn)?shù)據(jù)的一致性 完整性佃牛,但對于外鍵的使用主要一直是矛盾的焦點淹辞,主要有兩個問題:一個是如何保證數(shù)據(jù)庫數(shù)據(jù)的完整性和一致性;二是數(shù)據(jù)庫性能問題
  • 觀點一
    • 由數(shù)據(jù)庫自身保證數(shù)據(jù)一致性俘侠,完整性象缀,更可靠,因為程序很難100%保證數(shù)據(jù)的完整性兼贡,而用外鍵即使在數(shù)據(jù)庫服務(wù)器當(dāng)機或者出現(xiàn)其他問題的時候攻冷,也能夠最大限度的保證數(shù)據(jù)的一致性和完整性。
    • 有主外鍵的數(shù)據(jù)庫設(shè)計可以增加ER圖的可讀性遍希,這點在數(shù)據(jù)庫設(shè)計時非常重要等曼。
    • 外鍵在一定程度上說明的業(yè)務(wù)邏輯,會使設(shè)計周到具體全面凿蒜。
  • 觀點二
    • 可以用應(yīng)用程序保證數(shù)據(jù)的完整性
    • 過分強調(diào)或者說使用主鍵/外鍵會平添開發(fā)難度禁谦,導(dǎo)致表過多等問題
    • 不用外鍵時數(shù)據(jù)管理簡單,操作方便废封,性能高
  • 總結(jié):
    • 在大型系統(tǒng)中(性能要求不高州泊,安全要求高),使用外鍵漂洋;在大型系統(tǒng)中(性能要求高遥皂,安全自己控制),不用外鍵刽漂;小系統(tǒng)隨便演训,最好用外鍵。
    • 用外鍵要適當(dāng)贝咙,不能過分追求
    • 不用外鍵而用程序控制數(shù)據(jù)一致性和完整性時样悟,應(yīng)該寫一層來保證,然后個個應(yīng)用通過這個層來訪問數(shù)據(jù)庫庭猩。

索引設(shè)計原則

>  基于合理的數(shù)據(jù)庫設(shè)計窟她,經(jīng)過深思熟慮后為表建立索引,是獲得高性能數(shù)據(jù)庫系統(tǒng)的基礎(chǔ)蔼水。而未經(jīng)合理分析便添加索引震糖,則會降低系統(tǒng)的總體性能。索引雖然說提高了數(shù)據(jù)的訪問速度徙缴,但同時也增加了插入试伙、更新和刪除操作的處理時間嘁信。<br/>
是否要為表增加索引于样、索引建立在那些字段上疏叨,是創(chuàng)建索引前必須要考慮的問題。解決此問題的一個比較好的方法穿剖,就是分析應(yīng)用程序的業(yè)務(wù)處理蚤蔓、數(shù)據(jù)使用,為經(jīng)常被用作查詢條件糊余、或者被要求排序的字段建立索引秀又。基于優(yōu)化器對SQL語句的優(yōu)化處理贬芥。

我們在創(chuàng)建索引時可以遵循下面的一般性原則:

  • (1)為經(jīng)常出現(xiàn)在關(guān)鍵字order by吐辙、group by、distinct后面的字段蘸劈,建立索引昏苏。
    在這些字段上建立索引,可以有效地避免排序操作威沫。如果建立的是復(fù)合索引贤惯,索引的字段順序要和這些關(guān)鍵字后面的字段順序一致,否則索引不會被使用棒掠。
  • (2)在union等集合操作的結(jié)果集字段上孵构,建立索引。其建立索引的目的同上烟很。
  • (3)為經(jīng)常用作查詢選擇的字段颈墅,建立索引。
  • (4)在經(jīng)常用作表連接的屬性上雾袱,建立索引恤筛。
  • (5)考慮使用索引覆蓋。對數(shù)據(jù)很少被更新的表谜酒,如果用戶經(jīng)常只查詢其中的幾個字段叹俏,可以考慮在這幾個字段上建立索引,從而將表的掃描改變?yōu)樗饕膾呙琛?/li>

除了以上原則僻族,在創(chuàng)建索引時粘驰,我們還應(yīng)當(dāng)注意以下的限制:

  • (1)限制表上的索引數(shù)目。
    對一個存在大量更新操作的表述么,所建索引的數(shù)目一般不要超過3個蝌数,最多不要超過5個。索引雖說提高了訪問速度度秘,但太多索引會影響數(shù)據(jù)的更新操作顶伞。
  • (2)不要在有大量相同取值的字段上饵撑,建立索引。
    在這樣的字段(例如:性別)上建立索引唆貌,字段作為選擇條件時將返回大量滿足條件的記錄滑潘,優(yōu)化器不會使用該索引作為訪問路徑。
  • (3)避免在取值朝一個方向增長的字段(例如:日期類型的字段)上锨咙,建立索引语卤;對復(fù)合索引,避免將這種類型的字段放置在最前面酪刀。
    由于字段的取值總是朝一個方向增長粹舵,新記錄總是存放在索引的最后一個葉頁中,從而不斷地引起該葉頁的訪問競爭骂倘、新葉頁的分配眼滤、中間分支頁的拆分。此外历涝,如果所建索引是聚集索引诅需,表中數(shù)據(jù)按照索引的排列順序存放,所有的插入操作都集中在最后一個數(shù)據(jù)頁上進行睬关,從而引起插入“熱點”诱担。
  • (4)對復(fù)合索引,按照字段在查詢條件中出現(xiàn)的頻度建立索引电爹。
    在復(fù)合索引中蔫仙,記錄首先按照第一個字段排序。對于在第一個字段上取值相同的記錄丐箩,系統(tǒng)再按照第二個字段的取值排序摇邦,以此類推。因此只有復(fù)合索引的第一個字段出現(xiàn)在查詢條件中屎勘,該索引才可能被使用施籍。
    因此將應(yīng)用頻度高的字段,放置在復(fù)合索引的前面概漱,會使系統(tǒng)最大可能地使用此索引丑慎,發(fā)揮索引的作用。
  • (5)刪除不再使用瓤摧,或者很少被使用的索引竿裂。
    表中的數(shù)據(jù)被大量更新,或者數(shù)據(jù)的使用方式被改變后照弥,原有的一些索引可能不再被需要腻异。數(shù)據(jù)庫管理員應(yīng)當(dāng)定期找出這些索引,將它們刪除这揣,從而減少索引對更新操作的影響悔常。

SqlServer數(shù)據(jù)類型

數(shù)據(jù)類型 類型 描述
bit 整型 bit 數(shù)據(jù)類型是整型影斑,其值只能是0、1或空值机打。這種數(shù)據(jù)類型用于存儲只有兩種可能值的數(shù)據(jù)矫户,如Yes 或No、True 或Fa lse 姐帚、On 或Off
int 整型 int 數(shù)據(jù)類型可以存儲從- 231(-2147483648)到231 (2147483 647)之間的整數(shù)吏垮。存儲到數(shù)據(jù)庫的幾乎所有數(shù)值型的數(shù)據(jù)都可以用這種數(shù)據(jù)類型障涯。這種數(shù)據(jù)類型在數(shù)據(jù)庫里占用4個字節(jié)
smallint 整型 smallint 數(shù)據(jù)類型可以存儲從- 215(-32768)到215(32767)之間的整數(shù)罐旗。這種數(shù)據(jù)類型對存儲一些常限定在特定范圍內(nèi)的數(shù)值型數(shù)據(jù)非常有用。這種數(shù)據(jù)類型在數(shù)據(jù)庫里占用2 字節(jié)空間
tinyint 整型 tinyint 數(shù)據(jù)類型能存儲從0到255 之間的整數(shù)唯蝶。它在你只打算存儲有限數(shù)目的數(shù)值時很有用九秀。這種數(shù)據(jù)類型在數(shù)據(jù)庫中占用1 個字節(jié)
numeric 精確數(shù)值型 numeric數(shù)據(jù)類型與decimal 型相同
decimal 精確數(shù)值型 decimal 數(shù)據(jù)類型能用來存儲從-1038-1到1038-1的固定精度和范圍的數(shù)值型數(shù)據(jù)。使用這種數(shù)據(jù)類型時粘我,必須指定范圍和精度鼓蜒。范圍是小數(shù)點左右所能存儲的數(shù)字的總位數(shù)。精度是小數(shù)點右邊存儲的數(shù)字的位數(shù)
money 貨幣型 money 數(shù)據(jù)類型用來表示錢和貨幣值征字。這種數(shù)據(jù)類型能存儲從-9220億到9220 億之間的數(shù)據(jù)都弹,精確到貨幣單位的萬分之一
smallmoney 貨幣型 smallmoney 數(shù)據(jù)類型用來表示錢和貨幣值。這種數(shù)據(jù)類型能存儲從-214748.3648 到214748.3647 之間的數(shù)據(jù)匙姜,精確到貨幣單位的萬分之一
float 近似數(shù)值型 float 數(shù)據(jù)類型是一種近似數(shù)值類型畅厢,供浮點數(shù)使用。說浮點數(shù)是近似的氮昧,是因為在其范圍內(nèi)不是所有的數(shù)都能精確表示框杜。浮點數(shù)可以是從-1.79E+308到1.79E+308 之間的任意數(shù)
real 近似數(shù)值型 real 數(shù)據(jù)類型像浮點數(shù)一樣,是近似數(shù)值類型袖肥。它可以表示數(shù)值在-3.40E+38到3.40E+38之間的浮點數(shù)
datetime 日期時間型 datetime數(shù)據(jù)類型用來表示日期和時間咪辱。這種數(shù)據(jù)類型存儲從1753年1月1日到9999年12月3 1日間所有的日期和時間數(shù)據(jù), 精確到三百分之一秒或3.33毫秒
Smalldatetime 日期時間型 smalldatetime 數(shù)據(jù)類型用來表示從1900年1月1日到2079年6月6日間的日期和時間椎组,精確到一分鐘
cursor 特殊數(shù)據(jù)型 cursor 數(shù)據(jù)類型是一種特殊的數(shù)據(jù)類型油狂,它包含一個對游標(biāo)的引用。這種數(shù)據(jù)類型用在存儲過程中寸癌,而且創(chuàng)建表時不能用
timestamp 特殊數(shù)據(jù)型 timestamp 數(shù)據(jù)類型是一種特殊的數(shù)據(jù)類型专筷,用來創(chuàng)建一個數(shù)據(jù)庫范圍內(nèi)的唯一數(shù)碼。一個表中只能有一個timestamp列灵份。每次插入或修改一行時仁堪,timestamp列的值都會改變。盡管它的名字中有“time”填渠,但timestamp列不是人們可識別的日期弦聂。在一個數(shù)據(jù)庫里鸟辅,timestamp值是唯一的
uniqueidentifier 特殊數(shù)據(jù)型 uniqueidentifier數(shù)據(jù)類型用來存儲一個全局唯一標(biāo)識符,即GUID莺葫。GUID確實是全局唯一的匪凉。這個數(shù)幾乎沒有機會在另一個系統(tǒng)中被重建∞嗝剩可以使用NEWID 函數(shù)或轉(zhuǎn)換一個字符串為唯一標(biāo)識符來初始化具有唯一標(biāo)識符的列
char 字符型 char數(shù)據(jù)類型用來存儲指定長度的定長非統(tǒng)一編碼型的數(shù)據(jù)再层。當(dāng)定義一列為此類型時,你必須指定列長堡纬。當(dāng)你總能知道要存儲的數(shù)據(jù)的長度時聂受,此數(shù)據(jù)類型很有用。例如烤镐,當(dāng)你按郵政編碼加4個字符格式來存儲數(shù)據(jù)時蛋济,你知道總要用到10個字符。此數(shù)據(jù)類型的列寬最大為8000 個字符
varchar 字符型 varchar數(shù)據(jù)類型炮叶,同char類型一樣碗旅,用來存儲非統(tǒng)一編碼型字符數(shù)據(jù)。與char 型不一樣镜悉,此數(shù)據(jù)類型為變長祟辟。當(dāng)定義一列為該數(shù)據(jù)類型時,你要指定該列的最大長度侣肄。它與char數(shù)據(jù)類型最大的區(qū)別是旧困,存儲的長度不是列長,而是數(shù)據(jù)的長度
text 字符型 text 數(shù)據(jù)類型用來存儲大量的非統(tǒng)一編碼型字符數(shù)據(jù)茫孔。這種數(shù)據(jù)類型最多可以有231-1或20億個字符
nchar 統(tǒng)一編碼字符型 nchar 數(shù)據(jù)類型用來存儲定長統(tǒng)一編碼字符型數(shù)據(jù)叮喳。統(tǒng)一編碼用雙字節(jié)結(jié)構(gòu)來存儲每個字符,而不是用單字節(jié)(普通文本中的情況)缰贝。它允許大量的擴展字符馍悟。此數(shù)據(jù)類型能存儲4000種字符,使用的字節(jié)空間上增加了一倍
nvarchar 統(tǒng)一編碼字符型 nvarchar 數(shù)據(jù)類型用作變長的統(tǒng)一編碼字符型數(shù)據(jù)剩晴。此數(shù)據(jù)類型能存儲4000種字符锣咒,使用的字節(jié)空間增加了一倍
ntext 統(tǒng)一編碼字符型 ntext 數(shù)據(jù)類型用來存儲大量的統(tǒng)一編碼字符型數(shù)據(jù)。這種數(shù)據(jù)類型能存儲230 -1或?qū)⒔?0億個字符赞弥,且使用的字節(jié)空間增加了一倍
binary 二進制數(shù)據(jù)類型 binary數(shù)據(jù)類型用來存儲可達(dá)8000 字節(jié)長的定長的二進制數(shù)據(jù)毅整。當(dāng)輸入表的內(nèi)容接近相同的長度時,你應(yīng)該使用這種數(shù)據(jù)類型
varbinary 二進制數(shù)據(jù)類型 varbinary 數(shù)據(jù)類型用來存儲可達(dá)8000 字節(jié)長的變長的二進制數(shù)據(jù)绽左。當(dāng)輸入表的內(nèi)容大小可變時悼嫉,你應(yīng)該使用這種數(shù)據(jù)類型
image 二進制數(shù)據(jù)類型 image 數(shù)據(jù)類型用來存儲變長的二進制數(shù)據(jù),最大可達(dá)231-1或大約20億字節(jié)

使用原則

  • 1.字符類型建議采用varchar/nvarchar數(shù)據(jù)類型
  • 2.金額貨幣建議采用money數(shù)據(jù)類型
  • 3.科學(xué)計數(shù)建議采用numeric數(shù)據(jù)類型
  • 4.自增長標(biāo)識建議采用bigint數(shù)據(jù)類型 (數(shù)據(jù)量一大拼窥,用int類型就裝不下戏蔑,那以后改造就麻煩了)
  • 5.時間類型建議采用為datetime數(shù)據(jù)類型
  • 6.禁止使用text蹋凝、ntext、image老的數(shù)據(jù)類型
  • 7.禁止使用xml數(shù)據(jù)類型总棵、varchar(max)鳍寂、nvarchar(max)

3. 數(shù)據(jù)庫查詢規(guī)范

禁止在數(shù)據(jù)庫做復(fù)雜運算

禁止使用SELECT *

減少內(nèi)存消耗和網(wǎng)絡(luò)帶寬

給查詢優(yōu)化器有機會從索引讀取所需要的列

表結(jié)構(gòu)變化時容易引起查詢出錯

禁止在索引列上使用函數(shù)或計算

禁止在索引列上使用函數(shù)或計算

在where子句中,如果索引是函數(shù)的一部分,優(yōu)化器將不再使用索引而使用全表掃描

禁止使用游標(biāo)

禁止使用觸發(fā)器

禁止使用存儲過程

禁止在查詢里指定索引

With(index=XXX)( 在查詢里我們指定索引一般都用With(index=XXX) )

隨著數(shù)據(jù)的變化查詢語句指定的索引性能可能并不最佳

索引對應(yīng)用應(yīng)是透明的,如指定的索引被刪除將會導(dǎo)致查詢報錯情龄,不利于排障

新建的索引無法被應(yīng)用立即使用迄汛,必須通過發(fā)布代碼才能生效

變量/參數(shù)/關(guān)聯(lián)字段類型必須與字段類型一致

避免類型轉(zhuǎn)換額外消耗的CPU,引起的大表scan尤為嚴(yán)重

參數(shù)化查詢

限制JOIN個數(shù)

單個SQL語句的表JOIN個數(shù)不能超過5個

過多的JOIN個數(shù)會導(dǎo)致查詢分析器走錯執(zhí)行計劃

過多JOIN在編譯執(zhí)行計劃時消耗很大

限制SQL語句長度及IN子句個數(shù)

在 IN 子句中包括數(shù)量非常多的值(數(shù)以千計)可能會消耗資源并返回錯誤 8623 或 8632骤视,要求IN子句中條件個數(shù)限制在100個以內(nèi)

盡量避免大事務(wù)操作

只在數(shù)據(jù)需要更新時開始事務(wù)鞍爱,減少資源鎖持有時間

增加事務(wù)異常捕獲預(yù)處理機制

禁止使用數(shù)據(jù)庫上的分布式事務(wù)

除非必要SELECT語句都必須加上NOLOCK

指定允許臟讀。不發(fā)布共享鎖來阻止其他事務(wù)修改當(dāng)前事務(wù)讀取的數(shù)據(jù)尚胞,其他事務(wù)設(shè) 置的排他鎖不會阻礙當(dāng)前事務(wù)讀取鎖定數(shù)據(jù)硬霍。允許臟讀可能產(chǎn)生較多的并發(fā)操作,但其代價是讀取以后會被其他事務(wù)回滾的數(shù)據(jù)修改笼裳。這可能會使您的事務(wù)出錯,向用戶顯示從未提交過的數(shù)據(jù)粱玲,或者導(dǎo)致用戶兩次看到記錄(或根本看不到記錄

使用UNION ALL替換UNION

UNION會對SQL結(jié)果集去重排序躬柬,增加CPU、內(nèi)存等消耗

查詢大量數(shù)據(jù)使用分頁或TOP

合理限制記錄返回數(shù)抽减,避免IO允青、網(wǎng)絡(luò)帶寬出現(xiàn)瓶頸

遞歸查詢層級限制

使用 MAXRECURSION 來防止不合理的遞歸 CTE 進入無限循環(huán)

EXISTS替代IN

盡量避免使用OR運算符

對于OR運算符,通常會使用全表掃描卵沉,考慮分解成多個查詢用UNION/UNION ALL來實現(xiàn)颠锉,這里要確認(rèn)查詢能走到索引并返回較少的結(jié)果集

增加事務(wù)異常處理機制

輸出列使用二段式命名格式

多表查詢 使用別名 查詢結(jié)果 別名.字段

4. 數(shù)據(jù)庫架構(gòu)

讀寫分離

  • 設(shè)計之初就考慮讀寫分離,哪怕讀寫同一個庫史汗,有利于快速擴容
  • 按照讀特征把讀分為實時讀和可延遲讀分別對應(yīng)到寫庫和讀庫
  • 讀寫分離應(yīng)該考慮在讀不可用情況下自動切換到寫端

Schema解耦

  • 禁止跨庫Join

數(shù)據(jù)生命周期

  • 根據(jù)數(shù)據(jù)的使用頻繁度琼掠,對大表定期分庫歸檔
  • 主庫/歸檔庫物理分離

日志類型的表應(yīng)分區(qū)或分表

  • 對于大的表格要進行分區(qū),分區(qū)操作將表和索引分在多個分區(qū)停撞,通過分區(qū)切換能夠快速實現(xiàn)新舊分區(qū)替換瓷蛙,加快數(shù)據(jù)清理速度,大幅減少IO資源消耗

頻繁寫入的表戈毒,需要分區(qū)或分表

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末艰猬,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子埋市,更是在濱河造成了極大的恐慌冠桃,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,013評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件道宅,死亡現(xiàn)場離奇詭異食听,居然都是意外死亡套么,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,205評論 2 382
  • 文/潘曉璐 我一進店門碳蛋,熙熙樓的掌柜王于貴愁眉苦臉地迎上來胚泌,“玉大人,你說我怎么就攤上這事肃弟$枋遥” “怎么了?”我有些...
    開封第一講書人閱讀 152,370評論 0 342
  • 文/不壞的土叔 我叫張陵笤受,是天一觀的道長穷缤。 經(jīng)常有香客問我,道長箩兽,這世上最難降的妖魔是什么津肛? 我笑而不...
    開封第一講書人閱讀 55,168評論 1 278
  • 正文 為了忘掉前任,我火速辦了婚禮汗贫,結(jié)果婚禮上身坐,老公的妹妹穿的比我還像新娘。我一直安慰自己落包,他們只是感情好部蛇,可當(dāng)我...
    茶點故事閱讀 64,153評論 5 371
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著咐蝇,像睡著了一般涯鲁。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上有序,一...
    開封第一講書人閱讀 48,954評論 1 283
  • 那天抹腿,我揣著相機與錄音,去河邊找鬼旭寿。 笑死警绩,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的许师。 我是一名探鬼主播房蝉,決...
    沈念sama閱讀 38,271評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼微渠!你這毒婦竟也來了搭幻?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 36,916評論 0 259
  • 序言:老撾萬榮一對情侶失蹤逞盆,失蹤者是張志新(化名)和其女友劉穎檀蹋,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,382評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡俯逾,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,877評論 2 323
  • 正文 我和宋清朗相戀三年贸桶,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片桌肴。...
    茶點故事閱讀 37,989評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡皇筛,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出坠七,到底是詐尸還是另有隱情水醋,我是刑警寧澤,帶...
    沈念sama閱讀 33,624評論 4 322
  • 正文 年R本政府宣布彪置,位于F島的核電站拄踪,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏拳魁。R本人自食惡果不足惜惶桐,卻給世界環(huán)境...
    茶點故事閱讀 39,209評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望潘懊。 院中可真熱鬧姚糊,春花似錦、人聲如沸卦尊。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,199評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽岂却。三九已至,卻和暖如春裙椭,著一層夾襖步出監(jiān)牢的瞬間躏哩,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,418評論 1 260
  • 我被黑心中介騙來泰國打工揉燃, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留扫尺,地道東北人。 一個月前我還...
    沈念sama閱讀 45,401評論 2 352
  • 正文 我出身青樓炊汤,卻偏偏與公主長得像正驻,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子抢腐,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,700評論 2 345

推薦閱讀更多精彩內(nèi)容