SQLServer之FOREIGN KEY约束
FOREIGN KEY约束添加规则
1、外键约束并不仅仅可以与另一表的主键约束相链接,它还可以定义为引用另一个表中 UNIQUE 约束的列。
2、如果在 FOREIGN KEY 约束的列中输入非 NULL 值,则此值必须在被引用列中存在;否则,将返回违反外键约束的错误信息。 若要确保验证了组合外键约束的所有值,请对所有参与列指定 NOT NULL。
3、FOREIGN KEY 约束仅能引用位于同一服务器上的同一数据库中的表。 跨数据库的引用完整性必须通过触发器实现。
4、FOREIGN KEY 约束可引用同一表中的其他列。 此行为称为自引用。
5、在列级指定的 FOREIGN KEY 约束只能列出一个引用列。 此列的数据类型必须与定义约束的列的数据类型相同。
6、在表级指定的 FOREIGN KEY 约束所具有的引用列数目必须与约束列列表中的列数相同。 每个引用列的数据类型也必须与列表中相应列的数据类型相同。
7、对于表可包含的引用其他表的 FOREIGN KEY 约束的数目或其他表所拥有的引用特定表的 FOREIGN KEY 约束的数目, 数据库引擎 都没有预定义的限制。 尽管如此,可使用的 FOREIGN KEY 约束的实际数目还是受硬件配置以及数据库和应用程序设计的限制。 表最多可以将 253 个其他表和列作为外键引用(传出引用)。 SQL Server 2016 (13.x) 将可在单独的表中引用的其他表和列(传入引用)的数量限制从 253 提高至 10,000。 (兼容性级别至少必须为 130。)数量限制的提高带来了下列约束:
DELETE 和 UPDATE DML 操作支持大于 253 个外键引用。 不支持 MERGE 操作。
对自身进行外键引用的表仍只能进行 253 个外键引用。
列存储索引、内存优化表和 Stretch Database 暂不支持进行超过 253 个外键引用。
8、对于临时表不强制 FOREIGN KEY 约束。
9、如果在 CLR 用户定义类型的列上定义外键,则该类型的实现必须支持二进制排序。
10、仅当 FOREIGN KEY 约束引用的主键也定义为类型 varchar(max) 时,才能在此约束中使用类型为varchar(max) 的列。
使用SSMS数据库管理工具添加外键约束
本示例演示当表结构已存在时添加外键约束,创建表时添加外键约束步骤和表结构存在时添加外键步骤相同。示例演示如下:
1、连接数据库,打开要添加外键的数据表-》右键点击-》选择设计。

2、在表设计窗口-》选择要添加外键的数据行-》右键点击-》选择关系。

3、在外键关系窗口中-》点击添加。

4、添加完毕后-》首先修改表和列规范。

5、在表和列窗口中-》输入外键名-》在左边选择主表和关联的列-》在右边选择从表和作为外键的列-》点击确定。

6、在外键关系窗口中-》可选择添加或者不添加外键描述-》可选择添加或者不添加修改或者删除数据时级联操作-》可选择添加或者不添加强制外键约束-》可选择添加或者不添加强制用于复制-》点击关闭。

7、点击保存按钮(ctrl+s)-》此时表会弹出警告窗口,点击是-》刷新查看外键是否添加成功。


使用T-SQL脚本添加外键约束
当表结构已存在时
如果要添加约束的表已存在外键约束,需要先删除外键约束再添加外键约束。如果不存在外键约束可以添加外键约束。
语法:
if exists(select * from sysobjects where name=约束名)
alter table 数据库名.[dbo].表名 drop constraint 约束名;
alter table 数据库名.[dbo].表名 with check add constraint 约束名 foreign key(列名)
references 数据库名.[dbo].表名(列名)
on delete cascade
on update cascade;
go
示例:
if exists(select * from sysobjects where name='t1_t2')
alter table [testss].[dbo].[test1] drop constraint t1_t2;
alter table [testss].[dbo].[test1] with check add constraint t1_t2 foreign key(classid)
references [testss].[dbo].[test2](id)
on delete cascade
on update cascade;
go

