数据库编程第1章

第1章 数据库原理与访问

1.1 数据库基本原理

1.1.1 概述

数据库技术的发展历程

数据库是现代计算机应用的一个重要组成部分,是人们有效地进行数据存储、共享和处理的工具。

数据库系统的优势

数据库同文件相比,有以下优势:

首先,数据库中的数据是高度结构化的,不仅考虑数据项之间的关系,还考虑了记录类型之间的关系,从而反映出现实中的信息实体。

其次,数据库中的数据是面向系统而不是面向应用的,因此数据库的数据比文件系统的共享程度高,面向系统的另一个好处是信息结构稳定,易于扩展。

第三,数据库系统比文件系统有更高的独立性。为了实现这种独立性,数据库系统往往拥有比特定应用更多的数据,对于特定的应用只提供局部的逻辑结构,保持应用的逻辑独立性。

第四,数据库系统具有较好的数据安全性和一致性维护措施。数据库系统都具有特定的授权机制,防止非法用户的使用。在多用户操作的情况下,数据库可以进行良好的数据并发处理,维护数据的一致性。

最后,数据库对数据的存取不是以记录为单位的,可以仅操作记录的某些字段,方便了外部应用对数据的操纵。

数据库管理系统

数据库系统是一个多级结构,需要定义各级上的模式,这就需要一组软件提供相应的定义工具;数据库为了保证其中的数据安全和一致性,必须有一套软件来完成相应的控制和管理任务,这样的软件称为数据库管理系统,即DBMS。

DBMS的功能随着系统而异,但是通常情况下都包括如下几个方面的功能:

  • 数据库描述功能:定义数据库的全局逻辑结构(概念模式) 、局部逻辑结构(外模式)以及其它各种数据库对象。

  • 数据库管理功能:包括系统控制、数据存储以及更新管理、数据安全性与一致性维护。

  • 数据库查询和操作功能:能从数据库中检索信息或者改变信息。

  • 数据库建立与维护功能:包括数据写入、数据库重建、数据库结构维护、恢复以及系统性能监视等。

如果以内容来划分DBMS的组成,它应该包括下面三个部分:

  • 数据描述语言(DDL)以及它的解释程序。

  • 数据操纵语言(DML)以及它的解释程序。

  • 数据库管理例行程序。

1.1.2 桌面数据库

桌面数据库是一类数据库软件,这些数据库有时又被称为“ISAM数据库”,因为这些数据库都采用了ISAM(Inexed Sequential Access Method)文件。目前市场上的桌面数据库包括 MicrosoftAccess、MicrosoftFoxPro 和 BorlandParadox。

桌面数据库将元数据存放在自己的 ISAM 数据文件里,而这些数据文件都是可自描述的,使各种应用程序能够访问桌面数据库里的数据。桌面数据库一般都拥有自己的操作语言和数据类型,包括运行以其操作语言编写的程序的解释程序。可以采用桌面数据库语言来建立数据库应用程序,但是这些经过解释的数据库语言具有极大的局限性,难以建立完整的商业应用。

桌面数据库一般能够提供标准的数据库管理(DBMS)功能,例如数据定义、查询、安全以及维护等,为了提高记录查询速度,桌面数据库要数据增加索引,并使用ISAM。桌面数据库的ISAM文件可以通过局域网(LAN)供网络上的计算机访问,这统称为客户机/服务器(C/S)模式,但是通过LAN访问ISAM文件的能力和效率是有限的,当ISAM数据文件被通过LAN访问时,数据要在客户机上进行处理,所有数据和索引都必须从服务器端传送到客户机,造成了应用环境里数据吞吐量的急剧增长。因此说,桌面数据库是专门为个人计算机设计的,是个人计算机数据库应用软件开发的首选数据库。

1.1.3 对象数据库

