详解SQL Server数据库架构和对象、定义数据完整性

前言

本节我们继续SQL之旅,本节我们如题来讲讲一些基本知识以及需要注意的地方,若有不妥之处,还望指出,简短的内容,深入的理解。

数据库架构和对象

数据库包含架构,而架构又包含对象,架构可以看做是表、视图、存储过程等对象的容器。架构是一个命名空间,它被用做对象名称的前缀,比如在Cnblogs的架构中有一个名称为Blogs的表,此时我们用架构式限定式名称(即两部分式对象名称)所以Blogs表示为Cnblogs.Blogs。如果我们引用对象时省略了架构名称,SQL Server将会检查对象是否存在用户的默认架构中,如果不是则检查是否存在dbo架构中,当我们创建数据库时,在用户没有显式地指定一个其他架构时,数据库会自动dbo架构作为我们默认的架构。微软也建议在代码中引用对象时始终用【两部分式】对象名称,基于此我们推荐的建议时在引用对象时建议:在代码中始终使用架构限定式的对象名称即两部分式名称。

定义数据完整性

关系模型最大好处则是我们能够自定义数据完整性,同时数据完整性是关系模型不可或缺的一部分,什么是数据完整性,说的通透一点则是对数据进行声明式约束,在SQL Server中声明式约束包括:主键约束、唯一键约束、外键约束、检查约束、默认约束。下面我们一一来介绍这几个约束。

主键约束

下面首先来创建一个表:

CREATE TABLE Blogs
(
 BlogId INT NOT NULL,
 BlogName VARCHAR(max) NOT NULL
);

主键约束用来强制行的唯一性,上述我们无法表示行的唯一性,现在我们添加约束来强制行的唯一性,用PRIMARY KEY约束如下。

ALTER TABLE dbo.Blogs
ADD CONSTRAINT pk_constraint_blogId PRIMARY KEY(BlogId)

在键文件夹中则生成对列BlogId的约束即升级为主键,如下:

当对主键插入重复数据时会提示插入重复键失败,违反约束。为了强制逻辑主键约束的唯一性,SQL Server会在后台创建一个唯一索引,唯一索引是SQL Server为了强制唯一性而使用的一种物理机制,索引(不一定是唯一索引)是为了加速查询,避免不必要的全表扫描。

唯一约束

唯一约束强制行的唯一性,允许我们在自己的数据库中实现关系模型的备用键概念。它与主键不同,可以在同一个表中定义多个唯一约束同时允许多个NULL标记(类似NULL标记彼此不同),但是SQL Server拒绝重复NULL标记(类似两个NULL标记彼此相等)通过UNIQUE来约束。如下所示对BlogName进行唯一约束。

ALTER TABLE dbo.Blogs
ADD CONSTRAINT uq_constraint_blogname UNIQUE(BlogName)

此时添加唯一约束结果如下

一个个尝试发现居然对字符串和文本类型无法添加唯一约束,涨知识了,不知道为何不能添加唯一约束(补充:在sql 2008R2却可以建立,真纳闷)。

通过上述对主键约束和唯一约束的讲解,我们就搞清楚主键约束和唯一约束了呢?博主看的是SQL Server2012基础教程,教程就讲到这里结束,至此我是还没弄清楚,主键约束和唯一约束到底应该怎样用以及主键约束和唯一约束有什么区别?

(1)对键添加主键约束,那么能不能在此基础上添加唯一约束呢?

我们在上述已经添加BlogId为主键约束的基础上来添加唯一约束,如下

ALTER TABLE dbo.Blogs
ADD CONSTRAINT uq_constraint_blogId UNIQUE(BlogId)

通过上述我们知道对同一列既可以添加主键约束也可以添加唯一约束。

(2)上述基础教程中也讲到唯一性约束的列可以允许多个NULL标记,真的是这样?我们看看另外一种情况

我们创建如下表

create table test (
Id INT NOT NULL,
NAME VARCHAR(max) NOT NULL
)

接下来对Id约束为唯一约束。

ALTER TABLE test
ADD CONSTRAINT UNQ UNIQUE(Id)

此时我们对Id添加一个NULL试试看,结果可以插入还是不可以呢?

INSERT INTO TEST VALUES(NULL,'B')

不是唯一约束的列可以为NULL么,难道教程出错了或者sb翻译出错了么,这事我们应该看看定义表时列Id是不能为NULL的,所以到这里我们的疑问算是结束了,唯一约束的列是可以为NULL的。

