您的位置:首页 > 其它

《Database.System.Concepts》【2.1 Structure of Relational Databases】至【2.3 Keys】

2018-03-18 14:58 447 查看

2.1 关系数据库的结构

     关系数据库由表(table)的集合构成,每个表有唯一的名字。例如,图2-1中的 instructor 表记录了有关教师的信息,它有四个列首:ID、name、dept _name和 salary 。该表中每一行记录了一位教师的信息,包括该教师的ID、name、depr_name以及 salary 。类似地,图2-2中的 course 表存放关于课程的信息,包括每门课程的 course _Id、title、 dept_name和credits 。注意,每位教师通过ⅠD列的取值进行标识,而每门课程则通过 course id 列的取值来标识。
      图2-3给出的第三个表是 prereg ,它存放了每门课程的 comp . 先修课程信息。该表具有 course _id和 prereg _id两列,每一天由一个课程对组成,这个课程对表示了第二门课程是第 一门课程的先修课。     由此,Prerep表中的每行表示了两门课程之间的联系:其中一门课程是另一门课程的先修课。作为另一个例子,我们 考察 Instructor 表,表中的行可被认为是代表了从一个特定的ID到相应的name、dept_name和salary值之间的联系般说来,表中一行代表了一组值之间的一种联系。由 于一个表就是这种联系的一个集合,表这个概念和数学上的关系这个概念是密切相关的,这也正是关系数据模型名称的由来。在数学术语中,元组(tuple)只是一组值的序列(或列表)。在n个值之间的一种联系可以在数学上用关于这些值的一个n元组(n-tuple)来表示,换言之,n元组就是一个有n个值的元组,它对应于表中的一行。









      这样,在关系模型的术语中,关系(relation )用来指代表,而元组( tuple )用来指代行。类似地,属性( attribute )指代的是表中的列。
      考察图2-1,我们可以看出 instructor 关系有四个属性:ID 、name 、dept_name和salary。
      我们用关系实例( relation instance )这个术语来表示一个关系的特定实例 也就是所包含的一组特定的行。图2-1所示的 instructor 的实例有12个元组,对 应于12个教师。
      本章我们将使用多个不同的关系来说明作为关系数据模型基础的各种概念。这些关系代表一个大学的一部分。它们并没有包含真实的大学数据库中的所有数据,这主要是为了简化表示。在第7章和第8章里我们将详细讨论如何判断适当的关系结柿的相关准则。
      由于关系是元组集合,所以元组在关系中出现的顺序是无关紧要的。因此,无论关系中的元组是像图2-1那样被排序后列出,还是像图2-4那样无序的,都没有关系;在上述两图中的关系是一样的,因为它们具有同样的元组集合。为便于说明,当我们在显示关系时 大多数情况都按其第一个属性排序。




      对于关系的每个属性,都存在一个允许取值的集合,称为该属性的域( domain )。这样 instructor 关系的 salary 属性的域就是所有可能的工资值的集合,而name属性的域是所有可能的教师名字的集合。
      我们要求对所有关系r而言,r的所有属性的域都是原子的。如果域中元素被看作是不可再分的单元,则域是原子的。它存放教师的一组联系电话号码。那么 phone-number的区域就不是原子的。因为其中的元素是一组电话号码,是可以被再分为单个电话号码这样的子成分的。
      重要的问题不在于域本身是什么,而在于我们怎样在数据库中使用域中元素。现在假设 phone _number属性存放单个电话号码。即便如此,如果我们把电话号码的属性值拆分成国家编号、地区编号以及本地号码,那么我们还是把它作为非原子值来对待。如果我们把每个电话号码作为不可再分的单元。那么phone_number属性才会有原子的域。
      空(null)值是一个特殊的值,表示值未知或不存在。如前所述,如果我们在关系 instructor 中包括属性 phone _number,则可能某教师根本没有电话号码,或者电话号码未提供。这时我们就只能使用空值来强调该值未知或不存在。以后我们会看到,空值给数据库访问和更新带来很多困难,因此应尽量避免使用空值。我们先假设不存在空值,然后在3.6节中我们将插述空值对不同操作的影响。

2.2 数据库模式

       当我们谈论数据库时,我们必须区分数据库模式( database schema )和数据实例( databas Instance ),前者是数据库的逻辑设计,后者是给定时刻数据库中数据的一个快照。关系的概念对应于程序设计语言中变量的概念,而关系模式( relation schema )的概念对应于程序设计语言中类型定义的概念。
      一般说来,关系模式由属性序列及各属性对应域组成。等第3章讨论SQL语言时,我们才去关心每个属性的域的精确定义。
      关系实例的概念对应于程序设计语言中变量的值的概念。给定变量的值可能随时间发生变化;类似地,当关系被更新时,关系实例的内容也随时间发生了变化。相反,关系的模式是不常变化的。

      尽管知道关系模式和关系实例的区别非常重要,我们常常使用同一个名字,比如 instructor ,既指代模式,也指代实例,在需要的时候,我们会显示地指明模式或实例。例如“ instructor 模式”或 instructor 关系的一个实例”、然而,在模式或实例的含义清楚的情况下,我们就简单地使用关系的名字。




      考察图2-5中的 department 关系,该关系的模式是: department ( dept _name, building , budget )。 
      请注意属性dept_name既出现在 instructor 模式中,又出现在 department 模式中。这样的重复并不是一种巧合。实际上,在关系模式中使用相同属性正是将不同关系的元组联系起来的一种方法。例如,假设我们希望找出在 Watson 大楼工作的所有教师的相关信息。我们首先在 department关系中找出所有位于 Watson 的系的 dept _name。接着,对每一个这样的系,我们在 instructor 关系中找出与 dept _name对应的教师信息。
