什么是外键? 为什么需要外键?怎么使用外键?

article/2025/9/14 4:12:40

首先我们先思考一个问题:

如何将京东"fuliuqingfeng"的用户信息及其多个邮寄商品地址保存到数据库中?

我们第一步会这样操作实现:

create table user_info(id char(36) primary key,user_name varchar(30) not null,password varchar(30) not null,real_name varchar(8),mobile char(11),address varchar(150)
);
insert into user_info (id,user_name,password,real_name,mobile,address) 
values ('51b28fe1-4ebf-41ac-a17b-d5e276861fd0','fuliuqingfeng','123456','张三','18920120206','河南安阳');
insert into user_info (id,user_name,password,real_name,mobile,address) 
values ('cc95772b-75a2-4702-bd99-4c3b0322d606','fuliuqingfeng','123456','李四','18617297545','北京海淀');
insert into user_info (id,user_name,password,real_name,mobile,address)
values ('c63028fd-cf8d-4dac-a278-b5cc8fd61e3c','fuliuqingfeng','123456','王五','17694976949','山西大同');

这样在表中的形式为:

表中数据可以理解为:

 用户名为fuliuqingfeng 支付密码为 123456  但其有不同的收获地址

如: 张三 联系电话为18920120206 收获地址为 河南安阳 下面也是这样。

 

但我们可以看到这时表中的数据存在一个问题:

这种表结构存在严重的字段冗余(user_name和password列),如果个人信息字段比较多这一问题表现的越严重(比如再加入身份证信息,这一列又会重复出现)。

所以我们可以做出改变,利用两个表解决这样的问题:

create table user_info(id char(36) primary key,user_name varchar(30) not null,password varchar(30) not null
)
insert into user_info (id,user_name,password) values ('51b28fe1-4ebf-41ac-a17b-d5e276861fd0','fuliuqingfeng','123456');create table address(id char(36) primary key,user_info_id char(36),real_name varchar(8) not null,mobile char(11) not null,address varchar(150) not null
)
insert into address (id,user_info_id,real_name,mobile,address) 
values ('bfb9472a-7911-4e6f-a479-3b719454ebab','51b28fe1-4ebf-41ac-a17b-d5e276861fd0','张三','18920120206','河南安阳');
insert into address (id,user_info_id,real_name,mobile,address) 
values ('5227c6b9-45a2-44aa-8ac0-1f63a38d3b65','51b28fe1-4ebf-41ac-a17b-d5e276861fd0','李四','18617297545','北京海淀');
insert into address (id,user_info_id,real_name,mobile,address) 
values ('30b8584b-aa6a-4516-a623-03f487058586','51b28fe1-4ebf-41ac-a17b-d5e276861fd0','王五','17694976949','山西大同');

结果为:

这种表结构消除了字段冗余,但由于只是逻辑上的“外键”关系,所以依然无法保证数据完整性

此时依然存在问题:

例如可以将user_info中id为51b28fe1-4ebf-41ac-a17b-d5e276861fd0的数据删除,但此时地址表中数据将不再完整——找不到这些地址属于哪个用户;再例如也可以向address表中添加一条user_info_id不存在的地址信息(如:insert into address (id,user_info_id,real_name,mobile,address) values ('7da42cc6-36a6-4ad5-9998-71dbc30c8e17','ddc376dd-f8b3-42a6-b42a-db22abed1941','xiaowang','18338970095','北京东城区');)——同样,该条数据并不完整,依然找不到这些地址属于哪个用户。

进而我们继续改进:

create table user_info(id char(36) primary key,user_name varchar(30) not null,password varchar(30) not null
)
insert into user_info (id,user_name,password) values ('51b28fe1-4ebf-41ac-a17b-d5e276861fd0','fuliuqingfeng','123456');create table address(id char(36) primary key,user_info_id char(36),real_name varchar(8) not null,mobile char(11) not null,address varchar(150) not null,constraint address_user_info_id_fk foreign key(user_info_id) references user_info(id)
)
insert into address (id,user_info_id,real_name,mobile,address) 
values ('bfb9472a-7911-4e6f-a479-3b719454ebab','51b28fe1-4ebf-41ac-a17b-d5e276861fd0','张三','18920120206','河南安阳');
insert into address (id,user_info_id,real_name,mobile,address) 
values ('5227c6b9-45a2-44aa-8ac0-1f63a38d3b65','51b28fe1-4ebf-41ac-a17b-d5e276861fd0','李四','18617297545','北京海淀');
insert into address (id,user_info_id,real_name,mobile,address) 
values ('30b8584b-aa6a-4516-a623-03f487058586','51b28fe1-4ebf-41ac-a17b-d5e276861fd0','王五','17694976949','山西大同');

