【你也能从零基础学会网站开发】 SQL结构化查询语言应用基础--DDL篇--SQL Server数据库开发创建表之FOREIGN KEY外键约束完全详解最详细!

🚀 个人主页 极客小俊
✍🏻 作者简介:程序猿、设计师、技术分享
🐋 希望大家多多支持, 我们一起学习和进步!
🏅 欢迎评论 ❤️点赞💬评论 📂收藏 📂加关注

浅谈FOREIGN KEY 外键约束

说到FOREIGN KEY 约束 这个东西就有点特殊了, 它个跟我们表与表之间的关系是有 联系的!

比如

一个表中的 FOREIGN KEY 约束字段 通常会指向另一个表中的 PRIMARY KEY主键字段

FOREIGN KEY 约束的作用是预防破坏表与表之间连接的动作,也能防止非法数据插入外键字段, 因为它必须是它指向的那个表中的值之一~!

这样说可能大家还有点不是很理解,其实FOREIGN KEY约束是数据库中用于确保数据一致性和完整性的一种重要机制

首先我们要理解一下表的定义与关系以及外键的基本含义

外键

外键在我们这里其实就是FOREIGN KEY约束 我们平常简称FK, 是中的一个多个字段,注意这些字段的值依赖于另一个表, 通常称为主表父表, 而值就是主表中的主键唯一键的值

关系

我们通过外键,我们可以在两个表之间建立一种父子关系,也就是说外键所在的表称之为子表从表, 它依赖于外键所引用的表, 我们称之为: 主表父表

FOREIGN KEY约束 场景描述

从我们的实际应用场景来说我们可以看做是如下案例:
员工与部门
假设有两个表,一个是员工表(子表)命名为Employee,另一个是部门表(主表)命名为dep
那么此时此刻,我们可以把员工表中的部门ID字段可以设置为外键FOREIGN KEY约束,引用部门表中的主键id字段,从而建立员工部门之间的关联关系, 这样建立了从属关系!

所以首先你要知道谁属于谁, 那么你就明白FOREIGN KEY约束是建立在哪个表中了!
其实你可以这样想, 在SQLFOREIGN KEY约束 存在于哪个表,那么那个表就是子表!

语法规则

子表建立的时候,执行以下规则:

子表字段名称 int,  
FOREIGN KEY (子表字段名称) REFERENCES 主表名(主表字段名称)
员工与部门数据场景描述

语法解释如下

这里的子表字段名称是指我们想要设置为外键的字段,它子表中, 而主表名主表字段名称则分别指的是外键引用父表的名称和该表中的字段名称,该字段通常是主键唯一键

那么如果从SQL代码建立表的角度来说,代码如下:

CREATE TABLE dep(  
    department_id int PRIMARY KEY,  
    dep_name VARCHAR(100)  
)
  
CREATE TABLE employees (  
    id int PRIMARY KEY,  
    username VARCHAR(100),  
    department_id int,  
    FOREIGN KEY (department_id) REFERENCES dep(department_id)  
)

我们在SQL Server 2000中来执行以下看看效果!

如图

我们要注意一点,FOREIGN KEY约束通常不是单独使用的,而是作为CREATE TABLE语句或ALTER TABLE语句的一部分进行使用!

在这个例子中,Employee表department_id字段被设置为外键,它引用了dep表的id主键字段

那现在你可能会想,这样做的目的又是什么呢?

这样做有几个关键的作用和好处:

1.数据一致性

外键约束确保了Employee员工表中的每一条记录都指向dep部门表中存在的一个有效部门

那么这意味着,我们不能在Employee员工表中随意插入一个department_id,如果要插入那么department_id必须要在dep部门表中存在才可以进行插入!~ 否则会报错!

如图


效果如图


这就有助于维护数据的一致性,防止出现孤立的、无法与部门对应的员工记录了!

2.数据完整性

外键约束还可以防止dep(部门表)中的部门信息被意外删除修改,从而影响到Employee员工表中的相关记录。
也就是说外键约束会阻止我们删除修改那些仍然被Employee表引用的部门记录,从而维护了数据的完整性。

如图

3.FOREIGN KEY约束也可以进行查询优化

