数据库:关系型数据库

在开始编写文章前,有几个问题需要思考一下:

  • 数据字典和系统目录
  • 完整性规则
  • 索引
  • 关系集合操作
  • 关系数据库表联系
  • 数据冗余

数据之间的联系也可使用关系来表示增强了关系数据库逻辑视图的应用。关系是一种数学上的结构,但对于用户而言,将其看作“  "表" 则更容易理解。表是由行和列构成的二维结构。由于关系模型的创建者 E.F.Codd 使用关系作为表的同义词,因此表也被称为关系。表是逻辑关系的永久化表示四,即关系的内容可以永久存储。就表用户而言,表包含一组相关的实体发生,即表是一个实体集。这是由于这个原因,"实体集" 和 "表" 常常替换使用。

表视图使得发现和定义实体和联系变得简单,从而大大简化了数据库设计任务。

  • 表是由行和列构成的二维结构
  • 表中的每行(元组)代表实体集中的一个实体发生
  • 表中的每列代表一个属性,并且每列名称不同
  • 每一行和列的交叉点代表单一的数据值
  • 每列中的所有值必须遵循相同数据格式
  • 每列都有一个称为属性域的特定取值范围
  • 对 DBMS 而言,行与列的顺序无关紧要
  • 每张表必须有一个属性或属性的组合唯一标识每一行

1. 数据字典和系统目录

数据字典是对数据库中所有表的详细描述。因此,数据字典至少应包含系统中每张表的所有属性名称和特征。简言之,数据字典包含元数据,即关于数据的数据。数据字典有时也称为 "数据库设计者的数据库",因为它记录了表和表结构的设计决定。

与数据字典相似,系统目录(system catalog)也包含元数据。系统目录称为详细的系统数据字典,用于描述数据库中所有的对象,包括表名、表的创建者和创建时间、每张表中列的数量、每个列的数据类型、索引文件名称、索引创建者、授权用户和存取权限等数据。由于系统目录包含所有需要的数据字典信息,因此术语 "系统目录" 和 "数据字典" 常常混用。事实上,当前关系数据库软件一般只提供系统目录,我们可以从中导出设计者的数据字典信息。系统目录实际上是一个系统创建的数据库,其中的表存储了用户/设计者创建的数据库特征和内容。因此,系统目录表可以像任何用户/设计者创建的表一样进行查询。

实际上,系统目录会自动产生数据库文档。当向数据库添加一个新表时,RDBMS 会检查文档以清除多义词和同义词。如 boar 和 bore,或者是拼写相同但意义不同的词,如 fair(意思是 "just")和 fair(意思是 "festival")。在数据库上下文中,多义词是指相同属性名称标记不同属性。为了减少混乱,应避免在数据库中出现多义词。在这个意义上讲,数据字典很有用。

同义词是多义词的反义词,是指使用不同名称描述相同属性。例如,car 和 auto 都指汽车。数据库也应避免出现同义词。

2. 码

在关系模型中,码是很重要的概念,它们用于唯一标识表中的每一行。另外,它们也用于建立表与表之间的联系,以保证数据的完整性。

码(Key)由一个或多个能够决定所有其他属性的属性组成。码的作用体现在 "决定"(Determination)概念上。"决定" 概念非常重要,因为它还用于决定关系数据库的一个核心概念——函数依赖(Functional Dependency)。函数依赖可以用简单定义为:如果属性 A 决定属性 B,那么属性 B 函数依赖于属性 A。更准确的定义是:如果列 A 的每个值决定且是唯一 一个列 B 中的值,则称属性 B 函数依赖于属性 A。

函数依赖的定义可进一步推广到决定属性值在表中不止出现一次的情况,因此函数依赖也可进一步定义为:如果表中所有行在属性 A 上的取值相同且在属性 B 上的取值也相同,则称 A 决定 B,则 B 函数依赖于 A。

定义函数依赖时可能出现多个属性情形,即码可能由多个属性组成,称由多个属性组成的码为复合码(Composite key)。码中的任何属性称为码属性(Key Attribute)。

由于可能存在复合码,可进一步定义完全函数依赖:如果属性 B 函数依赖于复合码 A,但不依赖于复合码的任何子集,则称属性 B 函数依赖于 A。