我们继续看大学数据库的例子。
      大学里的每门门程可能妥讲授多次,可以在不同学期授课,甚至可能在同一个学期授课。我们需要一个关系来描述每次课的授课情况或分段情况。该关系模式为 
        section (course_id, sec _id, semester , year , building , room _number, time _slot_id)
图2-6给出了 section 关系的一个示例。我们需要一个关系来描述教师和他们所讲授的课程段 之间的联系。描述此联系的关系模式是:
       Teachers(course_id,sec_id,semester, year , building , room _number, time _slot_id)



       图2-7给出了 teaches 关系的一个示例。
   正如你可以料想的,在一个真正的大学数据库中还维护了更多的关系。除了我们已经列出的这些关系: instructor 、 department 、 course 、 section ,prereq和teaches,在本书中我们还要使用下列关系
 student (ID, name , dept _ name , tot _cred) 
 takes(ID, course _id, sec _id, semester , year ,  grade )
 classroom (building, room _number, capacity )

 time slot (time_slot_id, day , start-t
4000
ime , end _time)





2.3 码

      我们必须有一种能区分给定关系中的不同元组的方法。这用它们的属性来表明。也就是说,一个元组的属性值必须是能够唯一区分元组的。换句话说,一个关系中没有两个元组在所有属性上的取值都相同。
    超码( superkey )是一个或多个属性的集合,这些属性的组合可以使我们在一个关系中唯一地标识一个元组。例如, instructor 关系的ID属性足以将不同的教师元组区分开来,因此,ID是一个超码。另一方面, instructor的name属性却不是一个超码,因为几个教师可能同名。形式化地描述,设R表示关系r模式中的属性集合。如果我们说R的一个子集K是r的一个超码,则限制了关系r中任意两个不同元组不会在K的所有属性上取值完全相等,即如果t1和t2在r中且t1≠t2,,则t1,K≠L2、K。
       超码中可能包含无关紧要的属性。例如,ID和name的组合是关系 Instructor 的一个超码。如果K是一个超码,那么K的任意超集也是超码。我们通常只对这样的一些超码感兴趣,它们的任意真子集都不能成为超码。这样的最小超码称为候选码( candidate key )。几个不同的属性集都可以做候选码的情况是存在的。假设name和 depr _name的组合足以区分instructor关系的各个成员。那么ID和|name,dept _name|都是候选码。虽然属性ID和name一起能区分instructor关系的各个成员,但它们的组合|ID,name|并不能成为候选码,因为单独的属性ID已是候选码。
      我们用主码( primary key )这个术语来代表被数据库设计者选中的、主要用来在一个关系中区分不同元组的候选码。码(不论是主码、候选码或超码)是整个关系的一种性质,而不是单个元组的性质。关系中的任意两个不同的元组都不允许同时在码属性上具有相同的值。码的指定代表了被建模的事物在现实世界中的约束。
      主码的选择必须慎重。正如我们所注意到的那样,人名显然是不足以作主码的,因为可能有多个人重名。在美国,人的社会保障号可以作候选码。而非美国居民通常不具有社会保障号,所以跨国企业必须设重他们自己的唯一标识符。另外也可以使用另一些属性的唯一组合作为码。
      主码应该选择那些值从不或极少变化的属性。例如,一个人的地址就不应该作为主码的一部分,因为它很可能变化。另一方面,社会保障号却可以保证决不变化。企业产生的唯一标识符通常不变,除非两个企业合并了,这种情况下可能在两个公司中会使用相同的标识符,因此需要重新分配标识符以确保其唯一性。
      习惯上把一个关系模式的主码属性列在其他属性前面;例如, department 中的 depr _name属性最先列出,因为它是主码。主码属性还加上了下划线。
     一个关系模式(如r1)可能在它的属性中包括另一个关系模式(如r2)的主码。这个属性在r1上称作参照r2的外码( foreign key )。关系r1也称为外码依赖的参耀关系( referencing relation ),r2叫做外码的被参关系 relation )。例如, instructor 中的dept-name属性在 instructor 上是外码,它参照 department ,因为dept_name是 department 的主码。在任意的数据库实例中,从 instructor 关系中任取一个元组,比如,在 department关系中必定存在某个元组,比如t,使得t在dept-name属性上的取值与t与在主码dept_name上的取值相同
      现在考察section 和 teaches 关系。如下需求是合理的:如果一门课程是分段授课的,那么它必须至少由一位教师来讲授;当然它可能由不止一位教师来讲授。为了施加这种约束,我们需要保证如果特定的( course _id,sec_id, semester ,year)组合出现在 section 中,那么该组合也必须出现在 teaches 中。可是,这组值并不构成 teaches 的主码,因为不止一位教师可能讲授同一个这样的课程段。其结果是,我们不能声明从 section 到 teaches 的外码约束(尽管我们可以在相反的方向上声明从teaches到 section 的外码约束)。
      从 section 到 teaches 的约束是参照完整性约束的一个例子。参照完整性约束要求在参照关系中任意元组在特定属性上的取值必然等于被参照关系中某个元组在特定属性上的取值。

 

参考文献:

1.    本文来自《Database.System.Concepts》 SIXTH EDITION,本书主要介绍了数据库系统的基本概念,包括数据库设计数据库语言和系统实现。
2.    作者:(美国)西尔伯沙茨(Abraham Silberschatz)(美国)科思(Henry F.Koah)(美国)苏达尔善(S.Sudarshan)
 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: