《SQL学习指南(第2版)(修订版)》——1.1 数据库简介

    xiaoxiao2024-03-28  13

    本节书摘来自异步社区出版社《SQL学习指南(第2版)(修订版)》一书中的第1章,第1.1节,作者: 【美】Alan Beaulieu,更多章节内容可以访问云栖社区“异步社区”公众号查看。

    1.1 数据库简介

    SQL学习指南(第2版)(修订版)“数据库”是指一组相关信息的集合。例如,电话簿就可以被视为包含某地区所有居民的姓名、电话号码、地址等信息的数据库。尽管电话簿可能是一个最为普及和常用的数据库,但它仍有不少缺点,比如:

    查找某人的电话号码相当费时,特别是在电话簿包含了海量条目时;电话簿只是根据姓名来索引,因此对于根据特定地址查找居民姓名就无能为力了;当电话簿被打印后,随着该地区居民的流动、更改电话号码或住址等行为不断发生,电话簿上的信息也变得越来越不准确。电话簿的这些缺陷同样存在于任何人工编制的数据存储系统,比如存放在档案柜的病历等。由于这些纸质数据库不方便,因此最早的计算机应用之一就是开发数据库系统,即通过计算机来存储和检索数据的机制。因为数据库系统通过电子而不是纸质方式来存储数据,所以它可以更快速地检索数据、以多种方式索引数据以及为其用户群提供最新的信息。

    早期的数据库系统将被管理的数据存储在磁带上。一般情况下磁带的数量比磁带机要多得多,因此在请求数据时需要技术人员手动装卸磁带。同时由于那个时代的计算机内存很小,通常对同一数据的并发请求必须多次读取磁带,降低了使用效率。因此尽管这些数据库系统相对于纸质数据库有了显著的进步,但与今天的数据库技术相比仍有相当遥远的差距。(现代数据库系统能够利用海量快速的磁盘驱动器来管理太字节级的数据,在高速内存中存放数十吉字节的数据。)

    1.1.1 非关系数据库

    提示本小节讨论早期非关系数据库的背景信息,如果读者急于学习SQL,可以跳过下面几页,直接阅读下一章节。在计算机数据库发展的前几十年里,数据以各种不同的方式存储并展现给用户。例如,在层次数据库系统中,以一个或多个树形结构来表示数据。图1-1显示了以树形结构表示的George Blake和Sue Smith的银行账户数据。

    George和Sue的数据树都包含了各自的账户以及交易信息。层次数据库系统提供了定位客户信息树的工具,并能够遍历此树找到所需要的账户或交易数据。树中的每个节点都具有0个或1个父节点,以及0个、1个或多个子节点。这种设置被称为单根层次结构(single-parent hierarchy)。

    另一种管理数据的方式是网状数据库系统,它表现为多个记录集合,集合之间通过链接来定义不同记录间的关系。图1-2显示了使用此系统表示的George和Sue的账户信息。

    在此系统中,为了查找Sue的MoneyMkt账户上的交易信息,需要执行下面的步骤:

    1. 查找Sue Smith的客户记录;

    2. 通过链接从Sue Smith的客户记录找到其账户列表;

    3. 遍历账户列表直至找到MoneyMkt账户;

    4. 通过链接从MoneyMkt账户找到其交易列表。

    网状数据库系统的有趣特性体现在图1-2中最右侧的products记录。注意每个product记录(Checking、Savings等)都指向一个account记录列表,以指定这些账户记录的产品类型。因此account记录可以通过多个入口进行访问(customer记录或product记录),这使得网状数据库具有多根层次的特点。

    层次和网状数据库仍然存在,尽管主要在大型机领域中使用。此外,层次数据库系统与可扩展标记语言(XML)相结合,在目录服务方面获得了新的应用,比如Microsoft公司的Active Directory和Red Hat的Directory Server。然而,从20世纪70年代开始,一种新的表示数据的方式逐步扎根并获得发展,这种方式更为严谨,且易于理解和实现。

    1.1.2 关系模型

    1970年,IBM研究院的E.F.Codd博士发表了一篇名为“大型共享数据银行的数据关系模型”的论文,提出使用表集合来表示数据,但相关条目之间并不使用指针来导航,而是借助冗余数据来链接不同表中的记录。图1-3显示了此方法所表示的George和Sue的账户信息。

    图1-3中包含了4个记录表:Customer、Product、Account和Transaction。首先查看图中顶部的Customer表,其中具有3列:cust_id(其中包含客户的ID号)、fname(其中包含客户的名字)和lname(其中包含客户的姓氏)。Customer表中包含了两个记录行,分别为Georage Blake和Sue Smith的数据。在不同的数据库管理服务器中,记录表可包含的最大列数是有差异的,但通常这个数目足够大而不需要为此担心(比如Microsoft的SQL Server允许每张表可以最多具有1024列)。表中数据行的数目通常只是受到物理设备(磁盘空间大小)和可维护性(在表中记录数在到达多大规模之后仍能保持易用性)的限制,而数据库管理服务器一般不对此进行限制。

    关系数据库中的每张表都包含一项作为每行唯一标识的信息(主键),它与其他信息一起构成了对条目的完整描述。对于Customer表,cust_id列为每个顾客保存了不同的编号。例如,George Blake可以由顾客 ID#1来唯一标识,其他顾客则永远不会被赋予此标识符。因此在Customer表中,不再需要其他信息来定位George Blake的数据。

    提示每种数据库服务器都提供用于产生一组作为主键值的唯一数字的机制,因此用户不需要为哪些数字已被赋予为主键而操心。当然也可以选择联合使用fname和lname两列作为主键(包含两列或多列的主键通常被称为复合主键),实际上,在银行账户中很可能会出现两个或多个人具有完全相同的姓氏和名字。因此,选择cust_id列专门用于Customer表的主键是更合适的做法。

    提示在本例中,选择fname/lname作为主键,称之为自然主键;使用cust_id作为主键,则称为逻辑主键。使用哪一种主键更好一直是悬而未决的热门讨论问题,但在本例中的选择是显而易见的,因为人们的姓名可能发生改变(比如某人结婚后使用其配偶的姓氏),而主键列在被赋值后是绝不允许被修改的。一些表中还包含了导航到其他表的信息,即前文提到的“冗余数据”。举例来说,Account表中的cust_id列,它包含了使用该账户的顾客的唯一性标识,而product_id列则包含了该账户所关联产品的唯一性标识。这些列被称为外键,用于作为账户信息网络结构中的各实体之间的连线。如果需要查询某个账户所有者的相关信息,则需要获取cust_id列的值,并使用它在Customer表中查找相应的行(在关系数据库术语中,此过程被称为连接(join),在第3章基本查询对此进行了介绍,并在第5章和第10章进行了更深入的讨论)。

    也许多次存储同样的信息是一种浪费的做法,但是某些情况下使用冗余数据能够更清晰地体现关系模型。例如,在Account表中包含一个该账户所有者的唯一标识符是合适的,如果在Account表中再增加顾客的fname/lname列就不太恰当了,这会使数据库中的数据不再可靠。因为放置该数据(顾客的姓/名)的地方应当是Customer表,并且该表中只有cust_id列才适合在其他表中被引用。此外,在一列中包含多条信息也是不合适的,比如使用name列同时包含顾客的姓和名,或者使用address列包含街道、城市、省以及邮政编码等信息。数据库设计精化过程的主要目标就是保证每条独立的信息只存放在一个地方(外键除外),称为规范化。

    返回到图1-3中的4个表,或许你会疑惑如何使用这些表来查找George Blake在他的checking账户上的交易信息。首先,在Customer表中找到George Blake的唯一性主键。然后,在Account表中找到cust_id列等于George的唯一性标识符,并通过Product_id匹配Product表中name列为“Checking”的那些行。最后,通过匹配Account表的唯一性标识account_id列来定位Transaction表中相对应的行。这些看起来有些复杂,但你很快就会发现,在SQL语言中,使用一个命令就足以完成这些任务了。

    1.1.3 一些术语

    在前面已经介绍了一些新的术语,下面介绍一些正式的定义,表1-1显示了本书余下部分所使用术语的定义。

    本文仅用于学习和交流目的,不代表异步社区观点。非商业转载请注明作译者、出处,并保留本文的原始链接。

    相关资源:SQL学习指南(第二版)
    最新回复(0)