主键、候选键与外键的关系

主键、候选键与外键的关系

主键、候选键与外键的关系?
一个表的外键只能是其他表的主键吗?还是其他表的候选键也可以?
比如:员工表的字段中包含员工ID和员工账号,其中员工ID为主键,员工账号为普通候选键,作为其他表的外键时,应该使用哪个字段呢?

外键(Foreign Key)、主键(Primary Key)和候选键(Candidate Key)在关系数据库中有着密切的关系:

  1. 主键(Primary Key):在一个表中,主键是一个或一组字段的集合,这些字段的值能够唯一地标识表中的每一行记录。每个表只能有一个主键,并且其值必须是唯一的,不能为空。

  2. 候选键(Candidate Key):候选键也是一个或一组字段,它们的组合也能唯一地标识表中的每条记录,就像主键一样。但一个表可以有多个候选键。在选择主键时,从候选键中选出一个作为主键,其他的候选键则保持为可唯一标识记录的备用键。

  3. 外键(Foreign Key):外键是在一个表中引用另一个表的主键或候选键的字段。它用于建立两个表之间的关联关系,确保参照完整性。外键并不一定是另一个表的主键,它可以是另一个表的任何候选键,只要这个候选键在被引用表中保证了唯一性。

关于员工表的例子,假设员工表中有“员工ID”和“员工账号”两个字段,如果这两个字段都是候选键,即它们都能唯一确定一个员工,则在设计其他表需要引用员工信息时,选择哪个作为外键取决于业务逻辑和数据模型设计的需求:

  • 如果“员工ID”是更稳定、不变或者更具识别性的标识符(比如系统内部主要依据ID进行操作),那么通常会选择“员工ID”作为外键。
  • 如果“员工账号”在某些业务场景下也是独一无二的,并且同样适合用来与其他表关联(例如账号可能更容易被用户记忆或查找),那么也可以用作外键。

所以,在实际应用中,外键既可以是另一个表的主键,也可以是那个表的一个候选键,关键在于所选字段能否有效、稳定地标识出相关的记录。

不过,在实践中,为了保持数据库设计的一致性及易于理解和维护,通常会优先选用主键作为外键,因为主键的设计目的就是为了提供稳定的、唯一的参照点。

外键:员工ID与员工账号

当不同的系统中,有独立的数据库(A系统无法访问B系统的数据库);A系统中数据经过处理后存储在B系统中,此时,需要进行数据的冗余存储,也就是把A系统中的某些数据,在B系统中再存一份。
在此情况下,B系统在表中存储的外键,来自于A系统的表,比如员工表来自A系统且数据要存在B系统,此时B系统的外键使用员工账号是不是比存员工ID更合适?

在决定B系统中存储外键时,选择员工ID还是员工账号作为外键,主要取决于以下因素:

  1. 稳定性:员工ID通常是由系统自动生成或分配的,并且一旦分配给某个员工后一般不会更改。这使得员工ID成为更稳定、持久的标识符。

  2. 唯一性与不变性:员工账号理论上也应该具有唯一性,但如果账号可以被修改(例如,员工更换了用户名或者由于安全原因重置了账号),那么使用账号作为外键可能会导致数据完整性问题,因为外键关系会因账号变更而断裂。

  3. 业务需求和关联紧密度:如果员工账号是业务操作中更加关键的识别信息,比如在跨系统交互时,外部系统更多依赖于账号进行对接,则使用账号作为外键可能更为合适。

  4. 性能与查询效率:一般来说,内部系统生成的ID通常是整数类型,对于数据库索引和查询效率更有优势。而员工账号如果是字符串类型并且长度不固定,可能对数据库性能产生一定影响。

  5. 隐私和安全性:从安全角度考虑,员工ID可能是内部标识符,对外暴露风险较小;而员工账号可能涉及用户隐私,作为外键存储需要谨慎评估安全风险。

综合上述因素,在实际设计中,如果员工账号具备良好的唯一性和稳定性,并且在跨系统交互中起着核心作用,同时不存在隐私泄露或其他安全问题,则可以考虑将员工账号用作外键。然而,大部分情况下,由于员工ID具有更高的稳定性和更低的风险,往往会选择员工ID作为在不同系统间传递和存储的外键值。同时,即使存入账号信息以支持特定业务流程,也应当保证通过员工ID来维护主从表之间的参照完整性。

员工表的设计方案

设计员工表,应该包含哪些字段?应该员工ID和员工账号分成两个字段吗?

