【SQL Server】外键约束

外键约束

  • 前序
  • 外键约束

前序

在很多场景里面,都会用到外键来关联两张表或两张以上的表之间主从关系,从而来快捷地通过外键字段来查询数据之间的联系。

其实外键在我的概念中还是比较模糊的,没有真正地使用过。大多数情况下,我都是使用单表来处理。

场景:在数字孪生的项目中,动环设备、网管设备、安防设备它们的设备信息都来源于设备资产,设备资产会记录所有的设备信息
,在这三个模块里面,除了常规的设备信息外,每个模块里面的设备资产也对应了不同的信息,例如属于动环设备的设备资产记录了每个设备的信号,网管设备的设备资产记录了每个设备的线路,安防设备的设备资产记录了每个设备的监控,因此依靠这设备信息衍生出了很多的其他信息,且不同功能模块下,表的结构也不一样,当一开始将表都设计成单表时,问题就出来了!

问题: 因为表都设计成了单表,彼此之间没有任何连接,导致删除了设备信息表里面一条设备信息,而其他表对应的这条设备的其他信息没有被删除,也没有阻止删除设备信息表的这条设备信息。

解决:为了解决这个问题,就需要引入外键约束的概念,这包括了一对多或一对一的概念,一对多就意味着主键对应着一张表的多个外键,一对一就意味着主键只能对应着一张表的一个外键。

外键约束

为了说明外键约束的特性,先建两张表:asset_recordsignal_lab

create table asset_record
(id nvarchar(36) not nullconstraint PK__asset_re__3213E83F986BB1C9primary key,sn nvarchar(32),name nvarchar(32),asset_type nvarchar(36),asset_status nvarchar(32),asset_brand nvarchar(36),brand_model nvarchar(36),responsible nvarchar(32),create_by nvarchar(50),create_time datetime,update_by nvarchar(50),update_time datetime,remark nvarchar(32),price float,asset_tag nvarchar(32),putaway_time datetime,buy_time datetime,takeoff_time datetime,asset_room nvarchar(36),area_id nvarchar(32)
)
go

上面创建了一张 asset_record 表,它用来记录设备信息,其中主键为 id 。

create table signal_bind
(id nvarchar(36) not nullconstraint PK__signal_b__3213E83F122745EBprimary key,asset_record nvarchar(36),asset_type nvarchar(36),signal_code nvarchar(36),signal_id nvarchar(36),signal_type nvarchar(3),name nvarchar(50),alarm_level nvarchar(3),threshold nvarchar(10),value_desc nvarchar(100)
)
go

上面创建了一张 signal_bind 表,它用来记录设备的信号,其中主键为 id,与 asset_record 的关系为一对多。

表中并没有设置外键,就是两张及其普通的单表结构。

现在为其两张表分别插入两条数据。

INSERT INTO [dbo].[asset_record] ([id], [sn], [name], [asset_type], [asset_status], [asset_brand], [brand_model], [responsible], [create_by], [create_time], [update_by], [update_time], [remark], [price], [asset_tag], [putaway_time], [buy_time], [takeoff_time], [asset_room], [area_id]) VALUES ('170100001000004', NULL, N'温湿度', N'1689559538522439684', N'2', N'1689877026292453378', N'4028a98189e33ed80189e340b9d60006', NULL, N'admin', '2023-09-13 13:48:52.073', NULL, NULL, N'', NULL, N'1', '2023-09-13 13:48:51.383', '2023-09-13 13:48:51.383', NULL, N'4028a98189f17d860189f17d860c0000', NULL);
INSERT INTO [dbo].[asset_record] ([id], [sn], [name], [asset_type], [asset_status], [asset_brand], [brand_model], [responsible], [create_by], [create_time], [update_by], [update_time], [remark], [price], [asset_tag], [putaway_time], [buy_time], [takeoff_time], [asset_room], [area_id]) VALUES ('080300000000006', NULL, N'UPS', N'1689559538522439683', N'2', N'1689877026032406530', N'4028a98189e346420189e34642120000', NULL, N'admin', '2023-09-13 13:48:51.507', NULL, NULL, N'', NULL, N'1', '2023-09-13 13:48:51.383', '2023-09-13 13:48:51.383', NULL, N'4028a98189f17d860189f17d860c0000', NULL);

asset_record 插入两个设备信息:温湿度、UPS。