(3)主键约束和唯一约束的区别?

主键约束:通过对列强制唯一性,此时主键在列上创建一个聚集索引且主键不能为空。

唯一约束:通过对列强制唯一性,此时在列上创建的唯一键为非聚集索引,唯一约束仅仅允许一个NULL值。

二者最大区别在于:主键约束强调的是行的唯一性来标识行,不允许重复,而唯一约束强调的是列的唯一性不允许重复。

(4)主键约束和唯一约束都可以建立唯一索引

【1】唯一索引通过主键约束和唯一约束都可以创建。

  如果表中不存在聚集索引的话并且我们没有明确指定一个非聚集索引的话,通过主键约束将自动创建一个唯一聚集索引。

  当创建唯一约束时,默认情况下一个非聚集索引会被创建来强制一个唯一约束,如果在表中聚集索引不存在的话,我们可以指定一个聚集索引。

【2】唯一约束和唯一索引区别

我们接下来创建一个表,如下:

CREATE TABLE test
(
 Id INT NOT NULL PRIMARY KEY,
 Code INT
)

首先我只对Code创建唯一索引

CREATE UNIQUE INDEX uq_ix ON dbo.test(Code)

此时我们再在Code列上添加唯一约束:

ALTER TABLE StudyTest.dbo.test
ADD CONSTRAINT uq_nonclster_ix UNIQUE(Code)

此时我们在索引文件夹下可以看到所创建的唯一索引和唯一约束所创建的唯一非聚集索引

看起来二者都是唯一非聚集索引,只是图标不一样而已,二者应该是一样的吧

(5)唯一索引和唯一约束的区别在哪里?唯一约束能替代唯一索引吗?

【1】返回错误码不同

当我们插入数据时,唯一索引返回错误代码为2601

唯一约束返回的错误代码为2627

【2】唯一约束不能筛选,而唯一索引能进行筛选,如下

CREATE UNIQUE NONCLUSTERED INDEX uq_code_filter
ON test(Code) WHERE Code is not null;

总结:上述只是表示二者在使用上的不同,对于唯一约束和唯一索引并没有什么很大的差异,同时对于唯一约束和唯一索引在查询性能上也没有很大的不同,对于唯一约束我们一直强调的是数据完整性,对列进行唯一约束保证其值不能重复,这同时对于建立索引查询时性能会有显著的提升。

外键约束

外键约束也用来强制数据完整性,外键的目的是限制在外键列中允许的值主要存在于那些被引用列中。下面我们来演示外键约束,我们创建如下雇员表和部门表:

USE SQLStudy;
IF OBJECT_ID('dbo.Department','U') IS NOT NULL
 DROP TABLE dbo.Department
CREATE TABLE [dbo].[Department] (
 [DepartmentID] INT NOT NULL IDENTITY,
 [DepartmentName] VARCHAR(50)
)
GO
CREATE TABLE [dbo].[Employee] (
 [EmployeeID] INT NOT NULL IDENTITY,
 [FirstName] VARCHAR(50),
 [LastName] VARCHAR(50),
 [DepartmentID] INT
)

由上我们知道雇员表是依赖于部门表,一个雇员到底是在哪个部门呢?所以此时雇员表中的部门Id应该是部门表中部门Id的外键,接下来我们进行外键约束,如下:

ALTER TABLE [dbo].[Employee]
ADD CONSTRAINT [FK_Employee_Department]
FOREIGN KEY ( [DepartmentID] ) REFERENCES [dbo].[Department] ( [DepartmentID] )

此时执行完你会发现如下错误:

现在我们知道外键可不是随便就能建立的,为什么会出现我们引用部门表并将其雇员表中部门Id作为外键约束的错误呢?通过上述错误我们知道在引用表即部门表中没有其匹配的主键或候选键,这是指的什么,它的意思是引用表中的外键必须是被引用表中的完整主键,而不是作为被引用表的一部分,说的更加明确一点则是被引用表即部门表中的部门Id应该是主键,在这里我们未对部门表中部门Id进行主键约束而导致如上错误。我们添加主键约束即可

ALTER TABLE [dbo].[Department]
ADD CONSTRAINT [PK_Department] PRIMARY KEY ( [DepartmentID] )
GO

