sqlserver数据库的对象有哪些(详解SQL Server数据库架构和对象、定义数据完整性)
sqlserver数据库的对象有哪些
详解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
总结
本节我们详细讲解了主键约束和唯一约束这一块,其余相对比较简单,算是略过,到此结束,下节再会。
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流,同时也希望多多支持开心学习网!
- sqlserver备份数据库语句(SQL SERVER 数据库备份的三种策略及语句)
- sqlserver怎么查看数据库版本(Sql Server数据库各版本功能对比)
- sql server提供的聚合函数(SQLServer行列互转实现思路聚合函数)
- windows安全策略设置sqlserver(SQLServer 错误: 15404,无法获取有关 Windows NT 组/用户 WIN-8IVSNAQS8T7Administrator 的信)
- sqlserver调试存储过程(sql server2008调试存储过程的完整步骤)
- sqlserver中的存盘按钮在哪(SQL Server 2016里的sys.dm_exec_input_buffer的问题)
- sqlserver 添加分区(SQL Server 数据库分区分表水平分表详细步骤)
- SqlServer2016模糊匹配的三种方式及效率问题简析(SqlServer2016模糊匹配的三种方式及效率问题简析)
- sqlserver如何生成xml文件(实现SQL Server 原生数据从XML生成JSON数据的实例代码)
- sqlserver数据库技术及应用教程(SQLServer2019 数据库的基本使用之图形化界面操作的实现)
- sqlserver小结(基于sqlserver的四种分页方式总结)
- sqlserver 锁表原因(SQL Server学习笔记之事务、锁定、阻塞、死锁用法详解)
- sqlserver2012知识点(SQL Server 2012 安全概述)
- sqlserver2008收缩数据文件(SQL2008 详解直接将XML存入到SQL中)
- sqlserver安装与使用教程(SQL Server 2017 Developer的下载、安装、配置及SSMS的下载安装配置图文教程详解)
- sqlserver拒绝访问怎么办(SQL server服务显示远程过程调用失败的解决方法)
- 苏志燮赵恩静结婚,韩国四大公共财产变三人,这么快就有替补了(苏志燮赵恩静结婚)
- 《内在美》后,一大波新韩剧来袭,李钟硕朴信惠宋慧乔玄彬回归(一大波新韩剧来袭)
- 给孩子选购保温杯,注意这4个步骤,比颜值更重要(给孩子选购保温杯)
- 保温好 容量大 颜值高 保温杯你给娃娃买对了吗(保温好容量大颜值高)
- 《道德经》 人生避开骄狂,才能免去祸患(道德经人生避开骄狂)
- 郭麒麟(郭麒麟)
热门推荐
- php数组实例说明(PHP检测一个数组有没有定义的方法步骤)
- mysql insert into 怎么用(MySQL中INSERT的一般用法)
- yii2对比springboot(Yii框架实现对数据库的CURD操作示例)
- 怎么查看nginx支持rewrite(nginx里的rewrite跳转的实现)
- asp.net使用swfupload上传
- laravel数据库切换(实现laravel 插入操作日志到数据库的方法)
- JS中call和apply区别
- python面向对象实例教程(Python面向对象程序设计类的多态用法详解)
- pythonmatplotlib怎么设置图像(完美解决Python matplotlib绘图时汉字显示不正常的问题)
- python 怎么解析中文(Python中一般处理中文的几种方法)
排行榜
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9