INSERT INTO [dbo].[signal_bind] ([id], [asset_record], [asset_type], [signal_code], [signal_id], [signal_type], [name], [alarm_level], [threshold], [value_desc]) VALUES ('1693536753555603458', N'170100001000004', N'1689559538522439684', N'', N'017100001', N'0', N'温度1通信状态', N'2', N'1', N'0&正常;1&告警');
INSERT INTO [dbo].[signal_bind] ([id], [asset_record], [asset_type], [signal_code], [signal_id], [signal_type], [name], [alarm_level], [threshold], [value_desc]) VALUES ('1693536757124956161', N'080300000000006', N'1689559538522439683', N'', N'07610000E', N'0', N'UPS设备通信状态告警', N'2', N'1', N'0&正常;1&告警');

signal_bind 插入两个设备的一条信号:温湿度【温度1通信状态】、UPS【UPS设备通信状态告警】。

这个时候删除 asset_record 里面的一条温湿度设备信息。

DELETE FROM asset_record WHERE id = '170100001000004';

按理来说,既然设备都不存在了,那么设备的信号存储在表里面是没有意义的,因此还需要删除对应的信号数据。

DELETE FROM signal_bind WHERE id = '170100001000004';

这样表面是没有问题的,但是如果忘记删除设备信号,那么设备信息还是可以被删除,这就导致设备信号表里面存在脏数据,脏数据多了就会影响查询效率。

因此需要用外键来约束。

ALTER TABLE signal_bind
ADD CONSTRAINT FK_asset_record
FOREIGN KEY (asset_record)
REFERENCES asset_record (id);

只需要在修改 signal_bind 表的 asset_record 字段为外键,且与 asset_record 的主键关联就可以啦,其中你需要注意如果 signal_bind 表的外键存在,而 asset_record 表里面没有对应的主键数据,那么创建外键就会失败,并且报错 ALTER TABLE 语句与 FOREIGN KEY 约束"FK_asset_record"冲突。 巴拉巴拉之类的。

SELECT sb.asset_record
FROM signal_bind AS sb
LEFT JOIN asset_record AS ar ON sb.asset_record = ar.id
WHERE ar.id IS NULL;

通过联合查询来判断 signal_bind 表里面哪些外键在 asset_record 表里面没有对应的主键。

设置好外键后,再次直接删除设备信息表里面UPS的数据就会报错(DELETE 语句与 REFERENCE 约束"FK_asset_record"冲突。),要先删除设备信息对应的设备信息数据,才能删除设备信息。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/90795.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Pandas 2.1中的新改进和新功能

大家好,Pandas 2.1于2023年8月30日发布,跟随本文一起看看这个版本引入了哪些新内容,以及它如何帮助用户改进Pandas的工作负载,包含了一系列改进和一组新的弃用功能。 Pandas 2.1在Pandas 2.0中引入的PyArrow集成基础上进行了大量…

【RabbitMQ实战】07 3分钟部署一个RabbitMQ集群

一、集群的安装部署 我们还是利用docker来安装RabbitMQ集群。3分钟安装一个集群,开始。 前提条件,docker安装了docker-compose。如果没安装的话,参考这里 docker-compose文件参考bitnami官网:https://github.com/bitnami/contai…

巧用@Conditional注解根据配置文件注入不同的bean对象

项目中使用了mq,kafka两种消息队列进行发送数据,为了避免硬编码,在项目中通过不同的配置文件自动识别具体消息队列策略。这里整理两种实施方案,仅供参考! 方案一:创建一个工具类,然后根据配置文…

Swift 周报 第三十八期

文章目录 前言新闻和社区苹果自研调制解调器芯片受挫:速度太慢容易过热,落后高通 3 年App Store 现已接受适用于最新版操作系统的 App 和游戏提交 提案通过的提案正在审查的提案驳回的提案 Swift论坛推荐博文话题讨论关于我们 前言 本期是 Swift 编辑组…

弹性资源组件elastic-resource设计(一)-架构

简介 弹性资源组件提供动态资源能力,是分布式系统关键基础设施,分布式datax,分布式索引,事件引擎都需要集群和资源的弹性资源能力,提高伸缩性和作业处理能力。 本文介绍弹性资源组件的设计,包括架构设计和详细设计,指导开发人员代码开发 关键词 作业管理器/资源管理器/…

duilib 之 各种消息框

本文主要介绍,使用同一个布局文件,生成不同样式消息框是如何实现的。 目录 一、消息框 1、不同消息框展示 2、实现方式 1)、布局, 2)、扩展 MsgB

简易实现通讯录(2.0)

这篇文章是在上期实现的通讯录基础上,增加了自动增容的功能,也解决了一开始通讯录自动开辟一个空间,可能会浪费空间,或者是信息过多无法增容的痛点,由于我们使用的是malloc这类函数来开辟空间,我们也需要来…

