• 定义数据完整性


      关系模型带来的最大优点之一就是模型本身集成了数据完整性。作为模型的一部分而实施的数据完整性(也就是说,作为表定义的一部分)称为声明式(declarative)数据完整性。用代码来实施的数据完整性(例如,用存储过程或触发器)称为过程式(procedural)数据完整性。

      为属性选择的数据类型和是否允许为NULL值,甚至数据模型本身都是声明式数据完整性约束的例子。其他声明式约束包括主键、唯一约束(UNIQUE)、外键、检查约束(CHECK),以及DEFAULT约束。当用CREATE TABLE语句创建表时,可以同时定义这些约束;或者在已经创建好表之后,用ALTER TABLE语句增加这些约束。除了DEFAULT约束以外,其他所有约束都可以定义为组合约束(即基于一个或多个属性的约束)。

    一、主键约束(Primary Key Constraints)

      主键约束实施行的唯一约束,同时不允许约束属性取NULL值。约束属性中每一组唯一的值在表中只能出现一次,换句话说,表内的每行数据可以被唯一确定。如果试图在允许NULL值的列上定义主键约束,RDBMS会拒绝。每个表只能定义一个主键。下面以前面创建的Employees表为例,在它的empid列上定义一个主键约束:

     ALTER TABLE dbo.Employees
     ADD CONSTRAINT PK_Employees
     PRIMARY KEY(empid)
    

        定义好主键以后,就可以保证所有的empid值将是唯一而确定的。如果插入或更新一行违反数据约束的数据,RDBMS就会拒绝操作,生成一个报错。

      为了实施逻辑主键约束的唯一约束,SQL Server将在幕后创建一个唯一索引(unique index)。唯一索引是SQL Server为了实施唯一约束而采用的一种物理机制。也可以用索引(不一定是唯一索引)来加速查询的处理,避免对整个表进行不必要的扫描(类似于图书的索引)。

    二、唯一约束(Unique Constraints)

      唯一约束用来保证数据行的一个列(或一组列)数据的唯一,可以在数据库中实现关系模型的替换键(alternate key)的概念。与主键不同的是,在同一个表中可以定义多个唯一约束。此外,唯一约束也不限于只定义在NOT NULL列上。ANSI SQL支持两种类型的唯一约束,一种是只允许在唯一约束列中有一个列可以为NULL值,另一种则允许多个NULL值列。SQL Server只实现了前者。

    以下代码在Employees表中定义了ssn列上的一个唯一约束:

     ALTER TABLE dbo.Employees
     ADD CONSTRAINT UNQ_Employees_ssn
     UNIQUE(ssn);
    

      

    和主键一样,SQL Server也在幕后创建一个唯一索引,作为实施逻辑唯一约束的物理机制。

    三、外键约束

      外键约束用于实施引用完整性。这种约束在引用表(referencing table)的一组属性上进行定义,并指向被引用表(referenced table)中的一组候选键(主键或唯一约束)。注意:引用表和被引用表可能是同一个表。外键的目的是为了将外键列允许的值域限制为被引用列中现有的值。

      以下代码创建了一个名为Orders的表,其主键定义在orderid列上:

    IF OBJECT_ID('dbo.Orders','U') IS NOT NULL
         DROP TABLE dbo.Orders;
     CREATE TABLE dbo.Orders
     (
         orderid INT            NOT NULL,
         empid    INT            NOT NULL,
         custid    VARCHAR(10) NOT NULL,
         orderts    DATETIME    NOT NULL,
         qty        INT            NOT NULL,
         CONSTRAINT PK_Orders PRIMARY KEY(orderid)
     );
    

      

      如果现在想实施一个完整性规则,将Orders表的empid列支持的值域限制为现有的Employees表中empid列的值。为此,要在Orders表的empid列上定义一个外键约束,让它指向Employees表的empid列,如下所示

     ALTER TABLE dbo.Orders
     ADD CONSTRAINT FK_Orders_Employees
     FOREIGN KEY(empid)
     REFERENCES dbo.Employees(empid)
    

      

        类似地,如果想限制Employees表的mgrid列支持的值域为同一个表中已经存在的那些empid列的值,可以增加以下外键约束:

     ALTER TABLE dbo.Employees
     ADD CONSTRAINT FK_Employees_Employees
     FOREIGN KEY(mgrid)
     REFERENCES Employees(empid)
    

      

      注意:即使被引用的候选键列不存在NULL值,在外键列中也允许NULL值(例如Employees表中的mgrid)。

      前面两个外键的定义实施的引用操作称为“禁止操作(no action)“。禁止操作的含义是:当试图删除被引用表中的行,或更新被引用的候选键时,如果在引用表中存在相关的行,则此操作不能执行。例如,如果试图从Employees表中删除一个雇员数据行,而Orders表中同时还存在与这个雇员相关的订单数据行,RDBMS将拒绝执行这样的操作,并生成报错信息。

      可以定义具有级联操作的外键,以补偿这样的操作----为了当在引用表中存在相关的数据行时,可以删除被引用表中的数据行或更新被引用候选键属性。可以在外键定义中将ON DELETE和ON UPDATE选项定义为CASCADE、SET DEFAULT和SET NULL之类的操作。CASCADE的含义是:操作(删除或更新)将被级联到引用表中相关行。例如,ON DELETE CASCADE意味着当从被引用表中删除一行时,RDBMS也将从引用表中删除相关的行。SET DEFAULT和SET NULL意味着补偿操作会把相关行的外键属性分别设置为列的默认值或NULL值。注意:不论选择哪种操作,如果遇到了前面提及的NULL值异常,引用表将只有孤立的数据行。

    四、检查约束(Check)

      检查约束用于定义表中输入或修改一行数据之前必须满足的一个谓词。例如,以下的检查约束可以保证Employees表的salary列只支持正数:

     ALTER TABLE dbo.Employees
     ADD CONSTRAINT CHK_Employees_salary
     CHECK(salary>0);
    

      

      如果试图用非正数的salary值插入或更新数据行,RDBMS将拒绝这样的操作。注意:当谓词计算结果为FALSE时,检查约束将拒绝插入或更新数据行的操作。当谓词计算结果为TRUE或UNKNOWN时,RDBMS将会接受对数据行的修改。例如:salary为-1000将被拒绝,而salary为50000和NULL都可以被接受。

      当增加CHECK和FOREIGN KEY约束时,可以指定一个WITH NOCHECK选项,告诉RDBMS不必对现有的数据进行约束检查。通常认为这是一种不好的实践做法,因为这样不能保证数据的一致性。

      也可以禁用或激活现有的CHECK和FOREIGN KEY约束。

    五、默认约束(Default)

      默认约束与特定的属性关联。当插入一行数据时,如果没有为属性显示指定明确的值,就可以用一个表达式作为其默认值。例如,以下代码为orderts属性定义了一个默认约束(表示订单的时间戳):

     ALTER TABLE dbo.Orders
     ADD CONSTRAINT DFT_Orders_orderts
     DEFAULT(CURRENT_TIMESTAMP) FOR orderts;
    

         默认表达式会调用CURRENT_TIMESTAMP函数,由它返回当前的日期和时间值。在定义好默认表达式以后,当在Orders表插入一行数据,而且没有显示指定orderts属性时,SQL Server将把这个属性值设置为CURRENT_TIMESTAMP。

  • 相关阅读:
    stm32ADC+DMA串口发送实验
    凑算式
    全排列
    字符串相同
    判断值相同
    插入加号求最小值
    动态规划递归—最小子段和
    动态规划-最小子段和
    进程的描述和进程的创建
    系统调用下
  • 原文地址:https://www.cnblogs.com/ShaYeBlog/p/2696332.html
Copyright © 2020-2023  润新知