SQL Server中有關約束(constraint)的一些細節

來源:互聯網
上載者:User

標籤:儲存   意義   未命名   tle   自動產生   name   暫存資料表   檢查   情況   

原文:SQL Server中有關約束(constraint)的一些細節

 

本文出處:http://www.cnblogs.com/wy123/p/7350265.html 
(保留出處並非什麼原創作品權利,本人拙作還遠遠達不到,僅僅是為了連結到原文,因為後續對可能存在的一些錯誤進行修正或補充,無他)


SQL Server 資料庫中的約束(Constrint)是作用是為了保證資料庫的完整性和一致性,可以建表的時候指定某個欄位要符合某種約束(或者對已有表的欄位添加約束),比如唯一性(或者主鍵)約束,非空約束,預設值約束等
對於具體的約束,可以分為主鍵(唯一鍵)約束,預設值約束,檢查約束,外鍵約束等幾類。

 

約束的建立方式

  1,建表的時候指定

    如下,可以在建表的時候指定某些欄位滿足某種約束。

  2,以建立約束的方式指定

    也即在建表的時候沒有指定任何約束,在建表之後,以alter table的方式指定某些欄位上的約束

    

     

    對於Check或者Default約束,也可以事先定義出來規則(Rule),然後將規則綁定到對應表的欄位
     如下分別定義了一個check約束和預設值約束,然後將表的欄位綁定到對應的約束,這樣做的好處是對於某些複雜的約束,定義好約束之後就可以重用了
    需要注意的是,對於Rule來說,NULL值是不與任何規則衝突的,
    舉個例子,如下,雖然把TestConstrint.Sex欄位指定了規則Rule_Sex,如果Sex定義的是int,該欄位寫入資料的時候只能是0或者1,寫入2是失敗的,
    但是往該欄位寫入null值是可以的,因為null與規則指定的(0,1)相比沒有任何意義(或者沒有任何結果)

    

 

 約束的一些特點

    對於建表的時候指定的未命名的約束,SQL Server會自動產生尾碼隨機的預設的約束名字,為了增加規範性,正常情況下是不允許這麼寫的,因為我們不希望看到資料庫中一堆亂七八髒的命名。

    

     如果是指定約束的名字,看起來就規範多了。

如果是通過定義規則,然後綁定到表的欄位的情況下,通過SSMS的圖形介面,是看不到約束展開之後的內容的(雖然這個約束是生效的)

 

 資料庫約束中那些不容易被注意的坑

    約束看起來非常簡單,不管是在建表的時候直接指定,或者是通過alter 表的方式增加約束,看起來都沒有任何問題,條條大道通羅馬,不過裡面還是有一些小坑的。
    一個資料庫中的約束不允許重名。
    也就是意味著,不同的表之間,或者表上與自訂約束之間,都不能存在同名的情況,包括主鍵約束(不能同名),檢查約束(check),預設值約束等,都不能同名
    約束的道理跟表一樣,一個庫的一個schema下中不能定義同名的表一個道理,一個庫的一個schema下不能定義同名的約束一樣。
    現在也不難理解,為什麼sqlserver預設產生的約束的名字,後面是一串隨機字元了吧?

    1,表與表之間的約束不能同名

    

    2,表與自訂約束名之間不能同名。

    

    當然有人會說,這有什麼,定義的時候報錯就知道了,還有更大的坑。
    這裡涉及到約束的另一種定義方法,建表的過程中指定命名的主鍵約束。

 

    比如如下的定義暫存資料表的指令碼,看起來沒有任何問題,也確實沒有任何問題,
    實際中遇到的一個開發人員的問題,編寫的預存程序中定義了暫存資料表,定義暫存資料表的時候指定了命名的主鍵約束(可能是抄的物理表的定義方式),測試通過並發布到生產環境中,一切看起來非常正常。
    發布之後測試了兩把,也表現為正常,等到系統真正被使用者使用的時候,部分使用者反饋系統(涉及到這個功能的地方)偶爾會報錯,時而正常,時而不正常(其實這種問題最難診斷的了)。
    監控應用程式會發現,某個時間段之內,發現這個預存程序會連續地報錯一種錯誤,錯誤原因就是“無法建立索引或者約束”
    開發人員也很委屈,提交完代碼之後,明明是測試通過了的,更可惡的是,偶爾會報錯,大部分時間是正常的。

    通過觀察其代碼,然後冷靜下來想一想,也不難理解,資料庫中的約束是不能同名的,當然暫存資料表生存的臨時庫也不例外,
    暫存資料表用完就會自動銷毀沒有錯,意味著如果所有的Session都是串列執行,這個完全沒有問題。
    但是一旦出現並發調用的情況,不同的Session會同時調用這個預存程序,
    一旦並發調用這個預存程序,不同的Session會建立同一個名字的約束,鐵定只有一個會成功,這麼看,單線程測試正常,並發上來之後報錯也就不難理解了。

    

總結: 

    為了保證資料庫的完整性和一致性(外鍵,本文未涉及),可以使用約束來達到這個目的,但是約束本身有自己的某些規則和特點,它跟其他資料庫物件並沒有不同的,都不允許同一個schema下存在同名的對象。
    如果沒有按照其自身的某些規則來使用,就有可能造成某些潛在的問題。
    為了規範約束的命名,在定義約束名字的時候,要嚴格遵循簡寫首碼+schema+tableName+columnName的方式來定義,如果是暫存資料表,禁止定義命名約束。

 

SQL Server中有關約束(constraint)的一些細節

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.