SQL 外键知识

当我们用主键唯一标识记录时,我们就可以在​ ​students​​表中确定任意一个学生的记录:

name

other columns…

我们还可以在​ ​classes​​表中确定任意一个班级记录:

name

other columns…

但是我们如何确定​ ​students​​表的一条记录,例如,​ ​id=1​​的小明,属于哪个班级呢?

由于一个班级可以有多个学生,在关系模型中,这两个表的关系可以称为”一对多”,即一个​ ​classes​​的记录可以对应多个​ ​students​​表的记录。

为了表达这种一对多的关系,我们需要在​ ​students​​表中加入一列​ ​class_id​​,让它的值与​ ​classes​​表的某条记录相对应:

class_id

name

other columns…

这样,我们就可以根据​ ​class_id​​这个列直接定位出一个​ ​students​​表的记录应该对应到​ ​classes​​的哪条记录。

例如:

  • 小明的​ ​class_id​​是​ ​1​​,因此,对应的​ ​classes​​表的记录是​ ​id=1​​的一班;
  • 小红的​ ​class_id​​是​ ​1​​,因此,对应的​ ​classes​​表的记录是​ ​id=1​​的一班;
  • 小白的​ ​class_id​​是​ ​2​​,因此,对应的​ ​classes​​表的记录是​ ​id=2​​的二班。

在​ ​students​​表中,通过​ ​class_id​​的字段,可以把数据与另一张表关联起来,这种列称为​ ​外键​​。

外键并不是通过列名实现的,而是通过定义外键约束实现的:

其中,外键约束的名称​ ​fk_class_id​​可以任意,​ ​FOREIGN KEY (class_id)​​指定了​ ​class_id​​作为外键,​ ​REFERENCES classes (id)​​指定了这个外键将关联到​ ​classes​​表的​ ​id​​列(即​ ​classes​​表的主键)。

通过定义外键约束,关系数据库可以保证无法插入无效的数据。即如果​ ​classes​​表不存在​ ​id=99​​的记录,​ ​students​​表就无法插入​ ​class_id=99​​的记录。

由于外键约束会降低数据库的性能,大部分互联网应用程序为了追求速度,并不设置外键约束,而是仅靠应用程序自身来保证逻辑的正确性。这种情况下,​ ​class_id​​仅仅是一个普通的列,只是它起到了外键的作用而已。

要删除一个外键约束,也是通过​ ​ALTER TABLE​​实现的:

注意:删除外键约束并没有删除外键这一列。删除列是通过​ ​DROP COLUMN ...​​实现的。

通过一个表的外键关联到另一个表,我们可以定义出一对多关系。有些时候,还需要定义”多对多”关系。例如,一个老师可以对应多个班级,一个班级也可以对应多个老师,因此,班级表和老师表存在多对多关系。

多对多关系实际上是通过两个一对多关系实现的,即通过一个中间表,关联两个一对多关系,就形成了多对多关系:

​teachers​​表:

name

张老师

王老师

李老师

赵老师

​classes​​表:

name

中间表​ ​teacher_class​​关联两个一对多关系:

teacher_id

class_id

通过中间表​ ​teacher_class​​可知​ ​teachers​​到​ ​classes​​的关系:

  • ​id=1​​的张老师对应​ ​id=1,2​​的一班和二班;
  • ​id=2​​的王老师对应​ ​id=1,2​​的一班和二班;
  • ​id=3​​的李老师对应​ ​id=1​​的一班;
  • ​id=4​​的赵老师对应​ ​id=2​​的二班。

同理可知​ ​classes​​到​ ​teachers​​的关系:

  • ​id=1​​的一班对应​ ​id=1,2,3​​的张老师、王老师和李老师;
  • ​id=2​​的二班对应​ ​id=1,2,4​​的张老师、王老师和赵老师;

因此,通过中间表,我们就定义了一个”多对多”关系。

一对一关系是指,一个表的记录对应到另一个表的唯一一个记录。

例如,​ ​students​​​表的每个学生可以有自己的联系方式,如果把联系方式存入另一个表​ ​contacts​​,我们就可以得到一个”一对一”关系​

student_id

mobile

135xxxx6300

138xxxx2209

139xxxx8086

有细心的童鞋会问,既然是一对一关系,那为啥不给​ ​students​​表增加一个​ ​mobile​​列,这样就能合二为一了?

如果业务允许,完全可以把两个表合为一个表。但是,有些时候,如果某个学生没有手机号,那么,​ ​contacts​​表就不存在对应的记录。实际上,一对一关系准确地说,是​ ​contacts​​表一对一对应​ ​students​​表。

还有一些应用会把一个大表拆成两个一对一的表,目的是把经常读取和不经常读取的字段分开,以获得更高的性能。例如,把一个大的用户表分拆为用户基本信息表​ ​user_info​​和用户详细信息表​ ​user_profiles​​,大部分时候,只需要查询​ ​user_info​​表,并不需要查询​ ​user_profiles​​表,这样就提高了查询速度。

关系数据库通过外键可以实现一对多、多对多和一对一的关系。外键既可以通过数据库来约束,也可以不设置约束,仅依靠应用程序的逻辑来保证。

Original: https://www.cnblogs.com/bdxily/p/16415896.html
Author: 疯人院code
Title: SQL 外键知识

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/684988/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球