最原始的数据库技术仅仅在数据文件里存储初始数据,即比特和字节,没有元数据的概念。桌面数据库和对象数据库则同时存放数据和元数据,使数据文件成为可自解释的。对象数据库则进一步在数据文件里存放操作数据的代码。

对象数据库一般都绑定在特定的编程语言上。C++的对象数据库直接支持C++语言的类型系统,可以使用C++对象数据库在数据库中存储C++类的实例。下面的代码使用C++对象数据库存放商品信息。

#include <string.h>

//Header file for the object database.
//Management Group object model
#include <odmg.h>

//Derive product class from d_object
//so that product can persist itself in the database
class Product : public d_object
{
public:
    int     iTypeNumber;
    char    szPName[96];
    double  dPrice;
private:
    d_Ref<Product> next;    //用于遍历数据库中的Product实例的指针
}

d_Database db;  //全局的对象数据库实例
const char db_name[] = "Product";

void main()
{
    db.open(db_name);   //打开Product对象数据库
    d_Transaction tx;   //创建一个处理事务并启动
    tx.begin();

    //在数据库里创建一个新的实例
    Product *product = new (&db, "Product") Product;
    product->iTypeNumber = 21;
    strcpy(product->szPName, "Refrigerator");
    product->dPrice = 2000;
    tx.Commit();    //将新创建的实例提交到对象数据库
    db.close();     //关闭对象数据库
}

代码开始部分包含一个 odmg.h 的头文件,该文件中包含了 d_Database 类的定义。 d_object 使一个C++基类,可以从该类派生新的类,实现特定数据的操作。Product 类即 d_object 类的派生类。类 Product 具有 d_Ref next 成员,d_Ref<>是对象数据库供应商提供的一个指针类,通过这个指针类实现对象的引用。

main 函数实现了对象数据库打开、Product实例的创建与数据赋值、对象提交和对象数据库关闭等操作,这些代码都不难理解。

C++ 类使我们能够对复杂实体及其关系进行建模,能够在数据库里存放复杂的C++类的实例。但是,对象数据库也有局限性,由于对象数据库同特定的语言紧密集成,所以不便于其它应用程序的访问。另外,在客户机/服务器环境下,对象数据库同桌面数据库一样,具有效率和吞吐量的限制,不能重复利用服务器的处理能力。

1.1.4 关系数据库服务器

关系数据库服务器在某些方面同桌面数据库类似,有自己的编程语言、解释程序和数据类型,也集成数据和元数据。但是关系数据库服务器提供了桌面数据库无法比拟的丰富功能、数据开放性、处理能力以及吞吐能力,同桌面数据库和对象数据库相比,关系数据服务器更适合于客户机/服务器体系结构。

关系数据库服务器可以充分利用高性能服务器的硬件资源,例如大量的RAM和高性能的磁盘子系统,将关系数据库服务器安装在RAID磁盘系统上,它会充分利用RAID驱动程序,提供交大的吞吐能力和可靠性。

关系数据库服务器也有自己的弱点。首先它要比桌面数据库和对象数据库昂贵,与特定商业应用的集成更难;同时可能对硬件有苛刻的要求,还要求数据库管理员定期对系统进行协调和维护。

尽管如此,大型的关系数据库服务器因为其高性能、稳定可靠等优势,成为当前大型商业应用的首选数据库。目前流行的关系数据库服务器有Oracle、SQL Server、DB2,这些系统各有千秋,需要根据不同的需求进行相应的选择。

1.1.5 选择适用的数据库

如何在众多的数据库中选择适合自己应用需求的一个呢?下面的指标值得参考:

  • 数据开放性。 其它过程或者应用程序在不访问数据库的源代码时,理解数据文件的能力。
  • 复杂数据类型。处理具有复杂数据实体和关系的应用程序的能力。
  • 支持的用户数量。多个线程、应用程序和用户同时访问数据的能力。
  • 性能。读写数据速度。
  • 可伸缩性与能力。随着数据量的增长,数据库依然保持良好性能的能力。
  • 提供基于集合的操作的能力。是否在其编程模型中提供了基于集合的操作。
  • 服务器对基于集合操作的支持。 在服务器端处理数据,而不必将数据传送到客户端进行处理的能力。
  • * 商业集成的方便性*。是否便于同商业应用程序的集成。
  • 数据校验与完整性。 数据库校验数据、确保数据完整性的能力。
  • 代码功能比。所编写的程序代码量与通过执行这些代码所能够获得的数据库能力之比。

1.2 数据库访问技术

1.2.1 概述

数据库是非常复杂的软件,编写程序通过某种数据库专用接口与其通信时非常复杂的工作。为此,产生了数据库的客户访问技术,即数据库访问技术。

数据库访问技术将数据库外部与其通信的过程抽象化,通过提供访问接口,简化了客户端访问数据库的过程。一个好的数据库访问接口就好像程序代码的放大镜,如图1-1所示。

目前供应商提供的数据库接口分为专用和通用两种。专用数据库接口具有很大的局限性,可伸缩性也比较差。通过的数据库接口提供了不同的、异构的数据库系统通信的统一接口,采用这种数据库接口可以通过编写一段代码实现对多种类型数据库的复杂操作,如图1-2所示。

数据库编程第1章_第1张图片

目前Windows系统上常见的数据库接口包括:

  • ODBC(开放数据库互连)
  • MFC(Microsoft基础类) ODBC类
  • DAO(数据访问对象)
  • RDO(远程数据对象)
  • OLE DB(对象链接嵌入数据库)
  • ADO(ActiveX数据对象)

以下对这些数据库接口作简单介绍。

1.2.2 ODBC API

ODBC 是80年代末90年代初出现的技术,它为编写关系数据库的客户软件提供了统一的接口。ODBC只提供单一的API,可用于处理不同数据库的客户应用程序。使用ODBC API的应用程序可以与任何具有ODBC驱动程序的关系数据库进行通信。

与其它数据库接口相比,ODBC API是比较底层的数据库接口,它在相对较低的层次上使客户应用程序可以配置并操作数据库。

由于ODBC为关系数据库提供了统一的接口,现在已经被广泛应用,并逐渐成为关系数据库接口的标准。

ODBC仅限于关系数据库,由于ODBC的关系型特性,很难使用ODBC与非关系数据源进行通信,例如对象数据库、网络目录服务、电子邮件存储等。

ODBC提供了ODBC驱动程序管理器(ODBC32.DLL)、一个输入库(ODBC32.LIB)和ODBC API函数说明的头文件。客户应用程序与输入框连接,以使用ODBC驱动程序管理器提供的函数。在运行时,ODBC驱动程序管理器调用ODBC驱动程序中的函数,实现对数据库的操作,ODBC API的体系结构如图1-3所示。

通过ODBC API操作数据库的数据库访问方法将在后面详细叙述。

1.2.3 ODBC的MFC类

ODBC 为关系数据库提供了统一的接口,但是ODBC API十分复杂。在Visual C++中,MFC提供了一些类,对ODBC进行了封装,以简化ODBC API的调用,这些MFC ODBC类使ODBC编程的复杂性大大降低。

MFC ODBC类在使用上比ODBC API容易,但是损失了ODBC API对底层的灵活控制。因此,MFC ODBC类属于高级数据库接口。

通过MFC ODBC类操作数据库的数据库访问方法将在后面详细叙述。

1.2.4 DAO 与 RDO

DAO,即Data Access Object的缩写,是一组Microsoft Access/Jet 数据库引擎的COM自动化接口。DAO直接与Access/Jet数据库通信,通过Ject数据库引擎,DAO也可以同其它数据库进行通信,如图1-4所示。

数据库编程第1章_第2张图片