此时外键约束才算建立完成。到这里其实还存在一种可能,当我们需要引用的表中已经存在一个主键,而不是由外键引用的列,此时部门表中的Id不是作为主键,而我们雇员表中的部门Id又需要将部门Id作为外键约束,这个时候我们只需要在部门表中部门Id上创建唯一或者唯一约束即可。

CREATE UNIQUE INDEX [IX_DepartmentID]
ON [dbo].[Department] ( [DepartmentID] )
GO
ALTER TABLE [dbo].[Employee]
ADD CONSTRAINT [FK_Employee_Department]
FOREIGN KEY ( [DepartmentID] ) REFERENCES [dbo].[Department] ( [DepartmentID] )
GO

或者唯一约束

CREATE UNIQUE INDEX [IX_DepartmentID]
ON [dbo].[Department] ( [DepartmentID] )
GO
ALTER TABLE [dbo].[Employee]
ADD CONSTRAINT [FK_Employee_Department]
FOREIGN KEY ( [DepartmentID] ) REFERENCES [dbo].[Department] ( [DepartmentID] )
GO

Check约束

Check约束定义一个谓词,要插入到表中的行或者被修改的行必须满足此要求。

比如在雇员表中再添加一个薪水字段,很显然薪水必须为正值,此时我们则可以像如下进行Check约束

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

如果试图插入非正值,将会被数据库所拒绝。我们需要注意的是Check约束只是对于结果为false才会拒绝,如果结果为True或者UNKNOWN是会被接受,即当结果为NULL时也会插入或者修改成功。

默认约束

默认约束无非就是当建立表时给定一个默认值,常见的是在表中存在添加数据的日期这一列,此时我们完全给定一个默认值,取当前的日期。默认约束用DEFAULT关键字表示。例如如下:

ALTER TABLE dbo.Employees
ADD CONSTRAINT DFT_Employees_updateTime
DEFAULT(GETDATE()) FOR UpdateTime

总结

本节我们详细讲解了主键约束和唯一约束这一块,其余相对比较简单,算是略过,到此结束,下节再会。

以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流,同时也希望多多支持我们!

(0)