虽然FOREIGN KEY约束本身并不直接优化查询性能,但它通过明确表之间的关系,使得数据库优化器能够更有效地执行JOIN等查询操作, 这是因为数据库知道哪些字段是相关的,并可以利用这些关系来减少需要扫描的数据量。

4.从业务逻辑表达方面
FOREIGN KEY约束是数据库层面上的业务逻辑表达, 它告诉数据库系统, 表与表之间存在一种特定的关系,这种关系对于应用程序的业务逻辑来说是至关重要的。通过FOREIGN KEY约束,数据库能够自动地强制执行这种关系,而不需要在应用程序代码中显式地编写额外的逻辑来维护它

5.数据建模方面

在数据库设计和建模过程中,FOREIGN KEY外键约束是表达实体之间关系的一种重要方式。
这样我们可以清晰地看到哪些实体是相互关联的,以及它们是如何关联的。
这对于理解数据库的结构、设计数据库查询以及维护数据库的一致性都是非常重要的!~

如图

订单与商品数据场景描述

再举个梨子:订单与商品的应用场景, 这个场景是我们实际开发中经常会遇见到的!

订单管理系统中,订单表商品表之间也可以通过外键建立关联,确保订单中引用的商品确实存在于商品表中。
所以我们首先要梳理清楚这种关系层面, 我们才好去建立 FOREIGN KEY外键关系 知道谁是主表(父表) 谁又是从表(子表)

在这个场景下很明显我们的商品表主表,而订单表从表, 以确保订单中引用的商品确实存在于商品表中!

例如

场景描述

在订单管理系统中,通常有以下几个关键实体:

商品表Product:代表可购买的物品或服务,每个商品有唯一的标识, 比如: 商品id
订单表order: 代表客户购买的一组商品,每个订单包含多个订单项, 每个订单项关联到一个具体的商品和购买数量

实体关系描述

商品表Product:作为主表(父表),存储商品的基本信息字段,比如: 商品ID(主键)、商品名称、价格等。
订单表 Order:作为从表(子表),存储订单的基本信息,比如: 订单ID(主键)、下单时间、客户信息等。

但是通常情况下订单表本身不直接存储商品信息,而是通过订单项商品表建立关联, 所以这里我们多建立一个订单项表OrderItem

订单项表OrderItem:来作为连接订单表商品表的桥梁,
也就是说每个订单项包含订单ID(外键,引用订单表的主键)、商品ID(外键,引用商品表的主键)和购买数量等信息
这样,一个订单可以包含多个订单项,每个订单项都关联到一个具体的商品。

注意: 在这里订单商品之间并不是直接的多对多关系,而是通过订单项表来实现的一对多多对一的组合关系。

外键关系

那么我们就可以在订单项表中,会有两个外键:order_idproduct_id
order_id外键,引用订单表order_id字段(主键),表示该订单项属于哪个订单
product_id外键,引用商品表product_id字段(主键),表示该订单项对应哪个商品

表的建立

建立FOREIGN KEY外键关系

在创建数据库表时,我们需要在这两个外键字段上设置外键约束,以确保数据一致性完整性

那么创建商品表、订单表、订单项目表SQL中我们可以如下方式:

商品表

CREATE TABLE Product(   /*创建商品表*/
  pid int PRIMARY KEY IDENTITY,
  pname varchar(20),
  price varchar(20) 
)

订单表

CREATE TABLE Orders(      /*创建订单表*/
    oid int PRIMARY KEY IDENTITY,
    times varchar(20)
    userinfo int
)

注意: 假设userinfo 字段用户ID ,那么这里很可能会把userinfo字段设置为外键, 还需要添加外键约束, 这里我们就不多说了!

订单项目表

CREATE TABLE OrderItem (    /*创建订单项目表*/
    order_id INT PRIMARY KEY IDENTITY,  
    oid INT,  
    pid INT,  
    FOREIGN KEY (oid) REFERENCES Orders(oid),  
    FOREIGN KEY (pid) REFERENCES Product(pid)  
)

如图


那么我们现在就可以来添加数据测试一下!


我们结合上图一起来捋一捋关系具体来说:

