在 SQL 中,当复合主键成为外键时应该如何被其它表引用
文章目录
当研究一个问题慢慢深入时,一个看起来简单的问题也暗藏玄机。在 SQL 中,主键成为外键这是一个很平常的问题,乍一看没啥值得注意的。但如果这个主键是一种复合主键,而另一个表又引用这个键作为它的复合主键,问题就会变得复杂。
这里为了便于说明,简单抽象出这样一个情景。数据库中有很多用户(User),每个用户有他的好友分组(Folder),每个分组下面有该用户的好友(Contact)。下面看看应该如何建表。
-
User 表建表示例代码如下:
CREATE TABLE User (id VARCHAR(64) NOT NULL,name VARCHAR(64) NOT NULL,# ...为了简化说明,此表省略其它字段...PRIMARY KEY (id) ); -
Folder 表建表示例代码如下:
CREATE TABLE Folder (id VARCHAR(64) NOT NULL,userId VARCHAR(64) NOT NULL,name VARCHAR(64) NOT NULL,# ...为了简化说明,此表省略其它字段...PRIMARY KEY (userId, id),# 因为上面的是复合主键,所以自动创建的是联合索引,而其它表的外键引用需要的是单个索引INDEX idIndex (id),FOREIGN KEY (userId) REFERENCES User (id) ); -
Contact 表建表示例代码如下:
CREATE TABLE Contact (id VARCHAR(64) NOT NULL,# 表示此联系人属于谁的好友userId VARCHAR(64) NOT NULL,# 表示此联系人对应 User 中的 idlinkedUserId VARCHAR(64) NOT NULL,folderId VARCHAR(64) NOT NULL,# ...为了简化说明,此表省略其它字段...PRIMARY KEY (userId, id),# 因为上面的是复合主键,所以自动创建的是联合索引,而其它表的外键引用需要的是单个索引INDEX idIndex (id),# 同一个用户,不能拥有两个相同 ID 的 ContactUNIQUE (userId, linkedUserId),# 当复合主键成为外键时,必须整个复合主键一起作为外键,不能只引用复合主键其中的某个属性FOREIGN KEY (userId) REFERENCES Folder (userId),FOREIGN KEY (folderId) REFERENCES Folder (id),FOREIGN KEY (linkedUserId) REFERENCES User (id) ); -
建表示意图如下:


笔者已经将正确的建表在上述给出了,但问题其实不简单。注意看,表 Contact 引用了两个表的外键:表 User 和 表 Folder。而很奇妙的是,表 User、Folder 和 Contact 都有一个形同“userId”的字段,而且,它们的这个字段的意义是相同的。那么,表 Contact 中的 userId 究竟是引用表 User 中的 id 呢?还是引用表 Folder 中的 userId 呢?还是随便选一个都可以呢?
答案是必须引用表 Folder 中的 userId,而不能引用表 User 中的 id。原因是,当复合主键成为外键时,必须整个复合主键一起作为外键,不能只引用复合主键其中的某个属性。
注意看,表 Contact 的属性 folderId 已经引用了表 Folder 的属性 id 了,但表 Folder 的主键是 (id,userId)。在这个情形下,表 Contact 必须也同时引用表 Folder 关于这个复合主键的其它属性。而正好表 Contact 有一个属性 userId,所以它必须引用表 Folder 中的 userId。
可是,表 Contact 不是也和表 User 有引用啊,为什么没有受到表 User 的约束呢?因为 User 的主键不是复合主键,而且表 Contact 已经通过属性 linkedUserId 引用了表 User 的主键 id,因此不需要强制引用 User 的其它属性。
当然,这只是 SQL 上的逻辑,而 SQL 只是一套标准,各个数据库的服务提供商对 SQL 的支持和实现因人而异。在 MySQL 中,如果建表时错误地将上述表 Contact 中的 userId 引用了表 User 中的 id,MySQL 并不会抛出错误,因为 MySQL 关于这方面不太严谨。但如果使用的是 SQLite,SQLite 将会在建表时就抛出错误。但不管各厂商的支持如何,将应该保证数据库建表的逻辑是正确的。
相关文章:
在 SQL 中,当复合主键成为外键时应该如何被其它表引用
文章目录 当研究一个问题慢慢深入时,一个看起来简单的问题也暗藏玄机。在 SQL 中,主键成为外键这是一个很平常的问题,乍一看没啥值得注意的。但如果这个主键是一种复合主键,而另一个表又引用这个键作为它的复合主键,问…...
Ps:通过显示大小了解图像的打印尺寸
在 Photoshop 中,如果想了解文档窗口中的图像打印出来之后的实质大小,只要知道两个数值即可。 第一个数值是图像分辨率(也称“文档分辨率”)的大小,可在Ps菜单:图像/图像大小 Image Size对话框中查询或设置…...
Linux - 驱动开发 - watchdog - SMP机制下多核确活
说明 理论上:不管IC是单核还是多核,只要watchdog有被循环feed,就不会触发超时重启,因此watchdog在SMP机制下的多核环境显得比较宽松,只要任意核存活(喂狗)就不会重启设备。 实际情况 有客户反…...
概念解析 | LoRA:低秩矩阵分解在神经网络微调中的魔力
注1:本文系“概念解析”系列之一,致力于简洁清晰地解释、辨析复杂而专业的概念。本次辨析的概念是:基于低秩矩阵分解的神经网络微调方法LoRA LoRA:低秩矩阵分解在神经网络微调中的魔力 Low-Rank Adaptation of Large Language Models LoRA由如下论文提出,详细信息请参见论文原…...
量子计算和量子通信技术:引领潜力无限的未来
近年来,随着量子计算和量子通信技术的迅速发展,它们在各个领域的广泛应用前景引起了人们的极大兴趣。本文将深入探讨量子计算和量子通信技术的普遍应用,以及它们预示的未来,同时提出业内人士需要注意的事项。 介绍:量子…...
nodejs+vue+python+PHP+微信小程序-安卓- 电影在线订票系统的设计与实现-计算机毕业设计推荐
目 录 摘 要 I ABSTRACT II 目 录 II 第1章 绪论 1 1.1背景及意义 1 1.2 国内外研究概况 1 1.3 研究的内容 1 第2章 相关技术 3 2.1 nodejs简介 4 2.2 express框架介绍 6 2.4 MySQL数据库 4 第3章 系统分析 5 3.1 需求分析 5 3.2 系统可行性分析 5 3.2.1技术可行性:…...
LightDB23.4支持mysql aes_encrypt/aes_decrypt/hex/unhex函数
背景介绍 为了兼容mysql数据库的功能,在LightDB23.4版本上支持hex/unhex/aes_encrypt/aes_decrypt函数。 函数原型如下: hex(data bytea) returns textunhex(data varchar) returns byteaaes_encrypt(data bytea, key bytea) returns byteaaes_encryp…...
uniapp——项目day04
购物车页面——商品列表区域 渲染购物车商品列表的标题区域 1. 定义如下的 UI 结构: 2.美化样式 渲染商品列表区域的基本结构 1. 通过 mapState 辅助函数,将 Store 中的 cart 数组映射到当前页面中使用: import badgeMix from /mixins/tab…...
7-爬虫-中间件和下载中间件(加代理,加请求头,加cookie)、scrapy集成selenium、源码去重规则(布隆过滤器)、分布式爬虫
0 持久化(pipelines.py)使用步骤 1 爬虫中间件和下载中间件 1.1 爬虫中间件(一般不用) 1.2 下载中间件(代理,加请求头,加cookie) 1.2.1 加请求头(加到请求对象中) 1.2.2 加cookie 1.2.3 加代理 2 scrapy集成selenium 3 源码去重…...
创建自己的nas服务,从远端拉取所需文件
一、前言 创建一个nas文件存储,然后需要的时候随时从远端或者其他终端拉取所需文件是不是一件很帅气的工作。 二、准备工作 一台服务器(云的更好),没了。 首先安装docker和docker-compose 此处省略docker的安装(改天更新)&…...
智慧化城市内涝的预警,万宾科技内涝积水监测仪
随着城市化进程的加速,伴随的是城市内涝问题日益凸显。频繁的暴雨和积水给市民的生活带来了诸多不便,也给城市的基础设施带来了巨大压力。如何解决这一问题,成为智慧城市建设的重要课题和政府管理的工作主题,只要内涝问题得到缓解…...
7-18 调用一个函数
分数 2 作者 Yiping 单位 广东东软学院 现有如下程序,请将注释后带??的代码补充完整: import mathdef normalize(normal):x normal[0]y normal[1]z normal[2]s math.sqrt(x**2 y**2 z**2)x / sy / sz / sreturn (x, y, z)if __name__ __mai…...
VB.net TCP服务端监听端口接收客户端RFID网络读卡器上传的读卡数据
本 示例使用设备介绍:WIFI/TCP/UDP/HTTP协议RFID液显网络读卡器可二次开发语音播报POE-淘宝网 (taobao.com) Imports System.Threading Imports System.Net Imports System.Net.Sockets Public Class Form1Dim ListenSocket As SocketDim Dict As New Dictionary(Of…...
Springboot 集成 MongoDB
在SpringBoot项目中集成MongoDB后的一些基本操作。 文章目录 前言一、pandas是什么?二、使用步骤 1.引入库2.读入数据总结 前言 本文介绍的内容是Springboot如何集成MongoDB,以及对MongoDB进行基本的增加、查询数据的操作。 提示:以下是本篇…...
AM@定积分的定义求某些类型的极限
文章目录 定积分定义求极限步骤例 定积分表示为极限 定积分定义求极限 容易从定积分的定义: ∫ a b f ( x ) d x \int_{a}^{b}f(x)\mathrm{d}x ∫abf(x)dx lim λ → 0 ∑ i 1 n f ( ξ i ) Δ x i \lim\limits_{\lambda\to{0}}\sum_{i1}^{n}f{(\xi_{i})}\Delta{x_i} λ→…...
Perl爬虫程序的框架
Perl爬虫程序的框架,这个框架可以用来爬取任何网页的内容。 perl #!/usr/bin/perl use strict; use warnings; use LWP::UserAgent; use HTML::TreeBuilder; # 创建LWP::UserAgent对象 my $ua LWP::UserAgent->new; # 设置代理信息 $ua->proxy(http, ); …...
15. 机器学习——聚类
机器学习面试题汇总与解析——聚类 本章讲解知识点 什么是聚类K-means 聚类算法均值偏移聚类算法DBSCAN 聚类算法高斯混合模型(GMM)的期望最大化(EM)聚类层次聚类算法本专栏适合于Python已经入门的学生或人士,有一定的编程基础。 本专栏适合于算法工程师、机器学习、图像…...
华为笔记本电脑原装win10/win11系统恢复安装教程方法
华为电脑matebook 14原装Win11系统带F10智能还原 安装恢复教程: 1.安装方法有两种,一种是用PE安装,一种是华为工厂包安装(安装完成自带F10智能还原) 若没有原装系统文件,请在这里获取:https:…...
计算机毕业设计 基于SpringBoot的养老院管理系统的设计与实现 Java实战项目 附源码+文档+视频讲解
博主介绍:✌从事软件开发10年之余,专注于Java技术领域、Python人工智能及数据挖掘、小程序项目开发和Android项目开发等。CSDN、掘金、华为云、InfoQ、阿里云等平台优质作者✌ 🍅文末获取源码联系🍅 👇🏻 精…...
Python数据容器(序列操作)
序列 1.什么是序列 序列是指:内容连续、有序。可以使用下标索引的一类数据容器 列表、元组、字符串。均可以视为序列 2.序列的常用操作 - 切片 语法:序列[起始下标:结束下标:步长]起始下标表示从何处开始,可以留空,留空视作从…...
RocketMQ延迟消息机制
两种延迟消息 RocketMQ中提供了两种延迟消息机制 指定固定的延迟级别 通过在Message中设定一个MessageDelayLevel参数,对应18个预设的延迟级别指定时间点的延迟级别 通过在Message中设定一个DeliverTimeMS指定一个Long类型表示的具体时间点。到了时间点后…...
【JavaEE】-- HTTP
1. HTTP是什么? HTTP(全称为"超文本传输协议")是一种应用非常广泛的应用层协议,HTTP是基于TCP协议的一种应用层协议。 应用层协议:是计算机网络协议栈中最高层的协议,它定义了运行在不同主机上…...
《Qt C++ 与 OpenCV:解锁视频播放程序设计的奥秘》
引言:探索视频播放程序设计之旅 在当今数字化时代,多媒体应用已渗透到我们生活的方方面面,从日常的视频娱乐到专业的视频监控、视频会议系统,视频播放程序作为多媒体应用的核心组成部分,扮演着至关重要的角色。无论是在个人电脑、移动设备还是智能电视等平台上,用户都期望…...
FastAPI 教程:从入门到实践
FastAPI 是一个现代、快速(高性能)的 Web 框架,用于构建 API,支持 Python 3.6。它基于标准 Python 类型提示,易于学习且功能强大。以下是一个完整的 FastAPI 入门教程,涵盖从环境搭建到创建并运行一个简单的…...
关于iview组件中使用 table , 绑定序号分页后序号从1开始的解决方案
问题描述:iview使用table 中type: "index",分页之后 ,索引还是从1开始,试过绑定后台返回数据的id, 这种方法可行,就是后台返回数据的每个页面id都不完全是按照从1开始的升序,因此百度了下,找到了…...
Cilium动手实验室: 精通之旅---20.Isovalent Enterprise for Cilium: Zero Trust Visibility
Cilium动手实验室: 精通之旅---20.Isovalent Enterprise for Cilium: Zero Trust Visibility 1. 实验室环境1.1 实验室环境1.2 小测试 2. The Endor System2.1 部署应用2.2 检查现有策略 3. Cilium 策略实体3.1 创建 allow-all 网络策略3.2 在 Hubble CLI 中验证网络策略源3.3 …...
【ROS】Nav2源码之nav2_behavior_tree-行为树节点列表
1、行为树节点分类 在 Nav2(Navigation2)的行为树框架中,行为树节点插件按照功能分为 Action(动作节点)、Condition(条件节点)、Control(控制节点) 和 Decorator(装饰节点) 四类。 1.1 动作节点 Action 执行具体的机器人操作或任务,直接与硬件、传感器或外部系统…...
unix/linux,sudo,其发展历程详细时间线、由来、历史背景
sudo 的诞生和演化,本身就是一部 Unix/Linux 系统管理哲学变迁的微缩史。来,让我们拨开时间的迷雾,一同探寻 sudo 那波澜壮阔(也颇为实用主义)的发展历程。 历史背景:su的时代与困境 ( 20 世纪 70 年代 - 80 年代初) 在 sudo 出现之前,Unix 系统管理员和需要特权操作的…...
MySQL中【正则表达式】用法
MySQL 中正则表达式通过 REGEXP 或 RLIKE 操作符实现(两者等价),用于在 WHERE 子句中进行复杂的字符串模式匹配。以下是核心用法和示例: 一、基础语法 SELECT column_name FROM table_name WHERE column_name REGEXP pattern; …...
NXP S32K146 T-Box 携手 SD NAND(贴片式TF卡):驱动汽车智能革新的黄金组合
在汽车智能化的汹涌浪潮中,车辆不再仅仅是传统的交通工具,而是逐步演变为高度智能的移动终端。这一转变的核心支撑,来自于车内关键技术的深度融合与协同创新。车载远程信息处理盒(T-Box)方案:NXP S32K146 与…...