在更广泛的码定义中,还有几类特殊的码:

  • 超码(Super Key):是任何可以唯一标识每一行的码。简言之,超码决定一行中的所有属性。
  • 候选码:是没有多余属性的超码,即最小的超码。简言之,主码是被挑选出来、唯一标识每一行的候选码。因此,主码和候选码一样,也是超码。
  • 主码:选做唯一标识任何指定元组的其他所有属性值的候选码。不能包含空值。
  • 辅助码:用于数据检索的一个属性或属性组合。
  • 外码:表中某个属性(或属性组合),其值要么为另一张表中的主码值,要么为空值。

在一个表中,每个主码值必须是唯一的,以保证主码能够唯一识别每一行。此时,称该表满足实体完整性。为保证实体完整性,主码不允许为空值。

不允许在主码中出现空值,也尽可能避免在其他属性上出现空值。在处理非码属性时,很少有不能合理避免出现空值的情形。另外,两个实体可能由于发生联系而出现空值的情形。但即便如此,还是应尽量少用空值。事实上,如果一个表存在空值,则常常表明其数据库设计存在问题。

由于空值表示不同含义,因此若使用不当,则可能出现问题。一个空值可表示:

  • 未知的属性值;
  • 已知但丢弃的属性值;
  • 属性值不可用。

关系数据库允许存在一定可控冗余,在不同表之间利用共享属性实现连接。只有当属性值是不必要重复时,才被认为是数据冗余。

关系数据库也可以用关系模式来表示。关系模式(Relational Schema)是用文本方式表示表,即每张表用表名和紧跟其后用圆括号括起来的属性列表表示,且主码属性用下划线标识。

VENDOR(VEND_CODE,VEND_CONTACT,VEND_AREACODE,VEND_PHONE)

辅助码是用于数据检索的码。注意,辅助码并不要求产生唯一的结果。例如,当一家人住在一起并使用同一个电话时,如果用客户的姓名和电话号码查询,则可能产生多条查询结果。一种效率更差的辅助码是将姓氏与邮政编码相组合,此时会产生更多的匹配结果,然后需再从中找出想要的结果。

3. 完整性规则

关系数据库完整性规则对设计具有良好结构的数据库来说非常重要。许多(但不是所有)RDBMS 会强制自动执行完整性规则。

  • 实体完整性:所有主码值唯一,主码的任何部分不能为空。
  • 参照完整性:外码要么为空(当其不是该表主码的一部分),要么与相关表的主码值相匹配(所有非空外码值必须是相关表中已存在的主码值)。

4. 索引

在关系数据库中,索引(Index)是一种用于逻辑访问表中元组的有序组织的数据结构。在任何情况下,索引都是用来快速定位所需对象的位置。索引是由索引码(Index Key)和一组指针(Point)组成。实际上,索引码是索引的参考点。更正式地,索引是一种码和指针的有序组织。每个索引码都指向以码标识的数据的位置。

如下 PAINTING 表,如果没有索引,则必须逐行检查 PAINTING 表,检查每行的 PAINTER_NUM 是否与所要查找画家的 PAINTER_NUM 相同。然而,如果以 PAINTER_NUM 作为索引码对 PAINTER 表建立了索引,则只需在索引中查找对应的 PAINTER_NUM 及包含的指针。

从上图可以看出,第一个 PAINTER_NUM 索引码值 123 可在 PAINTING 表的第 1、2 和 4 个记录中找到,而第二个 PAINTER_NUM 索引码值 126 可在 PAINTING 表的第 3 和 5 个记录中找到。

索引的用途:

  • 用于高效检索数据;
  • 用于检索按特定属性或属性集排序的数据。例如,如果在客户的姓上建立了索引,则可按客户的字母顺序检索数据。同时,索引码可以由一个或多个属性组成;

在 DBMS 中,索引对主码的实现也起着重要作用。当定义一张表的主码时,DBMS 自动对声明的主码列创建唯一索引。唯一索引(Unique Index)是指只有一个指针值与索引码相对应的索引。一个表可以拥有很多索引,但是每个索引只与一张表相关。索引码可以包含多个属性(复合索引)。