一个订单(Order)可以包含多个订单项(OrderItem),每个订单项代表订单中一个商品及其数量,对吧!
这是一对多的关系,因为一个订单对应多个订单项, 其实你可以理解这实际上就相当于一个订单对应了多个商品,因为每个订单项都代表了订单中的一个具体商品及其购买数量。

反过来想一个订单项OrderItem只属于一个订单Order,并且只对应一个商品(Product)。
这是多对一的关系,因为多个订单项可以属于同一个订单,但每个订单项只对应一个商品。

然而,当我们从另一个角度看时,即商品订单项之间的关系,以及订单项订单之间的关系结合起来考虑,可以说商品订单之间存在一种多对多的潜在关系,但这种关系并不是直接的,而是通过订单项作为中介来实现的。

一个商品可以被多个订单项引用,也就是说多个订单可能包含同一个商品。
同时,一个订单(Order)可以包含多个不同的商品,
因此,虽然订单商品之间不是直接的多对多关系,但它们之间确实存在这种潜在的、通过订单项表间接实现的多对多关系。在实际应用中,我们通常通过维护订单项表来管理这种复杂的关系,确保数据的准确性和一致性,同时也在适当的时候设置FOREIGN KEY外键约束

从这里的场景来说,我们会先有商品表(主表)然后再有订单表,最后才是订单项目表
所以我们有了FOREIGN KEY外键约束就不会存在 乱加数据 破坏数据的一致性和稳定性!

我们通过SQL查询可以来查看具体我们每一个订单对应哪些商品, 以及对应的用户

select Orders.oid,Product.pid,Product.price,Product.pname,Orders.userinfo 
from OrderItem
INNER JOIN Orders ON OrderItem.oid = Orders.oid 
INNER JOIN Product ON OrderItem.pid = Product.pid
WHERE Orders.userinfo = 1;

如图


比如我要查询用户ID为1的对应有哪些订单,以及商品

如图

修改FOREIGN KEY外键约束

如果在表已存在的情况下要给某个字段创建 FOREIGN KEY 约束 并且带有外键约束命名, 那么语法如下:

ALTER TABLE 表名称 ADD CONSTRAINT 外键约束名称 FOREIGN KEY (子表字段名称) REFERENCES 主表名称(主表字段名称)

我们来测试一下!

如图

CREATE TABLE Product(   /*创建商品表*/
  pid int PRIMARY KEY IDENTITY,
  pname varchar(20),
  price varchar(20) 
)

CREATE TABLE Orders(      /*创建订单表*/
    oid int PRIMARY KEY IDENTITY,
    times varchar(20),
    userinfo int
)

CREATE TABLE OrderItem (    /*创建订单项目表*/
    order_id INT PRIMARY KEY IDENTITY,  
    oid INT,  
    pid INT
)

然后修改OrderItem 表中的oidpid字段

ALTER TABLE OrderItem  ADD CONSTRAINT fk_oid FOREIGN KEY (oid) REFERENCES Orders(oid);
ALTER TABLE OrderItem  ADD CONSTRAINT fk_pid FOREIGN KEY (pid) REFERENCES Product(pid);

如图


我们可以在企业管理器中去查看外键约束的关系图

如图

删除FOREIGN KEY外键约束

如需撤销 FOREIGN KEY 约束 我们最好根据创建外键约束的时候,命名的名字来进行删除!

ALTER TABLE 表名称 DROP CONSTRAINT 外键名称

如图

这时候,我们回到企业管理器中查看表关系,就会自动取消 彼此之间的约束联系了!

如图

关于表与表之间的关系和SQL查询的方法以及如何使用INSERT UPDATE 和DELETE语句来处理数据 ,我会在接下来的章节再和大家 慢慢详谈!

"👍点赞" "✍️评论" "收藏❤️"

大家的支持就是我坚持下去的动力!

如果以上内容有任何错误或者不准确的地方,🤗🤗🤗欢迎在下面 👇👇👇 留个言指出、或者你有更好的想法,
欢迎一起交流学习❤️❤️💛💛💚💚

更多 好玩 好用 好看的干货教程可以 点击下方关注❤️ 微信公众号❤️
说不定有意料之外的收获哦..🤗嘿嘿嘿、嘻嘻嘻🤗!
🌽🍓🍎🍍🍉🍇