DB2 培训
DB2 逻辑组成图
DB2 数据库由一组对象组成
包含许多下面列出的物理和逻辑对象:
– 表、视图、索引和模式
– 锁、触发器、存储过程和包
– 缓冲池、日志文件和表空间
在以上对象中,有些(如表或视图)帮助确定数据是如何组
织的。
另一些对象(如表空间)引用数据库的物理实现。
剩下的一些对象(如缓冲池和其它内存对象)则仅处理如何
管理数据库性能。
DB2 存储模型
用户处理的实际数据位于表中
表本身位于表空间中。
表空间被用作数据库和包含实际表数据的容器对象之间
的一层。
表空间可包含多个表。
容器是物理存储设备。可以用目录名、设备名或文件名
来标识它。
一个容器分配给一个表空间。一个表空间可以跨越多个
容器。
DB2 存储模型
表、索引、长字段和表空间
表、索引、长字段(有时称为二进制大对象或 BLOB)
是在 DB2 数据库内创建的对象这些对象被映射到表
空间,而表空间本身则被映射到物理磁盘存储器。
表是一个无序的数据记录集。它由列和行构成,通常称
之为记录。
索引是与单个表相关联的物理对象。索引用来在表中强
制实施唯一性(也就是说,确保没有重复值),以及
在检索信息时改进性能。
长字段(或 BLOB)是表内的一种数据类型。这种数据
类型通常由非结构化数据(图像、文档和音频文件)
构成,并且包含数量极大的信息。在表内存储这种数
据会导致删除、插入和操作这些对象时的过度开销。
所以并不直接将它们存储在表的行中。
DMS 和 SMS 表空间
表空间是数据库和存储在该数据库中的表之间的逻辑层。
表空间在数据库内创建,表则在表空间内创建。
DB2 支持两种表空间:
– 系统管理的空间(System-Managed Space,SMS):
这里,操作系统的文件系统管理器分配并管理空间,其中表
是缺省表空间类型。
– 数据库管理的空间(Database-Managed Space,
DMS):这里,数据库管理器控制存储空间。这种表空间实
质上是特殊用途文件系统的实现,旨在最好地满足数据库管
理器的需要。
SMS 表空间需要的维护很少。然而,SMS 表空间提供
的优化选项较少,并且性能也许不及 DMS 表空间。
结构化查询语言(SQL)
大多数 SQL 语句包含一个或多个下列语言元素:
– 字符:单字节字符可以是一个字母)、一个数字或一个特殊
字符
– 标记:标记是一个或多个字符的序列。标记不能包含空格,
除非它是定界标识符或字符串常量。
– 标识符:SQL 标识符是用于构成名称的标记。
– 数据类型:值的数据类型决定了 DB2 如何解释该值。DB2
支持许多内置数据类型,也支持用户定义的数据类型
– 常量:常量指定一个值。
– 函数:函数是一组输入数据值和一组结果值之间的关系。数
据库函数可以是内置的,也可以是用户定义的。
– 表达式:表达式指定一个值。字符串表达式、算术表达式和
条件表达式都可以用于根据对一个或多个条件的求值指定一
个特定结果。
– 断言:断言指定了一个条件,对于给定的行或组这个条件可
能是真(true)、假(false)或者未知(unknown)。断言
有一些子类型:
• 基本断言对两个值进行比较(例如,x > y)。
• BETWEEN 断言把一个值同某一范围内的值进行比较。
• EXISTS 断言测试某些行的存在性。
• IN 断言把一个或多个值同一个值的集合进行比较。
• LIKE 断言搜索具有某种模式的字符串。
• NULL 断言测试空值。
专用寄存器
专用寄存器是数据库管理器为应用程序进程定义的存储
区,用于存储可以在 SQL 语句中引用的信息。目前,
DB2 通用数据库支持以下专用寄存器:
CLIENT ACCTNG CURRENT MAINTAINED TABLE
TYPES FOR OPTIMIZATION
CLIENT APPLNAME CURRENT PATH
CLIENT USERID CURRENT QUERY PTIMIZATION
CLIENT
WRKSTNNAME
CURRENT REFRESH AGE
CURRENT DATE CURRENT SCHEMA
专用寄存器
CURRENT
DBPARTITIONNUM
CURRENT SERVER
CURRENT DEFAULT
TRANSFORM GROUP
CURRENT TIME
CURRENT DEGREE CURRENT TIMESTAMP
CURRENT EXPLAIN
MODE
CURRENT TIMEZONE
CURRENT EXPLAIN
SNAPSHOT
USER
专用寄存器
为了要说明专用寄存器多么有用,请考虑一下 SALES
表,其中有一列,列名是 Sales_Date。下面的语句
向 SALES 表中插入一个新行,把销售日期设置成
CURRENT DATE 专用寄存器的值:
INSERT INTO sales (sales_date,
sales_person, region, sales) VALUES
(CURRENT DATE, 'SMITH', 'Manitoba',
100)
数据控制语言(DCL)
模式
模式是命名对象(如表、视图、触发器和函数)的集合。
模式提供了对象在数据库中的逻辑分类。对象名由两
部分组成,模式名用作第一部分。例如,考虑名称
。在这个示例中,STAFF 表的全限定
名称包括模式名 SMITH 以使其同其它任何在系统目
录中被命名为 STAFF 的表区分开来。
模式本身就是一个数据库对象。可以使用 CREATE
SCHEMA 语句显式创建模式;也可以在创建另一个对
象时隐式创建模式。
模式有与之相关联的特权。这允许模式所有者可以控制
哪些用户有特权在模式中创建、修改和删除对象。
数据定义语言(DDL)
CREATE 语句用于创建数据库对象,包括:
– 缓冲池(Buffer pool)
– 事件监控程序(Event monitor)
– 函数(Function)
– 索引(Index)
– 模式(Schema)
– 存储过程(Stored procedure)
– 表(Table)
– 表空间(Table space)
– 触发器(Trigger)
– 视图(View)
每当您创建数据库对象时,都会更新系统目录。
请考虑一下 CREATE TABLE示例:
CREATE TABLE org ( deptnumb SMALLINT
NOT NULL, deptname VARCHAR(14), manager
SMALLINT, division VARCHAR(10),
location VARCHAR(13) )
使用 DECLARE 语句生成新的数据库对象
DECLARE 语句与 CREATE 语句是类似的,只有一点
例外,用它所创建的是只能在数据库连接期间存在的
临时表。
当您要用到中间结果时,临时表挺有用的。
当您声明临时表时,不会更新系统目录。
例如:
DECLARE GLOBAL TEMPORARY TABLE
LIKE employee ON COMMIT
PRESERVE ROWS NOT LOGGED IN mytempspace
在这个示例中,DECLARE GLOBAL TEMPORARY
TABLE 语句被用来声明一个临时表,表名是 TEMP1
,位于用户现有的一个名叫 MYTEMPSPACE 的临时
表空间。每当处理 COMMIT 语句时,临时表中的行
就会被保留下来(不会被删除)。最后,对临时表所
做的更改不会记入日志。
临时表必须由模式名 SESSION 显式(否则将隐式)限
定,因为每个定义声明过的表的会话对该临时表都有
自己的(可能是唯一的)描述。
数据操作语言(DML)
SELECT 语句用于检索表或视图数据。要限制结果集中
的行数,请使用 FETCH FIRST 子句。使用
DISTINCT 子句来消除结果集中重复的行。
使用 WHERE 子句指定若干选择条件或搜索条件来在表
或视图中选择某些特定行。搜索条件由一个或多个断
言组成。在构造搜索条件时,请务必要:
– 只对数值型数据类型应用算术运算
– 只在兼容的数据类型间进行比较
– 将字符值括在单引号之内
– 完全按字符在数据库内的值指定字符值
使用集合运算符把两个或两个以上的查询合并成一个查询
您可以使用集合运算符 UNION、EXCEPT 或
INTERSECT 把两个或两个以上的查询合并成一个查询。
集合运算符将处理查询结果、去掉重复结果并返回最终
结果集。
– UNION 集合运算符会把两个或两个以上其它结果表合并生成一
个结果表。
– EXCEPT 集合运算符生成一个结果表时,把第一个查询返回的
所有行包括在内,但不计第二个以及其后的所有查询。
– INTERSECT 集合运算符提供只包括由所有查询都返回的行来
生成一个结果表。
SQL存储过程
SQL 过程是一个存储过程,它的主体是用 SQL 编写的。
主体包含了 SQL 过程的逻辑。它可以包括变量声明、
条件处理、控制流语句和 DML。可以在一条复合语句
中指定多条 SQL 语句,该复合语句将这几条语句组合
成一个可执行块。
当成功调用 CREATE PROCEDURE (SQL) 语句(该语
句用应用程序服务器定义 SQL 过程)时,就创建了一
个 SQL 过程。SQL 过程是定义那些每当需要时就可
以调用的更复杂的查询或任务的一种便捷方式。以下
步骤将创建一个命令行处理器(command-line
processor,CLP)脚本(名为 ),
该脚本将创建一个简单的 SQL 过程:
1. 连接到 SAMPLE 数据库。
2. 发出以下命令:
db2 -td@ -vf
该 db2 命令指定 -td 选项标志(该标志告知命令行
处理器定义并使用 @ 作为语句终止符)、-v 选项标
志(该标志告知命令行处理器将命令文本回显到标
准输出)和 -f 选项标志(该标志告知命令行处理器
从指定的文件(而不是标准输入)读取命令输入)。
CREATE PROCEDURE sales_status
(IN quota INTEGER, OUT sql_state
CHAR(5))
DYNAMIC RESULT SETS 1
LANGUAGE SQL
BEGIN
DECLARE SQLSTATE CHAR(5);
DECLARE rs CURSOR WITH RETURN FOR SELECT
sales_person, SUM(sales) AS total_sales
FROM sales GROUP BY sales_person HAVING
SUM(sales) > quota;
OPEN rs;
SET sql_state = SQLSTATE;
END @
这个名为 SALES_STATUS 的过程接受名为 quota 的
输入参数并返回名为 sql_state 的输出参数。该过程
主体包含了一条 SELECT 语句,该语句返回每个销售
总量超过指定配额的销售人员的姓名和销售总量。
SQL 过程的参数列表可以不指定任何参数,也可以指定
多个参数,每个参数可以是以下三种可能的类型之一:
– IN 参数将一个输入值传递到 SQL 过程;在过程主体中不能修改这
个值。
– OUT 参数从 SQL 过程返回一个输出值。
– INOUT 参数将一个输入值传递到 SQL 过程,并从该过程返回一个
输出值。
SQL 过程可以不返回结果集,也可以返回多个结果集。
在我们的示例中,SALES_STATUS 过程返回一个结
果集。这是通过以下步骤完成的:
1. 在 DYNAMIC RESULT SETS 子句中声明 SQL 过
程要返回的结果集的数量。
2. 对于将要返回的每个结果集,在过程主体中(使用
WITH RETURN FOR 子句)声明一个游标
(cursor)。游标是一个命名的控制结构,应用程
序用它来指向一个有序行集合中的某一特定行。游
标用于从集合中检索行。
3. 打开要返回的每个结果集的游标。
4. 当 SQL 过程返回时,仍使游标保持打开。
在 SQL 过程主体开始处必须声明变量。要声明变量,必
须为该变量指定一个唯一的标识符、指定该变量的
SQL 数据类型,并且可选地给该变量赋予一个初始
值。
我们的样本 SQL 过程中的 SET 子句是一个控制流子句
的示例。以下控制流语句、结构和子句可以用于 SQL
过程主体中的条件处理:
– CASE 结构根据对一个或多个条件的求值来选择执行路径。
– FOR 结构对表的每一行执行代码块。
– GET DIAGNOSTICS 语句将关于前一条 SQL 语句的信息返回到
SQL 变量中。
– GOTO 语句将控制权转移到带标签的块(一段由一条或多条语句组
成的代码,并由一个唯一的、后面带冒号的 SQL 名称标识)。
– IF 结构根据条件的求值来选择执行路径。如果其它条件为假
(false)的话,ELSEIF 和 ELSE 子句使您可以分支或指定缺省操
作。
– ITERATE 子句将控制流传递到带标签的循环的开始处。
– LEAVE 子句将程序控制权转移到循环或代码块的外面。
– LOOP 子句会多次执行某个代码块,直到 LEAVE、ITERATE 或
GOTO 语句将控制权转移到循环外面。
– REPEAT 子句会一直执行某个代码块,直到某个指定的条件返回真
(true)为止。
– RETURN 子句将控制权从 SQL 过程返回到调用程序。
– SET 子句将一个值赋值给输出参数或 SQL 变量。
– 当所指定的条件是真时,WHILE 子句会反复执行某个代码块。
可以使用 SQL CALL 语句从 DB2 命令行调用 SQL 过
程。必须在系统目录中定义了要被调用的过程。
1. 连接到 SAMPLE 数据库。
2. 发出以下语句:
db2 “CALL sales_status (25, ?) “
在本例中,输入参数 quota 的值 25 和作为输出参数
sql_state 的问号(?)占位符被传递到 SQL 过程。
该过程返回每个销售总量超过指定配额(25)的销售人
员的姓名和销售总量。
并发性和隔离级
在多用户数据库环境下,多个事务可以同步执行,并且
每个事务都有可能与其它正在运行的事务发生冲突。
DB2 通用数据库尝试用来强制执行并发性的方法之一是
通过使用隔离级别,它决定在第一个事务访问数据时,
如何对其它事务锁定或隔离该事务所使用的数据。
DB2 通用数据库使用下列隔离级别来强制执行并发性:
– 可重复的读(Repeatable Read)
– 读稳定性(Read Stability)
– 游标稳定性(Cursor Stability)
– 未提交的读(Uncommitted Read)
指定隔离级别
尽管隔离级别是控制如何为事务锁定资源的,但实际上是在应用程
序级别指定它们的。对于嵌入式 SQL 应用程序,是在预编译时
或将应用程序绑定到数据库时指定要使用的隔离级别。在大多数
情况下,应用程序的隔离级别是用受支持的编译语言(如 C 或
C++)编写的,通过 PRECOMPILE PROGRAM 和 BIND 命令
/API 的 ISOLATION 选项来设置隔离级别。对于调用级接口
(CLI)应用程序,所用的隔离级别是在应用程序运行时通过调
用指定了 SQL_ATTR_TXN_ISOLATION 连接属性的
SQLSetConnectAttr() 函数进行设置的。也可以通过指定
TXNISOLATION 关键字的值来设置 CLI 应用程序的隔离级别,
该关键字位于 配置文件中。对于 JDBC 和 SQLJ 应用
程序,隔离级别是在应用程序运行时通过调用驻留在 连
接接口中的 setTransactionIsolation() 方法设置的。
当没有指定隔离级别时,则缺省地使用“游标稳定性”隔离级别。
可以指定从 CLP 运行的命令和脚本所用的隔离级别,在建立与数据
库的连接之前在 CLP 中执行 CHANGE ISOLATION 命令设置的。
锁
锁是一种用来将数据资源与单个事务关联起来的机制,
其用途是当某个资源与拥有它的事务关联在一起时,
控制其它事务如何与该资源交互。如果一个事务尝试
访问数据资源的方式与另一个事务所持有的锁不兼容,
则该事务必须等待,直到拥有锁的事务终止为止。
所有的锁都需要存储空间;因为可用空间并不是无限的,
所以 DB2 数据库管理器必须限制锁可以使用的空间。
为了防止特定数据库代理超过已建立的锁空间限制,
当获取的(任意类型的)锁过多时,会自动执行称为
锁升级的进程。锁升级是一种转换,它将同一表内几
个单独的行级锁转换成一个单独的表级锁。因为锁定
升级是在内部处理的,所以唯一可从外部检测到的结
果可能只是对一个和多个表的并发访问减少了。
死锁
有时两个或更多个事务对锁的争用会引起称为死锁的情况。
当死锁状况发生时,除非某些外部代理采取行动,否则所
涉及的所有事务将无限期地等待释放锁。DB2 通用数据
库用于处理死锁的工具是称为死锁检测器的异步系统后
台进程。死锁检测器在大多数时间处于休眠状态,但会
在预置的时间间隔被“唤醒”,以确定是否存在死锁状
况。如果死锁检测器在锁定子系统中发现死锁,则选择
死锁涉及的一个事务、终止并回滚它。
锁超时
任何时候当一个事务在特定数据资源(例如,表或行)上持有锁时,
直到持有锁的事务终止并释放它所获取的所有锁之前,其它事务
对该资源的访问都可能被拒绝。如果没有某种适当的锁超时检测
机制,则事务可能无限期地等待锁的释放。例如,有可能出现这
种情况:一个事务在等待另一个用户的应用程序所持有的锁被释
放,而该用户离开了他(或她)的工作站,但忘了执行一些允许
应用程序终止拥有锁的事务的交互。显然,此类情况会导致极差
的应用程序性能。要避免发生此类情况时阻碍其它应用程序的执
行,可以在数据库的配置文件中指定锁超时值(通过 locktimeout
数据库配置参数)。使用之后,该参数就控制任何事务将等待获
取所请求的锁的时间。如果在指定的时间间隔过去之后还未获得
想要的锁,则等待的应用程序接收一个错误,并回滚请求该锁的
事务。分布式事务应用程序环境特别容易产生此类超时;可以通
过使用锁超时避免它们。
DB2 数据库管理器总是尝试获取行级锁。但是,可以通
过执行特殊形式的 ALTER TABLE 语句来修改这种行
为,如下所示:
ALTER TABLE [TableName] LOCKSIZE TABLE
其中 TableName 标识一个现有表的名称,所有事务在
访问它时都要获取表级锁。
也可以通过执行 LOCK TABLE 语句,强制 DB2 数据库
管理器为特定事务在表上获取表级锁,如下所示:
LOCK TABLE [TableName] IN [SHARE |
EXCLUSIVE] MODE
如果在执行这个语句时指定了共享(SHARE)模式,
就会获得一个允许其它事务读取(但不能更改)存储
在其中的数据的表级锁;如果执行时指定了互斥
(EXCLUSIVE)模式,就会获得一个不允许其它事务
读取或修改存储在表中的数据的表级锁。
实用工具Load
LOAD 实用程序是一种用数据来填充表的方法。经过格
式化的页被直接写入数据库。这种机制允许进行比
IMPORT 实用程序更有效的数据移动。不过,LOAD
实用程序不执行某些操作,如引用或表约束检查以及
触发器调用。
以下是 LOAD 命令的核心;
LOAD FROM input_source OF input_type
MESSAGES message_file [ INSERT |
REPLACE | TERMINATE | RESTART ] INTO
target_tablename
LOAD 的源输入的格式可以是 DEL、ASC、PC/IXF 或
CURSOR。游标是从 SELECT 语句返回的结果集。
LOAD 可以以四种不同方式执行:
– INSERT 方式将输入数据添加到表中,不更改现有表数据。
– REPLACE 方式从表中删除全部现有数据,然后用输入数据填充该
表。很有用的清空表方式:
load from /dev/null of del replace into tablename
– TERMINATE 方式终止装入操作,然后回滚到装入操作的起始点。
一个例外是:如果指定了 REPLACE 方式,那么表将会被截断。
– RESTART 方式用于重新启动以前中断的装入。它将自动从上一个
一致性点继续操作。
LOAD FROM OF IXF MESSAGES MODIFIED BY
DUMPFILE=c:\ TEMPFILES PATH d:\tmp INSERT
INTO employee FOR EXCEPTION mpexp
装入表期间,LOAD 实用程序会用互斥锁将它锁定。这是 ALLOW
NO ACCESS 选项的缺省行为。
检查装入操作的状态,还返回表状态:
LOAD QUERY TABLE table_name
ALLOW READ ACCESS 选项导致表在共享方式下被锁定。阅读器
可以访问表中已经存在的数据,却不能访问新的数据。正在装入
的数据要等到装入完成后才可获得。
DB2不会将与目标表定义不一致的输入数据装入表中。在装入阶段,
这样的数据会遭到拒绝,并被记录在消息文件中。在删除阶段,
LOAD 实用程序会删除那些违反任何唯一性约束的行。如果指定
了异常表,违规的行将插入该表。对于表可能定义的其它约束
(如引用完整性和检查约束),怎么办呢?LOAD 实用程序不检
查这些约束。表会被置于 CHECK PENDING 状态,这种状态迫
使您先手工检查数据完整性,然后才能访问表。
SET INTEGRITY FOR tablename IMMEDIATE CHECKED
使用开发中心开发存储过程
创建项目:
我们要做的第一件事是打开 DB2 Development
Center。选择 Start => Programs => IBM
DB2 => Development Tools =>
Development Center 调出 Development
Center Launchpad。
在 Open Project 窗口中,将项目命名为 JFitness 然后单击
OK。
接下来,我们需要将数据库连接关联到我们的项目。
继续,单击 Add Connection。
在 Add Database Connection 向导的下一个屏幕中,
应将连接类型指定为 Online。
在 Options 面板上,您可以将项目和 SQL Schema 或
SQL ID 关联在一起。我们在此不想进行这项操作,
因此请继续,单击 Next。
然后您需要提供一些有关数据库的信息,存储过程将应
用于该数据库。
在 Options 面板上,您可以将项目和 SQL Schema 或
SQL ID 关联在一起。我们在此不想进行这项操作,因此
请继续,单击 Next。
这时将向您提供有关数据库连接的摘要信息。如果所有
内容看来都是正确的,那么单击 Finish。
现在,我们将真正开始创建存储过程。使用 Launchpad
,您可以创建存储过程和 UDF(用户定义的函数)。选
择 Create Object。
指定存储过程类型
用模式 DB2Admin 创建我们正在创建的存储过程
单击 Statement 设置旁的“...”调出 SQL Statement
窗口。
生成 SQL 语句
通过它可以创建一些相当复杂的查询
指定合适的列
使内容可变
指定搜索条件
用 SQL Assist 完成工作
指定不返回结果集
指定 in 和 out 参数
指定创建和构建选项
复查摘要
确认工作
DB2常用命令
一、启动命令行处理器
$db2
出现提示:db2 =>
二、命令帮助
db2 =>? #列出所有命令
db2 =>? db2-command #列出具体命令的帮助
db2 =>? Sqlcode #列出sqlcode的对应提示
db2 =>? Sqlstate #列出sqlstate的对应提示
三、连接数据库
db2 => connect to db-name [User user-name Using pwd]
四、终止数据库连接
db2 => terminate
该命令终止数据库连接,并关闭CLP对话,如果一个
事务正在运行,它会被提交。
五、列出机器节点目录的内容
db2 => list node directory
六、列出机器数据库目录中的内容
db2 => list db directory