address表中添加一条user_info_id不存在的地址信息时:

将user_info中id为51b28fe1-4ebf-41ac-a17b-d5e276861fd0的数据删除时:

我们发现会报错。

此时也就实现了我们所说的 "外键"。


http://chatgpt.dhexx.cn/article/a6fMj9ft.shtml

相关文章

MySQL外键(详解)

MySQL外键(详解) 什么是外键:    外键是指引用另外一个表中的一列或多列数据,被引用的列应该具有主键约束或者唯一性约束(简单来说外键是另一个表的主键或者唯一约束)。外键可以有重复的, 可以是空值&…

C/C++unlink函数的使用

一、头文件 #include<unistd.h> 二、函数原型 int unlink(const char *pathname); 三、函数介绍 unlink()函数功能即为删除文件。执行unlink()函数会删除所给参数指定的文件。 注意&#xff1a; 执行unlink()函数并不一定会真正的删除文件&#xff0c;它先会检查文件…

Linux下unlink函数的使用

一、头文件 #include<unistd.h> 二、函数原型 int unlink(const char *pathname); 三、函数介绍 unlink()函数功能即为删除文件。执行unlink()函数会删除所给参数指定的文件。 注意&#xff1a; 执行unlink()函数并不一定会真正的删除文件&#xff0c;它先会检查文件系…

Universal link的坑

当你觉得Universal link所有配置都没问题&#xff0c;但是通过浏览器打开Universal Link没有命中的时候看下这里 看了很多篇文章对比了Universal Link配置和流程之后没问题&#xff0c;浏览器打开还是不生效&#xff0c;最终在最关键的配置apple-app-site-association文件破案了…

unlink 和 remove 的区别

Linux下开发的时候,会经常使用unlink来删除文件的,而用C的时候,经常用remove删除文件. 这两者的去区别通过man手册发现&#xff1a;  当remove() 中的pahtname指定为目录时,相当于调用rmdir 删除目录,当remove() 中的pathname指定问文件时,相当于调用unlink 删除文件链接 所以…

004link()unlink()_LINUX

Linux的学习笔记 link、unlink1. 共享盘块2. link() 为已经存在的文件创建目录项&#xff08;硬链接&#xff09;头文件包含和函数声明 3. unlink() 删除一个文件的目录项头文件包含和函数声明Linux下删除文件的机制&#xff1a;demo 4. unlink 使用注意及隐性回收demo4.1 编译…

CTF PWN之heap入门 unlink

环境 ubuntu20 pwndbg patchelf glibc-all-in-one 为什么要用ubuntu不用kali&#xff0c;这里不做解释&#xff0c;总之就是自己在搭环境时出现了各种问题&#xff0c;但用ubuntu20不会出现&#xff0c; pwndbg&#xff0c;打pwn题必备&#xff0c;具体安装过程见gdb与ped…

NPM报错 Error: EPERM: operation not permitted, unlink......解决办法和清除缓存。

由于国内外环境因素&#xff0c;npm install安装依赖的时候经常会出现各种问题&#xff0c;特别是“Error: EPERM: operation not permitted, unlink…”这个错误。 在这里插入图片描述 这个错误因为报错信息的误导性&#xff0c;导致很多网上提出的解决办法都是什么设置权限…

vue 启项目报错Error: EPERM: operation not permitted, unlink

使用npm install安装依赖之后&#xff0c;有时候存在网络或其他问题安装不上个别依赖&#xff0c;其项目失败&#xff0c;报错 当启项目时报错&#xff1a;Error: EPERM: operation not permitted, unlink 此问题困扰好久&#xff0c;刚开始以为和其他人遇到的问题相似是因为管…

