数据结构中:两个表的关联-表的主键

来源:互联网 发布:淘宝优惠券网站制作 编辑:程序博客网 时间:2024/04/28 01:18

    在现实的数据库应用中,数据保存在多个相关联的表中。基本上没有数据只存在一个表中的情况。小的应用系统一般也有十几个表,大型系统一般有上千个表。

 

    我们以学生成绩查询为例来讲解表的关联。除了Student表,这里我们需要新建成绩表,表Grade:

 

Sno

Cno

Grade

S01

C01

82

S01

C04

77

S02

C02

73

S03

C02

67

S03

C03

85

S04

C02

91

S05

C01

71

S05

C03

81

S06

C01

86

S06

C03

89

S06

C04

90

                                        表3 Grade

    表中的字段的含义分别为学号、课程号和成绩。其中字段Sno和Cno构成复合主键。

 

    相对于单一表,将数据分散保存在多个关联的表中,不仅条理清楚,而且方便数据的管理和查询。特别是存在多对多等复杂关系时,关联表可以通过中间表等方法轻松实现,此时如果采用单一表,表的规模会很大且存在很多冗余信息,大大降低查询效率。

 

    假如使用单一表,则需要如下结构的表来存储以上数据:

 

Sno

Sname

Ssex

Sage

Sdept

Cno

Grade

S01

王建平

21

自动化

C01

82

S01

王建平

21

自动化

C04

77

S02

刘华

19

电子

C02

73

S03

范林军

18

电子

C02

67

S03

范林军

18

电子

C03

85

S04

李伟

18

计算机

C02

91

S05

赵健

18

数学

C01

71

S05

赵健

18

数学

C03

81

S06

黄玲

20

数学

C01

86

S06

黄玲

20

数学

C03

89

S06

黄玲

20

数学

C04

90

 

    可见表的结构非常复杂。这个表只是包含了学生的基本信息和选课信息,倘若将几十上百个分立表中的信息都包含在一个表中,其复杂程度是不可想象的。随着复杂程度的增加,对数据的操作(例如插入新数据)SQL语句也会越来越复杂,这里就不举例子了。

    另外,我们可以看到表中有很多冗余的数据。黄玲一个学生,其基本信息在三条记录中被重复保存,这对系统存储空间也是一种浪费。

    正是由于上述原因,实际数据都是保存在相互关联的表中。那么多个表是如何实现相互关联的呢?

    这里我们新建此前已经提到的课程表,表Course,课程号Cno作为其主键:

 

Cno

Course

Credit

C01

数据库概论

3

C02

C程序设计

4

C03

高等数学

4

C04

计算机网络

3

 

    这样在当前学生选课的例子中有三个表,学生表(Sno,Sname,Ssex,Sage,Sdept)、成绩表(Sno,Cno,Grade)、课程表(Cno,Course,Credit)。其中成绩表中的Sno和Cno字段分别对应着学生表中的Sno字段和课程表中的Cno字段。也就是说,成绩表Sno字段的每个值都可以在学生表Sno字段值中找到,它们对应的是同一个学生,学生表和成绩表通过字段Sno相互关联。同理,成绩表和课程表通过字段Cno相互关联。

 

    定义外键能够体现表的关联。如果表A的一个字段X不是A的主键,而是另一个表B的主键,则这个字段X称为表A的外键,表A为参照表,表B为被参照表。外键约束主要是为了与另一张表进行关联,以维护两个表之间的一致性关系。表的外键是另一个表的主键,与主键不同的是,外键值可以有重复的,也可以是空的。在此例中,表Grade中的字段Sno即为外键,在表Student中字段Sno则是主键。这样,表Grade便通过外键Sno实现了与表Student的关联。

    一个表可以有多个外键。正如上述例子中字段Cno也是表Grade的外键,表Grade通过外键Cno与表Course实现了关联。

 

    相对于单表,多表关联有诸多优点:

    1.       结构关系灵活。每张表都可以反映不同方面的信息,通过多张相互关联的表,可以管理任意复杂的数据。

    2.       操作快速,效率高。无论是单表操作还是关联操作,在相互关联的多个表基础上都可以简单有效地实现。仍以学生选课为例,当需要修改表中的数据,例如插入一个学生的成绩,只需对表Grade作修改:

 

INSERT INTO Grade (Sno,Cno,Grade)  VALUES(“S04”,”C04”,62);

 

查询姓名为刘华的学生的选课情况,需要关联学生表和成绩表,SQL语句如下:

 

SELECT Student2.Sname,Grade.Cno From Student2 INNER JOIN Grade ON Student.Sno=Grade.Sno WHERE Student2.Sname=”刘华”;

 

    3.       节省存储空间。由于每个表分别存储不同方面的信息,数据重复存储的现象比较少。 

    4.       表间存在约束关系,避免出错。例如登记学生成绩时,成绩表中的学号必须对应学生表中已有的学号,这种约束关系避免了插入错误的信息。:

原创粉丝点击