在新表中创建外键
语法:
if exists( select * from sysobjects where name=表名 and type ='U')
drop table 表名;
go
--当表结构不存在时
--建表语法声明
create table 表名
(
--字段声明
列名 int identity(1,1) not null,
列名 int,
primary key clustered(id asc) with(ignore_dup_key=off) on [primary], --主键索引声明
constraint 外键名 foreign key(列名)
references 主表名(列名)
on update cascade--是否级联操作
on delete cascade
)on [primary]
--字段注释声明
exec sys.sp_addextendedproperty @name=N'MS_Description', @value=N'列说明' , @level0type=N'SCHEMA',
@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'表名', @level2type=N'COLUMN',@level2name=N'列名';
exec sys.sp_addextendedproperty @name=N'MS_Description', @value=N'列说明' , @level0type=N'SCHEMA',
@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'表名', @level2type=N'COLUMN',@level2name=N'列名';
go
示例:
if exists( select * from sysobjects where name='test1'and type ='U')
drop table test1;
go
--当表结构不存在时
--建表语法声明
create table test1
(
--字段声明
id int identity(1,1) not null,
name nvarchar(50) null,
sex nvarchar(50) null,
age nvarchar(50) null,
classid int,
primary key clustered(id asc) with(ignore_dup_key=off) on [primary], --主键索引声明
constraint t3_t4 foreign key(classid)
references test2 (id)
on update cascade
on delete cascade
)on [primary]
--字段注释声明
exec sys.sp_addextendedproperty @name=N'MS_Description', @value=N'id主键' , @level0type=N'SCHEMA',
@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'test1', @level2type=N'COLUMN',@level2name=N'id';
exec sys.sp_addextendedproperty @name=N'MS_Description', @value=N'姓名' , @level0type=N'SCHEMA',
@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'test1', @level2type=N'COLUMN',@level2name=N'name';
exec sys.sp_addextendedproperty @name=N'MS_Description', @value=N'性别' , @level0type=N'SCHEMA',
@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'test1', @level2type=N'COLUMN',@level2name=N'sex';
exec sys.sp_addextendedproperty @name=N'MS_Description', @value=N'年龄' , @level0type=N'SCHEMA',
@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'test1', @level2type=N'COLUMN',@level2name=N'age';
exec sys.sp_addextendedproperty @name=N'MS_Description', @value=N'班级id' , @level0type=N'SCHEMA',
@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'test1', @level2type=N'COLUMN',@level2name=N'classid';
go