好好说话之unlink

堆溢出的第三部分unlink&#xff0c;这可能是有史以来我做的讲解图最多的一篇文章了累死 。可能做pwn的人都应该听过unlink&#xff0c;见面都要说声久仰久仰。学unlink的时候走了一些弯路&#xff0c;也是遇到了很多困扰的问题&#xff0c;会在后面的内容中做出标注。由于写的…

Unlink

Author&#xff1a;ZERO-A-ONEDate&#xff1a;2021-07-03 一、unlink的原理 简介&#xff1a;俗称脱链&#xff0c;就是将链表头处的free堆块unsorted bin中脱离出来然后和物理地址相邻的新free的堆块合并成大堆块&#xff08;向前合并或者向后合并&#xff09;&#xff0c;再…

unlink快速入门

0x01 正常unlink 当一个bin从记录bin的双向链表中被取下时&#xff0c;会触发unlink。常见的比如&#xff1a;相邻空闲bin进行合并&#xff0c;malloc_consolidate时。unlink的过程如下图所示&#xff08;来自CTFWIKI&#xff09;主要包含3个步骤&#xff0c;就是这么简单。 …

Linux常用命令——unlink命令

在线Linux命令查询工具(http://www.lzltool.com/LinuxCommand) unlink 系统调用函数unlink去删除指定的文件 补充说明 unlink命令用于系统调用函数unlink去删除指定的文件。和rm命令作用一样&#xff0c;都是删除文件。 语法 unlink(选项)(参数)选项 --help&#xff1a;…

element table表格,动态生成表头,基于可拖拽组件,拖动排序

效果展示 使用步骤 所需页面根据解释粘入 表格页面(父组件).txt 中代码&#xff0c; 引入dragList.vue组件 1.表格页面(父组件) <dragList radio"ssss" ></dragList> //引用子组件<el-tablev-if"asa":data"tableData"ro…

vue-draggable的多列拖动与拷贝拖拽(不删除源数据列)

vue-draggable的多列拖动与拷贝拖拽&#xff08;不删除源数据列&#xff09; Demo所用属性所遇困难源码 Demo 官方文档 录屏软件&#xff1a;screenToGif (将视频转为Gif&#xff0c;我认为简单又好操作) 我深知&#xff0c;文字的感知不如图片&#xff0c;图片的感知不如视频…

【JavaScript】列表拖拽升级,支持双击添加和时间轴左右拖动

TOC H5实现时间揍拖动 实现双击文件列表的项添加到时间揍的最后一条。 时间轴里可以左右拖动位置。 主要代码&#xff1a; /*** 时间轴拖动结束* param $event* constructor*/ const lineDragEnd ( $event ) > {console.log( 时间轴拖动结束 , $event )console.log(移动了,…

echarts拖拽echarts实现多条可拖动节点的折线图

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <script src="js/echarts/echarts.js"></script> <title>在指定位置画多个点</title> <style> …

html拖拽页面特效,div+css实现网页模块或栏目拖动(即拖拽效果)

//为Number增加一个属性,判断当前数据类型是否是数字 Number.prototype.NaN0function(){return isNaN(this)?0:this;} //全局变量 var iMouseDownfalse; var dragObjectnull; //获得鼠标的偏移量(对象2-对象1) function getMouseOffset(target,ev) { evev||window.event; var …

RecyclerView实现Item可拖拽(拖动、删除)

RecyclerView实现Item可拖拽&#xff08;拖动、删除&#xff09; 话不多说&#xff0c;先附上效果图&#xff1a; ItemTouchHelper 这是一个RecyclerView的工具&#xff0c;提供了drag & swipe 的功能&#xff0c;可以帮助我们处理RecyclerView中的Item的拖拽和滑动事件…

原生drag拖拽后元素过大,挡住其他可拖动位置无法拖动问题

写一个蒙层&#xff0c;还未拖动前原始层在上面&#xff0c; 拖动那过程中&#xff08;dragover&#xff09;原始层在下面&#xff0c; 拖进目标元素后&#xff08;drop&#xff09;&#xff0c;此时蒙层在上面&#xff0c;根据drop的$event获取落在蒙层哪个div上&#xff0c…