需要创建哪些索引:

  • 对于查询频率高的字段创建索引。如果某个字段经常用来做查询条件,那么该字段的查询速度会影响整个表的查询速度。因此,为这样的字段建立索引,可以提高这个表的查询速度。
  • 为经常需要排序、分组和联合操作的字段建立索引。经常需要 order by、group by、distinct 和 union 等操作的字段,排序操作会浪费很多时间,如果为其建立索引,可以有效地避免排序操作。(索引本身就是会排序的,所以不需要额外的 order by 一次)

索引数目不宜太多:

  • 每创建一个索引都会占用相应的磁盘空间,索引越多,需要的磁盘空间越大;
  • 索引过多会导致 insert、update、delete 语句的执行效率降低;

5. 关系集合操作

  • 并(UNION):用于将两张表的所有行结合在一起,但不包括重复行。该操作要求参与运算的表必须具有相同的属性特征(即相同的列和域)。当两个或更多的表拥有相同的数量的列,且这些列都有相同的名称和相同(或相容)的域时,则称它们并相容。
  • 交(INTERSECT):用于产生同时在两个表中出现的行。与 UNION 操作一样,参与 INTERSECT 运算的表必须是“并相容”的。如果一个表中的属性是数值型而另一个表中的属性是字符型,则不能进行 INTERSECT 操作。
  • 差(DIFFERENCE):用于产生一张表中存在但另一张表中不存在的所有行,即用一张表“减去”另一张表。与 UNION 操作一样,参与 DIFFERENCE 运算的表必须是“并相容”的。
  • 积(PRODUCT):笛卡尔积,用于产生两张表中所有行的可能元组对。
  • 选择(SELECT):用于产生表中满足给定条件的所有行。SELECT 既可用来列出表中所有行,也可产生满足特定规则的行。换言之,SELECT 操作的结果是表的水平子集。
  • 投影(PROJECT):用于产生所有选定属性的值。换言之,PROJECT 产生表的垂直子集。
  • 连接(JOIN):用于对两个或更多表中的信息进行组合。JOIN 操作体现了关系数据库的强大能力,它能将各个独立的表通过共同属性实现互相连接。
  • 除(DIVIDE):用单列表(如列 a)作为除数,2 列表(如列 a 和 b)作为被除数。该操作要求两个表必须拥有共同的列(如列 a)。DIVIDE 操作的输出是单独的一列。

外连接:不仅保留向匹配的全部元组对,而且保留不能匹配的元组,并将其他表的不匹配值置为空值。

  • 左外连接:产生结果包含了左侧表的所有行。
  • 右外连接:产生的结果包含右侧表的所有行。

6. 关系数据库表联系

联系可以分为一对一(1:1)、一对多(1:M)和多对多(M:N 或 M:M)3 种类型。

  • 1:M 联系是理想的关系建模。因此,这种联系类型在关系数据库设计中最常见。在关系模式中一对多(1:M)联系非常容易实现,只需将“一”表的主码放入“多”表中作为外码即可。
  • 1:1 联系在关系数据设计中比较少见。在 1:1 联系中,一个实体集中的实体只与另一个实体集的一个实体相关联,反之亦然。一对一的联系存在有时意味着没有正确定义,两个实体可能实际上应属于同一张表。只有在比较特殊的情况下才使用

关系模型不能直接支持多对多(M:N)联系。然而,M:N 联系可以通过创建一个新的实体、并将该实体与原先两个实体分别建立 1:M 联系来实现。

可以通过创建一个复合实体以避免多对多(M:N)联系。复合实体也称桥接实体或联合实体。由于复合表用于与 M:N 联系中的原表进行连接,所以复合实体应至少报货外码,即原表的主码。在定义复合表的主码时,数据库设计人员有两种选择:使用外码的组合或创建一个新的主码。

7. 数据冗余

正确使用外码是控制数据冗余的关键。虽然外码无法完全消除数据冗余(因为外码值重复多次),但是正确使用外码可以将数据冗余最小化,从而尽可能减少出现数据异常的可能。数据库设计人员必须协调好 3 个相互矛盾的需求:设计简洁、处理速度和信息需求。正确的数据仓库设计要求仔细定义和控制数据冗余。但是,无论如何描述数据冗余,都需要采取正确的措施及认真控制才能减低其产生破坏的可能性。

猜你喜欢

转载自blog.csdn.net/dilixinxixitong2009/article/details/79973119
今日推荐