DAO的基于COM的自动化接口提供了比基于函数的API更多的功能,DAO提供了一种数据库编程的对象模型。DAO的对象模型比一般的API更适合于面向对象的程序开发,将一组不关联的API函数集成到一个面向对象的应用程序里,一般要求开发人员必须编写自己的一组类来封装这些API函数。除了提供一组函数外,DAO还提供了连接数据库并对数据库进行操作的对象,这些DAO对象很容易集成到面向对象应用程序的源代码里。

此外,DAO还封装了Access数据库的结构单元,例如表、查询、索引等,这样,通过DAO,可以直接修改Access数据库的结构,而不必使用SQL的数据定义语言(DDL)的语句。

DAO提供了一种非常有用的数据库编程的对象模型,但是,从图1-4可以看出,操作涉及到了很多层的软件。DAO也提供了访问Oracle、SQL Server等大型数据库。当我们利用DAO访问这些数据库时,对数据库的素有调用以及输出的数据必须经过Access/Jet数据库引擎,这对于使用数据库服务器的应用程序来说,无疑是个严重的瓶颈。

DAO同ODBC相比更容易使用,但不能提供ODBC API所提供的底层控制,因此DAO也属于高层的数据库接口。

MFC对DAO的自动化接口做了进一步的封装,叫做MFC DAO类。这些MFC DAO类都使用前缀CDao。在后面,我们将介绍如何使用DAO自动化接口和MFC DAO类对数据进行操作。

RDO是Remote Data Object的缩写,最初是作为ODBC API的抽象,为Visual Basic程序员提供的编程对象,因此RDO与Visual Basic密切相关。由于RDO直接使用ODBC API对远程数据源进行操作,而不像DAO要经过Jet引擎。所以,RDO可以为使用关系数据库服务器的应用程序提供很好的性能。

通过在应用程序里插入RemoteData控件,RDO就可以与Visual C++一起配合使用。RemoteData控件是一个OLE Control,可以被约束到应用程序的界面上,可以通过使用RemoteData控件的方法实现对RDO函数的调用。

1.2.5 OLE DB与ADO

OLE DB对ODBC进行了两个方面的扩展:一是提供了一个数据库编程的OLE接口,即COM;二是提供了一个可用于关系型和非关系型数据源的接口。

OLE DB提供了COM接口。OLE是COM的最初的名字,即使出现了OLE DB,OLE仍然被认为是COM,而COM是微软组件技术的基础。

COM接口同传统的数据库接口相比,例如ODBC,有更好的健壮性和灵活性,具有很强的错误处理能力,能够同非关系型数据源进行通信。

与ODBC API一样,OLE DB也属于底层的数据编程接口,OLE DB结合了ODBC对关系型数据库的操作功能,并进行了扩展,可以访问非关系型数据库源。

利用OLE DB进行软件开发应该包括两类软件:OLE DB客户程序(Consumer)和OLE DB供应程序(Provider),如图1-5所示为OLE DB客户程序与供应程序之间的关系。

数据库编程第1章_第3张图片

OLE DB客户程序是使用OLE DB接口的应用程序。例如,采用C++编写的使用OLE DB连接数据库服务器的所有应用程序都是OLE DB客户程序。OLE DB供应程序是实现OLE DB接口并实际与数据库服务器通信的DLL。在功能上,OLE DB同ODBC驱动程序相同。不过OLE DB实现的是COM接口,而不是API接口。

OLE DB使我们可以访问任何带有OLE DB供应程序的数据源。这些数据源包括电子邮件存储、对象数据库、网络目录及其它非关系型数据存储。

OLE DB是Windows操作系统上数据库客户开发的未来发展模式,微软自己的开发也集中在OLE DB上,未来所有新的数据库技术也将适用于OLE DB。OLE DB的数据库编程技术将在本书第7章详细叙述。

ADO是ActiveX Data Object的缩写,它建立在OLE DB之上。ADO实际上是一个OLE DB供应程序,使用ADO的应用程序要间接地使用OLE DB。