FOREIGN KEY约束优缺点
优点:
1、保证数据的一致性,完整性,更可靠。
2、关联查询时,可以用到FK 的统计信息。
3、有主外键的数据库设计可以增加ER图的可读性。
缺点:
1、删队或更新关联数据时需要做检查,效率会很低。
2、手工调数据时,会存在主从表校验,会比较麻烦。
3、批量导入数据时,会存在外键校验,需要先关闭外键约束,导入完成再打开外键约束,操作比较麻烦。
SQLServer之FOREIGN KEY约束的更多相关文章
- SQLServer 中有五种约束, Primary Key 约束、 Foreign Key 约束、 Unique 约束、 Default 约束和 Check 约束
一直在关注软件设计方面,数据库方面就忽略了很多,最近在设计数据库时遇到了一些小麻烦,主要是数据库中约束和性能调优方面的应用,以前在学习 Sql Server 2000,还有后来的 Sql Server ...
- SQLServer之修改FOREIGN KEY约束
使用SSMS数据库管理工具修改FOREIGN KEY约束 1.连接数据库,选择数据表->右键点击->选择设计(或者展开键,选择要修改的外键,右键点击,选择修改,后面修改步骤相同). 2.在 ...
- sqlserver truncate清空表时候,无法删除 'B表',因为该表正由一个 FOREIGN KEY 约束引用。
外键: 查询:select object_name(a.parent_object_id) 'tables' from sys.foreign_keys a where a.referenced_ ...
- SQL Server 2008 R2——TRUNCATE TABLE 无法截断表 该表正由 FOREIGN KEY 约束引用
=================================版权声明================================= 版权声明:原创文章 禁止转载 请通过右侧公告中的“联系邮 ...
- 可能会导致循环或多重级联路径。请指定 ON DELETE NO ACTION 或 ON UPDATE NO ACTION,或修改其他 FOREIGN KEY 约束。
错误提示:可能会导致循环或多重级联路径.请指定 ON DELETE NO ACTION 或 ON UPDATE NO ACTION,或修改其他 FOREIGN KEY 约束. 原因:自表连接(同一张表 ...
- C# json反序列化 对象中嵌套数组 (转载) 可能会导致循环或多重级联路径。请指定 ON DELETE NO ACTION 或 ON UPDATE NO ACTION,或修改其他 FOREIGN KEY 约束。
C# json反序列化 对象中嵌套数组 (转载) 看图: 这里可以看到是二层嵌套!!使用C#如何实现?? 思路:使用list集合实现 → 建立类 → list集合 → 微软的 Newtonso ...
- SQL PRIMARY KEY 约束\SQL FOREIGN KEY 约束\SQL CHECK 约束
SQL PRIMARY KEY 约束 PRIMARY KEY 约束唯一标识数据库表中的每条记录. 主键必须包含唯一的值. 主键列不能包含 NULL 值. 每个表都应该有一个主键,并且每个表只能有一个主 ...
- 无法删除对象 '产品',因为该对象正由一个 FOREIGN KEY 约束引用。
在删除northwindcs表时,发生报错,消息 3726,级别 16,状态 1,第 2 行,无法删除对象 '产品',因为该对象正由一个 FOREIGN KEY 约束引用.此时判断是因为有其他表的外键 ...
- 删除提示 FOREIGN KEY 约束引用”
有时想删除某个表时,提示“无法删除对象 'Orders',因为该对象正由一个 FOREIGN KEY 约束引用”,原因很简单不要急躁,它被其它表的外键引用了,所以无法删除,在此只需先找到哪些表的外键引 ...
随机推荐
- http缓存与离线缓存
一.http协议实现缓存 1. 缓存头部 通用缓存.条件缓存.缓存控制三大类 头部名称 说明 请求/响应 通用缓存头部 控制客户端是否向服务器发送请求或者是服务端响应请求 cache-contro ...
- qcharts编译
编译环境vs2013+qt5.5.1+perl5 qchart源码在git上自己下载,或者在此下载,参考文档:Qt Charts 5.7.0 安装教程,这篇文章是使用mingw的方式编译qcharts ...
- CSRF攻击原理及防御
一.CSRF攻击原理 CSRF是什么呢?CSRF全名是Cross-site request forgery,是一种对网站的恶意利用,CSRF比XSS更具危险性.想要深入理解CSRF的攻击特性我们有必要 ...
- asp.net core系列 36 WebAPI 搭建详细示例
一.概述 HTTP不仅仅用于提供网页.HTTP也是构建公开服务和数据的API强大平台.HTTP简单灵活且无处不在.几乎任何你能想到的平台都有一个HTTP库,因此HTTP服务可以覆盖广泛的客户端,包括浏 ...
- C#版[击败98.85%的提交] - Leetcode717. 1比特与2比特字符 - 题解
版权声明: 本文为博主Bravo Yeung(知乎UserName同名)的原创文章,欲转载请先私信获博主允许,转载时请附上网址 http://blog.csdn.net/lzuacm. C#版 - L ...
- Solr 01 - 什么是Solr + Solr安装包目录结构说明
目录 1 Solr概述 1.1 Solr是什么 1.2 Solr与Lucene的区别 2 Solr文件说明 2.1 Solr的目录结构 2.2 其他常用概念说明 2.3 创建基础文件目录 2.4 so ...
- 带着新人学springboot的应用11(springboot+Dubbo+Zookeeper 上)
这次说个在大型项目比较常见的东西,就是分布式,分布式到底是个什么东西呢?概念太大,不好说,就像刚学javaee的人问你,什么是web啊,什么是spring啊等等,你可能觉得,这个东西我好像知道,但是用 ...
- Typora中的Markdown教程
Tutorial of markdown in Typora 工欲善其事,必先利其器 如上所说,这里给大家安利一款高BIG的利器Typora,这是一款文艺青年(装逼)必备的用于编写markdown的打 ...
- linux文本处理三剑客的学习
linux下有三个文本处理的神器.分别是grep,sed,awk.功能都是比较强大的. grep帮助: http://my-study-grep.readthedocs.io/en/latest/ s ...
- sql distinct详解以及优化
一.distinct简介 distinct这个关键字来过滤掉多余的重复记录只保留一条,但往往只用 它来返回不重复记录的条数,而不是用它来返回不重记录的所有值.其原因是distinct只有用二重循环查询 ...