相关推荐

  • 浅述SQL Server的语句类别 数据库范式 系统数据库组成

    前言 终于等到这一天,我要开始重新系统学习数据库了,关于数据库这块,不出意外的话,每天会定时更新一篇且内容不会包含太多,简短的内容,深入的理解. SQL语句类别 SQL语句包括以下三个类别 (1)数据定义语言(Data Definnition Language)即DDL,我们数据最终从何而来,当然首先必须得建立表,所以它包括CREATE.ALTER.DROP表. (2)数据操作语言(Data Manipulation Language)即DML,我们对数据需要进行什么操作,当然无非就是增删改查,

  • 详解SQL Server中的数据类型

    前言 前面几篇文章我们讲解了索引有关知识,这一节我们再继续我们下面内容讲解,简短的内容,深入的理解. 数据类型 SQL Server支持两种字符数据类型,一种是常规,另外一种则是Unicode.常规数据类型包括CHAR和VARCHAR,Unicode数据类型包括NCAHR和NVARCHAR.常规字符的每个字符使用1个字节存储,而Unicode数据的每个字符要求2个字节.常规字符列限制为仅仅只针对于英语,而Unicode则是针对于多种语言.两种字符数据类型的文本表示方式也不相同,在表示常规字符文本

  • 浅述SQL Server的聚焦强制索引查询条件和Columnstore Index

    前言 本节我们再来穿插讲讲索引知识,后续再讲数据类型中的日期类型,简短的内容,深入的理解. 强制索引查询条件 前面我们也讲了一点强制索引查询的知识,本节我们再来完整的讲述下 (1)SQL Server使用默认索引 USE TSQL2012 GO SELECT * FROM Sales.Orders 上述就不用我再啰嗦了,使用默认主键创建的聚集索引来执行查询执行计划. (2)SQL Server使用强制索引 USE TSQL2012 GO SELECT custid FROM Sales.Orde

  • 在SQL Server 2005所有表中搜索某个指定列的方法

    有时候我们只知道列的名字,但是不知道这列数据到底在哪个表里面,那么可以用下面的办法把含有这列数据的表查找出来. 复制代码 代码如下: Select O.name objectName, C.name ColumnName from sys.columns C inner join sys.objects O ON C.object_id=O.object_id where C.name like '%ColumnName%'order by O.name, C.name 在你实际试用中,把Col

  • 浅析SQL Server的聚焦使用索引和查询执行计划

    前言 上一篇<浅析SQL Server 聚焦索引对非聚集索引的影响>我们讲了聚集索引对非聚集索引的影响,对数据库一直在强调的性能优化,所以这一节我们统筹讲讲利用索引来看看查询执行计划是怎样的,简短的内容,深入的理解. 透过索引来看查询执行计划 我们首先来看看第一个例子 1.默认使用索引 USE TSQL2012 GO SELECT orderid FROM Sales.Orders SELECT * FROM Sales.Orders 上述我们看到第2个查询的所需要的开销是第1个查询开销的3倍

  • 详解SQL Server的简单查询语句

    前言 对于一些原理性文章园中已有大量的文章尤其是关于索引这一块,我也是花费大量时间去学习,对于了解索引原理对于后续理解查询计划和性能调优有很大的帮助,而我们只是一些内容进行概括和总结,这一节我们开始正式步入学习SQL中简单的查询语句,简短的内容,深入的理解. 简单查询语句 所有复杂的语句都是由简单的语句组成基本都是由SELECT.FROM.WHERE.GROUP BY.HAVING.ORDER BY等组成,当然还包括一些谓词等等.比如当我们要查询某表中所有数据时我们会像如下进行. SELECT

  • 如何快速删掉SQL Server登录时登录名下拉列表框中的选项

    问题: 我以前创建了一个登录名如kpi,之后在"安全性-登录名" 里删掉了,但是每次登录时,登录名的下拉框中总是能显示登录名kpi,怎么把它删掉呢? 解决方案: 1).SQL Server 2008 R2和SQL Server 2008 先关闭数据库登录窗口,然后删除: %AppData%\Microsoft\Microsoft SQL Server\100\Tools\Shell\下的SqlStudio.bin文件.(直接在资源管理器中粘贴路径)再打开SSMS就看不到了. 2).SQ

  • 浅析SQL Server的分页方式 ISNULL与COALESCE性能比较

    前言 上一节我们讲解了数据类型以及字符串中几个需要注意的地方,这节我们继续讲讲字符串行数同时也讲其他内容和穿插的内容,简短的内容,深入的讲解.(可参看文章<详解SQL Server中的数据类型>) 分页方式 在SQL 2005或者SQL 2008中我们是利用ROW_NUMBER开窗函数来进行分页的,关于开窗函数,我们在SQL进阶中会详细讲讲.如下: USE TSQL2012 GO DECLARE @StartRow INT DECLARE @EndRow INT SET @StartRow =

  • 浅析SQL Server 聚焦索引对非聚集索引的影响

    前言 在学习SQL 2012基础教程过程中会时不时穿插其他内容来进行讲解,相信看过SQL Server 2012 T-SQL基础教程的童鞋知道前面写的所有内容并非都是摘抄书上内容,如若是这样那将没有任何意义,学习的过程必须同时也是一个思考的过程,无论是独立思考也好还是查资料也罢都是思考而非走马观花,要不然过一段时间又会健忘.简短的内容,深入的理解. 话题 非聚集索引定义:非聚集索引也是一个B树结构,与聚集索引不同的是,B树的叶子节点存的是指向堆或聚集索引的指针.你真的理解了吗??你能举出例子吗?

  • 详解SQL Server数据库架构和对象、定义数据完整性

    前言 本节我们继续SQL之旅,本节我们如题来讲讲一些基本知识以及需要注意的地方,若有不妥之处,还望指出,简短的内容,深入的理解. 数据库架构和对象 数据库包含架构,而架构又包含对象,架构可以看做是表.视图.存储过程等对象的容器.架构是一个命名空间,它被用做对象名称的前缀,比如在Cnblogs的架构中有一个名称为Blogs的表,此时我们用架构式限定式名称(即两部分式对象名称)所以Blogs表示为Cnblogs.Blogs.如果我们引用对象时省略了架构名称,SQL Server将会检查对象是否存在用

  • 详解SQL Server数据库状态和文件状态

    数据库状态 (database states) 查询数据库的当前状态 : 1.查询所有数据库的状态 ,通过sys.databases目录视图的state_desc列 user master go select state_desc ,[name] from sys.databases go 2.查询指定数据库的状态,通过DATABASEPROPERTYEX函数的Status属性 select DATABASEPROPERTYEX('demoData','status') go 状态: ONLIN

  • 详解SQL Server数据库链接查询的方式

    SQL Server数据库链接查询的方式的相关知识是本文我们主要要介绍的内容,我们知道,通过连接运算符可以实现多个表查询.连接是关系数据库模型的主要特点,也是它区别于其它类型数据库管理系统的一个标志.多表连接查询是使用Sql的基本操作,但连接的方式却有多种,熟练使用这些连接方式能够简化Sql语句,提高数据库运行效率. 在关系数据库管理系统中,表建立时各数据之间的关系不必确定,常把一个实体的所有信息存放在一个表中.当检索数据时,通过连接操作查询出存放在多个表中的不同实体的信息.连接操作给用户带来很

  • 详解SQL Server如何修改数据库物理文件的存在位置

    前言 大家应该都知道SQL Server创建新库时,默认会把数据存放在C盘中,一旦数据库中的存储数据多了以后,C盘的空间就会所剩无几.解决方案是将存放数据的物理文件迁移到其他盘. 具体流程为: 1.将现有的数据库脱机 ALTER DATABASE DB1 SET OFFLINE WITH ROLLBACK IMMEDIATE; 2.将数据库文件移到新的位置 文件复制完成以后需要:右键-属性-安全-在组或用户名处添加Authenticated Users-更改该组权限为完全权限,否则接下来的操作会

  • 详解SQL Server 2016快照代理过程

    本文我们通过SQL Server 2016一个实例数据表,给大家详细分析了快照代理过程遇到的问题和解决办法,并对快照生成过程做了详细说明,以下是全部内容: 概述 快照代理准备已发布表的架构和初始数据文件以及其他对象.存储快照文件并记录分发数据库中的同步信息. 快照代理在分发服务器上运行:SQLServer2016版本对快照代理做了一些比较好的优化,接下来详细了解一下快照的执行过程. 一.快照代理文件 在执行快照作业是会在指定的快照目录生成4种类型的文件. BCP文件:发布对象的数据文件. IDX

  • 图文详解SQL Server 2008R2使用教程

    本文为大家分享了SQL Server 2008R2简单使用教程,供大家参考,具体内容如下 1 首先找到开始菜单中相关内容:如下图:安装的组件不同可能有所不同:我的电脑中包括如下项: 商业智能:管理控制台:导入和导出数据:分析服务:集成服务:配置工具:文档和教程:性能工具: 因为偶装的组件多: 2 进入管理控制台 首先是登录:服务器类型选择 数据库引擎:此处先用Windows身份验证登录: 3 进入管理控制台 界面如下:看到 数据库 下有四个子项,系统数据库.数据库快照.ReportServer.

  • 详解SQL Server中的事务与锁问题

    一  概述 在数据库方面,对于非DBA的程序员来说,事务与锁是一大难点,针对该难点,本篇文章试图采用图文的方式来与大家一起探讨. "浅谈SQL Server 事务与锁"这个专题共分两篇,上篇主讲事务及事务一致性问题,并简略的提及一下锁的种类和锁的控制级别. 下篇主讲SQL Server中的锁机制,锁控制级别和死锁的若干问题. 二   事务 1   何为事务 预览众多书籍,对于事务的定义,不同文献不同作者对其虽有细微差别却大致统一,我们将其抽象概括为: 事务:指封装且执行单个或多个操作的

  • 图文详解SQL Server 2008 R2安装配置方法

    安装sql server2008 R2的方法,轻松简单易操作,按照操作一步一步来. 工具: sql server 2008 R2安装包一个(从网上下载) 方法/步骤: 安装包解压 解压后,打开setup.exe文件,选择安装,显示如图: 选择全新安装或向现有安装添加功能 点确定 输入 企业版序列号:R88PF-GMCFT-KM2KR-4R7GB-43K4B 点我接受许可条款,点下一步 点安装,如果操作系统没有安装.net framet3.5 sp1 ,将会自动安装. 必备环境全部通过后,点下一步

  • 详解SQL Server 2008工具SQL Server Profiler

    一.SQL Profiler工具简介 SQL Profiler是一个图形界面和一组系统存储过程,其作用如下: 1.图形化监视SQL Server查询: 2.在后台收集查询信息: 3.分析性能: 4.诊断像死锁之类的问题: 5.调试T-SQL语句: 6.模拟重放SQL Server活动: 也可以使用SQL Profiler捕捉在SQL Server实例上执行的活动.这样的活动被称为Profiler跟踪. 1.Profiler跟踪 从开始=>所有程序=>Microsoft SQL Server 2

随机推荐