vue 实现弹出菜单,解决鼠标点击其他区域的检测问题

弹出菜单应该具有的功能,当鼠标点击其他区域时,则关闭该菜单。 问题来了,怎么检测鼠标点击了其他区域而不是当前菜单? 百度“JS检测区域外的点击事件”,会发现有很多方法,有递归检测父元素,有遍…

大语言模型LLM知多少?

你知道哪些流行的大语言模型?你都体验过哪写? GPT-4,Llamma2, T5, BERT 还是 BART? 1.GPT-4 1.1.GPT-4 模型介绍 GPT-4(Generative Pre-trained Transformer 4)是由OpenAI开发的一种大型语言模型。GPT-4是前作GPT系列模型的进一步改进,旨在提高语言理解和生成的能力,…

Centos 7安装pm2 , 操作等常用命令

Centos 7安装pm2 1、首先需要安装node,node安装教程前一篇已经说了,是安装pm2 [rootlocalhost ~]# npm install -g pm2 2、pm2 命令参考 复制代码 2.1 启动进程/应用 pm2 start bin/www 或 pm2 start app.js 2.2 重命名进程/应用 pm2 start app.js -…

Blender导出FBX给UE5

最近在学习UE5的资源导入,总结如下: 建模使用Blender,UE5版本是5.3 1.纯静态模型导入UE5 Blender FBX导出设置保持默认即可, UE5把导入设置里Miscellaneous下Force Front XAxis和Convert Scene Unit勾选即可 2.带骨骼动画的模型…

ios项目安装hermes-engine太慢问题

问题说明 ios工程,在使用"pod install"安装依赖的时候,由于超时总是报错 $ pod install ... Installing hermes-engine (0.71.11)[!] Error installing hermes-engine [!] /usr/bin/curl -f -L -o /var/folders/4c/slcchpy55s53ysmz_1_q_gzw…

react项目优化

随着项目体积增大,打包的文件体积会越来越大,需要优化,原因无非就是引入的第三方插件比较大导致,下面我们先介绍如何分析各个文件占用体积的大小。 1.webpack-bundle-analyzer插件 如果是webpack作为打包工具的项目可以使用&…

MySQL 连接查询(多表查询 二)

基本介绍 作用:连接查询(Join)操作,用于联结多个表以获取更全面和准确的数据 基本分类: 内连接:相当于查询A、B交集部分数据(去掉迪卡尔积无效组合)外连接: 左外连接&…

Docker方式创建MySQL8的MGR集群

目录 一、MGR简述二、安装环境及要求2.1 系统版本2.2 网络要求 三、安装步骤3.1 创建容器3.2 创建用户3.3 安装插件3. 4 启动集群3.5 加入集群 四、查看集群查看 MGR 组成员列表查看 MGR 组成员拓扑信息 五、其他说明集群配置要求集群配置限制集群相关变量和状态 一、MGR简述 …

lwIP 开发指南(下)

目录 NETCONN 编程接口简介netbuf 数据缓冲区netconn 连接结构netconn 编程API 函数 NETCONN 编程接口UDP 实验NETCONN 实现UDPNETCONN 接口的UDP 实验硬件设计软件设计下载验证 NETCONN 接口编程TCP 客户端实验NETCONN 实现TCP 客户端连接步骤NETCONN 接口的TCPClient 实验硬件…

Python对于有空值的数据,按列进行求平均

三列数据dataframe,相对三列数据求平均值得到新的列,但是每一列都有空值,我们在求平均值的时候,如果都是空值则还是空值,如果不全为空,则对不为空的列进行求平均。 import pandas as pd import numpy as n…

freertos中函数调用和启动第一个任务(栈相关!!!!!!)

本内容仅就一些较难理解的点讲解,请结合其它文章实用 在函数调用时,m3的处理器使用r0-r3共四个寄存器传参,其余的使用栈传参。 但是,如果传入的参数是全局变量,则不需传参,因为全局变量在函数内部是可见的…

【算法练习Day8】 kmp算法找出字符串中第一个匹配项的下标反转字符串中的单词重复的子字符串

、​ ​📝个人主页:Sherry的成长之路 🏠学习社区:Sherry的成长之路(个人社区) 📖专栏链接:练题 🎯长路漫漫浩浩,万事皆有期待 文章目录 kmp算法找出字符串中第…

2023版 STM32实战5 基本定时器中断

基本定时器简介与特性 -1-时钟可分频 -2-计数模式只可以选择累加 -3-只可以用来定时(含中断) 查看时钟源 如图定时器7的时钟最大为72MHZ 定时时间的计算 通用定时器的时间计算公式为 Tout ((arr1)(psc1&…