设计员工表时,应考虑以下字段以满足基本的员工信息管理需求:

  1. employee_id(员工ID):通常为整数类型,作为主键,并且通常是自增的,用于唯一标识每个员工。

  2. employee_account(员工账号/工号):如果公司有独立的工号体系,则可设立一个字段存储员工工号。这个字段可能是字符串类型,也可能具有唯一性要求,取决于业务需要。

  3. name(姓名)

  4. email(电子邮件)

  5. phone_number(电话号码)

  6. address(地址)

  7. date_of_birth(出生日期)

  8. gender(性别)

  9. nationality(国籍)

  10. identification_number(身份证号、护照号或其他身份识别码)

  11. department_id(部门ID):外键关联到部门表。

  12. position_title(职位名称)

  13. hire_date(入职日期)

  14. employment_status(雇佣状态:如全职、兼职、试用期、离职等)

  15. salarybasic_salary(基本薪资)

  16. bonus(奖金)

  17. allowances(津贴)

  18. work_hoursschedule(工作时间安排)

至于员工ID和员工账号是否应该分成两个字段,主要取决于公司的内部管理制度和信息系统的需求。如果员工账号在业务流程中扮演着独特且重要的角色,比如登录系统、权限分配等,并且与员工ID不同,那么将它们分开是有意义的。否则,如果员工账号与员工ID没有本质区别,或者直接使用员工ID进行所有操作,就不必额外设立员工账号字段。在设计数据库时务必保证数据的一致性和完整性,同时兼顾未来扩展性和查询性能。

总结

在跨系统存储外键时,比如员工表,应该将员工ID和员工账号都存储下来;
员工ID作为外键,维护主从表之间的参照完整性;
员工账号作为数据冗余,为业务操作提供关键的识别信息,便于数据的查询。

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

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

相关文章

【状态管理一】概览:状态使用、状态分类、状态具体使用

文章目录 一. 状态使用概览二. 状态的数据类型1. 算子层面2. 接口层面2.1. UML与所有状态类型介绍2.2. 内部状态:InternalKvState 将知识与实际的应用场景、设计背景关联起来,这是学以致用、刨根问底知识的一种直接方式。 本文介绍 状态数据管理&#x…

pytorch入门第一天

今天作为入门pytorch的第一天。打算记录每天学习pytorch的一些理解和笔记,以用来后面回顾。当然如果能帮到和我一样的初学者,那也是不胜荣幸。作为一名初学者,难免有些地方会现错误,欢迎各位大佬指出 预备知识 这里主要介绍pyto…

【数据结构】堆(创建,调整,插入,删除,运用)

目录 堆的概念: 堆的性质: 堆的存储方式: 堆的创建 : 堆的调整: 向下调整: 向上调整: 堆的创建: 建堆的时间复杂度: 向下调整: 向上调整&#xff…

2023年06月CCF-GESP编程能力等级认证C++编程二级真题解析

一、单选题(每题2分,共30分) 第1题 高级语言编写的程序需要经过以下()操作,可以生成在计算机上运行的可执行代码。 A. 编辑 B. 保存 C. 调试 D. 编译 答案:D 第2题 能够实现下面流程图功能的伪代码是( )。 A. if 条件判断 then 语句块 B. if 条件判断 then 什么…

vue项目打包部署到flask等后端服务里面,实现前后端不分离部署,解决空白页面和刷新页面not fount问题

1. 编译模式一定要设置为esnext,否则会报错: Strict MIME type checking is enforced for module scripts per HTML spec.Expected a JavaScript module script but the server responded with a MIME type of "text/plain". 具体解释可以看vi…

Leetcode 第 382 场周赛题解

Leetcode 第 382 场周赛题解 Leetcode 第 382 场周赛题解题目1:3019. 按键变更的次数思路代码复杂度分析 题目2:3020. 子集中元素的最大数量思路代码复杂度分析 题目3:3021. Alice 和 Bob 玩鲜花游戏思路代码复杂度分析 题目4:302…

停车场|基于Springboot的停车场管理系统设计与实现(源码+数据库+文档)

