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的方式来定义,如果是临时表,禁止定义命名约束。

时间: 2024-11-06 07:28:54

SQL Server中有关约束(constraint)的一些细节的相关文章

SQL Server中使用Check约束提升性能

在SQL Server中,SQL语句的执行是依赖查询优化器生成的执行计划,而执行计划的好坏直接关乎执行性能. 在查询优化器生成执行计划过程中,需要参考元数据来尽可能生成高效的执行计划,因此元数据越多,则执行计划更可能会高效.所谓需要参考的元数据主要包括:索引.表结构.统计信息等,但还有一些不是很被注意的元数据,其中包括本文阐述的Check约束. 查询优化器在生成执行计划之前有一个阶段叫做代数树优化,比如说下面这个简单查询: 图1.简单查询 查询优化器意识到1=2这个条件是永远不相等的,因此不需要

十步优化SQL Server中的数据访问(转载)

原文地址:http://tech.it168.com/a2009/1125/814/000000814758.shtml 故事开篇:你和你的团队经过不懈努力,终于使网站成功上线,刚开始时,注册用户较少,网站性能表现不错,但随着注册用户的增多,访问速度开始变慢,一些用户开始发来邮件表示抗议,事情变得越来越糟,为了留住用户,你开始着手调查访问变慢的原因. 经过紧张的调查,你发现问题出在数据库上,当应用程序尝试访问/更新数据时,数据库执行得相当慢,再次深入调查数据库后,你发现数据库表增长得很大,有些表

SQL Server缺省约束、列约束和表约束

SQL Server缺省约束是SQL Server数据库中的一种约束,下面就为您介绍SQL Server缺省约束.列约束和表约束的定义方法啊,供您参考. SQL Server缺省约束 SQL Server缺省约束通过定义列的缺省值或使用数据库的缺省值对象绑定表的列,来指定列的缺省值.SQL Server 推荐使用缺省约束,而不使用定义缺省值的方式来指定列的缺省值. 定义SQL Server缺省约束的语法如下:CONSTRAINT constraint_nameDEFAULT constant_e

转载: SQL Server中的索引

http://www.blogjava.net/wangdetian168/archive/2011/03/07/347192.html 1 SQL Server中的索引 索引是与表或视图关联的磁盘上结构,可以加快从表或视图中检索行的速度.索引包含由表或视图中的一列或多列生成的键.这些键存储在一个结构(B 树)中,使 SQL Server 可以快速有效地查找与键值关联的行. 表或视图可以包含以下类型的索引: 聚集索引 聚集索引根据数据行的键值在表或视图中排序和存储这些数据行.索引定义中包含聚集索

SQL Server中临时表与表变量的区别

2009年02月20日 星期五  19:31 我 们在数据库中使用表的时候,经常会遇到两种使用表的方法,分别就是使用临时表及表变量.在实际使用的时候,我们如何灵活的在存储过程中运用它们,虽然它们 实现的功能基本上是一样的,可如何在一个存储过程中有时候去使用临时表而不使用表变量,有时候去使用表变量而不使用临时表呢? 临时表 临时表与永久表相似,只是它的创建是在Tempdb中,它只有在一个数据库连接结束后或者由SQL命令DROP掉,才会消失,否则就会一直存在.临时表在创建的时候都会产生SQL Ser

SQL Server中一些有用的日期sql语句

1.一个月第一天的 SELECT DATEADD(mm, DATEDIFF(mm,0,getdate()), 0) 2.本周的星期一 SELECT DATEADD(wk, DATEDIFF(wk,0,getdate()), 0) 3.一年的第一天 SELECT DATEADD(yy, DATEDIFF(yy,0,getdate()), 0) 4.季度的第一天 SELECT DATEADD(qq, DATEDIFF(qq,0,getdate()), 0) 5.当天的半夜 SELECT DATEAD

最简单删除SQL Server中所有数据的方法

原文:最简单删除SQL Server中所有数据的方法  最简单删除SQL Server中所有数据的方法 编写人:CC阿爸 2014-3-14 其实删除数据库中数据的方法并不复杂,为什么我还要多此一举呢,一是我这里介绍的是删除数据库的所有数据,因为数据之间可能形成相互约束关系,删除操作可能陷入死循环,二是这里使用了微软未正式公开的sp_MSForEachTable存储过程. 也许很多读者朋友都经历过这样的事情:要在开发数据库基础上清理一个空库,但由于对数据库结构缺乏整体了解,在删除一个表的记录时,

SQL Server中奇妙的NULL

相信大家在写SQL时都会有遇到NULL的经历吧,在一个table插入NULL,与NULL作比较等等. 1.NULL意思为缺失的值(missing value). 2.三值逻辑(three-valued-logic: TRUE,FALSE,UNKNOWN). 在SQL中有三个逻辑谓词:TURE,FALSE,UNKNOWN.在大多数的编程语言中只有TRUE和FALSE,而在SQL中独有UNKNOWN,之所有存在与NULL有关. 比如做如下比较: NULL>32;NULL=NULL;X+NULL>Y

理解SQL SERVER中的分区表(转)

简介 分区表是在SQL SERVER2005之后的版本引入的特性.这个特性允许把逻辑上的一个表在物理上分为很多部分.而对于SQL SERVER2005之前版本,所谓的分区表仅仅是分布式视图,也就是多个表做union操作. 分区表在逻辑上是一个表,而物理上是多个表.这意味着从用户的角度来看,分区表和普通表是一样的.这个概念可以简单如下图所示: 而对于SQL SERVER2005之前的版本,是没有分区这个概念的,所谓的分区仅仅是分布式视图: 本篇文章所讲述的分区表指的是SQL SERVER2005之