ADO提供了一种数据库编程对象模型,类似于DAO的对象模型,但比DAO有更高的灵活性。ADO简化了OLE DB,属于高层的数据库接口。另外同OLE DB相比,能够使用ADO的编程语言更多。ADO提供了一个自动化接口,使VBScript和JavaScript等脚本语言可以使用ADO。本书第8章将对ADO的数据编程进行详细介绍。

1.3 数据库操纵语言SQL

SQL(structured Query Language)是目前关系数据库领域中主流查询语言。它不仅能够在单机环境下提供对数据库的各种操作访问,而且还能作为一种分布式数据库语言用于客户机/服务器模式数据库应用的开发。

对数据库来说,一个简单的数据获取要求被定义为一个查询,通常需要为此开发特定的查询语言。SQL的概念是1974年由Boyce和Chamberlin提出的,1986年成为一个ANSI标准,1987年成为ISO标准,目前它广泛应用于数据库管理系统里。

SQL是一种数据库编程语言,一个SQL查询至少包括以下3个元素:

  • 一个动词,它决定了操作的类型,例如SELECT。
  • 一个宾语,由它指定操作的目标,是一个或者多个字段,是一个或者多个表对象。
  • 一个介词短语,由它来决定操作的对象,是数据库的某个对象,例如一个表,或者一个视图。

一个SQL语句被传送给一个基于SQL的查询引擎,产生查询结果集,结果集以行和列的形式给出。

SQL语句由命令、从句、运算符和合计函数构成,这些元素组合起来形成语句,用于创建、更新和操作数据库。

1.3.1 SQL命令

SQL命令包括以下几种:

  • SELECT命令:用于在数据库中查找满足特定条件的记录,形成特定的查询结果集。这是所有SQL语句中最常使用的SQL命令。
  • CREATE命令:用于创建数据库的特定对象,如表、索引、视图。
  • DROP命令:用于删除数据库中的特定对象。
  • ALTER命令:用于调整数据库对象的结构。
  • INSERT命令:用于在数据库中向特定表添加一行记录。
  • DELETE命令:用于删除数据库中表的某些记录。
  • UPDATE命令:用于修改数据库中表的某些记录。

1.3.2 SQL从句

SQL使用从句来指定查询条件,SQL从句包括如下几种类型:

  • FROM从句:用于指定从其中选定记录的表的名称。
  • WHERE从句:用于指定所选定记录必须满足的条件。
  • GROUP BY从句:用于指定查询结果集按照特定的列分成不同的组。
  • HAVING 从句:用于说明每个组需要满足的条件,一般同GROUP BY从句一起使用。
  • ORDER BY从句:用于指定查询结果集按照特定的列排序。

1.3.3 SQL运算符

SQL使用的运算符主要有两类:逻辑运算符和比较运算符。

逻辑运算符

逻辑运算符通常出现在WHERE从句里,用于组合查询的条件。SQL语句中经常出现的逻辑运算符主要是如下三种:

  • AND:对条件表达式进行“与”操作
  • OR:对条件表达式进行“或”操作
  • NOT:对条件表达式进行“非”操作

比较运算符

标记运算符用于比较两个表达式的值,从而得到一个条件表达式,下面是常用的SQL比较运算符:

  • < : 小于
  • >
  • <=
  • >=
  • -
  • BETWEEN:指定值的范围
  • LIKE:用于模糊查询
  • IN:用于指定数据库中的记录

1.3.4 SQL 合计函数

使用合计函数可以对一组数据进行各种不同的统计,它返回用于一组记录的单一值。它能从许多不同行中搜索数据并将它们汇总为一个最终结果。下面是常用的SQL合计函数:

  • Avg:获得特定列中数据的平均值。
  • Count:获得特定的行的计数。
  • Sum:获得特定行集合里特定列的数据总和。
  • Max:获得特定列的最大值。
  • Min:获得特定列的最小值。

你可能感兴趣的:(编程,数据库,vc++)