停车场管理系统目录 目录 基于Springboot的停车场管理系统设计与实现 一、前言 二、系统功能设计 三、系统实现 1、管理员功能实现 (1)车位管理 (2)车位预订管理 (3)公告管理 (4&#…

Vulnhub-Empire靶机-详细打靶流程

渗透思路 1.确认靶机IP地址2.端口服务扫描3.敏感目录扫描4.ffuf命令在这个目录下,继续使用ffuf工具扫描 5.ssh私钥爆破1.将私钥写进sh.txt中2.将私钥转换为可以被john爆破的形式3.通过John爆破 6.ssh私钥登陆7.icex64提权8.arsene提权 1.确认靶机IP地址 ┌──(roo…

浏览器F12调试

系列文章目录 提示:这里可以添加系列文章的所有文章的目录,目录需要自己手动添加 例如:第一章 Python 机器学习入门之pandas的使用 提示:写完文章后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目…

【Kotlin】Kotlin基本数据类型

1 变量声明 var a : Int // 声明整数类型变量 var b : Int 1 // 声明整数类型变量, 同时赋初值为1 var c 1 // 声明整数类型变量, 同时赋初值为1 val d 1 // 声明整数类型常量, 值为1(后面不能改变d的值) 变量命名规范如下。 变量名可以由字母、数字、下划线(_…

Tomcat之虚拟主机

1.创建存放网页的目录 mkdir -p /web/{a,b} 2.添加jsp文件 vi /web/a/index.jsp <% page language"java" import"java.util.*" pageEncoding"UTF-8"%> <html> <head><title>JSP a page</title> </head> …

Rust 初体验3

“开胃”代码 fn main() {let (a, mut b): (bool,bool) (true, false);// a true,不可变; b false&#xff0c;可变println!("a {:?}, b {:?}", a, b);b true;assert_eq!(a, b); }Rust语法和C语言有很大不同&#xff0c;特别是在变量声明、打印输出和错误处…

PAT-Apat甲级题1009(python和c++实现)

PTA | 1009 Product of Polynomials 1009 Product of Polynomials 作者 CHEN, Yue 单位 浙江大学 This time, you are supposed to find AB where A and B are two polynomials. Input Specification: Each input file contains one test case. Each case occupies 2 lin…

dockerfile 详细讲解

当编写 Dockerfile 时&#xff0c;你需要考虑你的应用程序所需的环境和依赖项&#xff0c;并将其描述为一系列指令。下面是一个简单的示例&#xff0c;演示如何编写一个用于部署基于 Node.js 的网站的 Dockerfile&#xff1a; Dockerfile # 使用官方 Node.js 镜像作为基础镜像…

力扣:47. 全排列 II

回溯解法思路&#xff1a; 1.先写一个集合来接收全部的全排列&#xff0c;再写一个集合来接受单个的全排列。在声明一个int【】数组来用于去重用的标记nums数组中什么元素用了的标记。同时排列一下nums数组方便去除重复的全排列。 2.调用回溯函数&#xff0c;终止条件为li2集…

Matplotlib绘制炫酷散点图:从二维到三维,再到散点图矩阵的完整指南与实战【第58篇—python:Matplotlib绘制炫酷散点图】

文章目录 Matplotlib绘制炫酷散点图&#xff1a;二维、三维和散点图矩阵的参数说明与实战引言二维散点图三维散点图散点图矩阵二维散点图进阶&#xff1a;辅助线、注释和子图三维散点图进阶&#xff1a;动画效果和交互性散点图矩阵进阶&#xff1a;调整样式和添加密度图总结与展…

低代码平台痛点

1、数据查询性能一直是低代码平台的痛点 原来的平台&#xff0c;数据查询时&#xff0c;直接查数据库&#xff0c;现在低代码平台需要先经过元数据解析后&#xff0c;才知道如何查数据库&#xff0c;因此增加了查询的耗时&#xff0c;针对不同的低码平台设计&#xff0c;影响的…

stable_diffusion提示词编写笔记(1)

stable_diffusion提示词编写笔记(1) start 总结一下AI绘画学到的知识。 一.提示词分两种&#xff1a; 1.正向提示词&#xff1b; 2.反向提示词&#xff1b; 一个对应你希望图形包含的内容提示词&#xff0c;一个对应你不希望图形出现的内容提示词。 二.如何书写提示词 1.内…

记一次VulnStack渗透

信息收集 netdiscover的主机发现部分不再详解&#xff0c;通过访问端口得知20001-2003端口都为web端口&#xff0c;所以优先考虑从此方向下手 外网渗透 GetShell Struct漏洞 访问2001端口后&#xff0c;插件Wappalyzer爬取得知这是一个基于Struct的web站点&#xff0c;直接…

gtkmm4 应用程序使用 CSS 样式

文章目录 前言css选择器css文件示例源代码效果 前言 程序样式和代码逻辑分离开 使代码逻辑更可观 css选择器 Cambalache提供了两种css-classes 相当于css里的类名:class“类名”css-name 相当于css里的标签名:spin div p 啥的 如上我设置了这个按钮控件的类名为testButton 标…