分享

DB2 通用数据库定义的数据类型、表、视图和索引

 昵称8440196 2012-03-16
DB2 通用数据库定义的数据类型、表、视图和索引 [转贴 2008-04-24 17:15:07]  
我顶 字号:

这篇教程讨论了 DB2 通用数据库定义的数据类型、表、视图和索引。它说明了这些对象的功能,如何使用结构化查询语言(Structured Query Language,SQL)创建和操作它们以及如何在应用程序中使用它们。本教程是由六篇教程组成的文章系列的第五篇,可以用它来帮助您为 DB2 Fundamentals Certification(Exam 512)做准备。这篇教程的内容主要讨论“第 5 节. 数据库对象”中的目标。您可以在 http://www.ibm.com/certify/tests/obj512.shtml 上查看这些目标。在本教程中,您将学到:

  • DB2 提供的内置数据类型,以及定义一个表时要使用哪些内置数据类型高级数据类型的概念在 DB2 数据库中创建表、视图和索引唯一性约束、引用完整性约束和表检查约束以及如何使用这些约束如何使用视图限制对数据的访问
  • 索引的功能以及如何使用这些功能

不需要 DB2 通用数据库的副本就可以学完本教程。不过,您可以下载 IBM DB2 通用数据库企业版的一个试用版。

数据类型的类别

DB2 提供了丰富而又灵活的数据类型分类。DB2 提供了基本数据类型如 INTEGER、CHAR 和 DATE,同时它还为创建用户定义的数据类型提供了方便,这些用户定义的数据类型使得程序员能够创建适应目前复杂编程环境的复杂的、非传统的数据类型。选择使用哪种类型取决于将存储在列中的信息的类型和范围。内置数据类型的分类如下:

  • 数字型(Numeric)字符串型(String)日期时间型(Datetime)
  • 数据链接型(Datalink)

用户定义的数据类型分类如下:

  • 用户定义的单值类型用户定义的结构化类型
  • 用户定义的引用类型

数字型数据类型

字符串型数据类型

DB2 提供了几种数据类型用来存储字符数据或字符串。使用哪种数据类型取决于您要存储的字符串的大小以及字符串中是什么数据。下列数据类型用于存储单字节字符串:

  • CHAR
    CHAR 或 CHARACTER 用于存储固定长度的字符串,长度最大为 254 个字节。例如,部件标识符可以用特定长度 8 个字符来定义,并因此在数据库中存储为列 CHAR(8)。
  • VARCHAR
    VARCHAR 用于存储可变长度的字符串。例如,部件描述可能由于部件的不同而长度相异,可以将它们定义为 VARCHAR(100)。VARCHAR 列的最大长度是 32,672 个字节。在数据库中,VARCHAR 数据只占用必需的空间。

下列数据类型用于存储双字节字符串:

  • GRAPHIC
    GRAPHIC 用于存储固定长度的双字节字符串。GRAPHIC 列的最大长度是 127 个字符。
  • VARGRAPHIC
    VARGRAPHIC 用于存储可变长度的双字节字符串。VARGRAPHIC 列的最大长度是 16336 个字符。

DB2 还提供了用来存储极长数据字符串的数据类型。所有的长字符串数据类型都有相似的特征。首先,数据不是以行数据实际存储在数据库中,这意味着访问这些数据需要进行一些额外处理。长数据类型的长度最大可以定义到 2G。不过,实际只使用必需的空间。长数据类型有:

  • LONG VARCHAR CLOB 或称字符大对象 LONG VARGRAPHIC DBCLOB 或称双字节字符大对象
  • BLOB 或称二进制大对象

日期时间型(Datetime)数据类型

DB2 提供了三种数据类型来存储日期和时间:

  • DATE TIME
  • TIMESTAMP

这些数据类型的值都以内部格式存储在数据库中,但在程序中您可以将它们作为字符串进行操作。这些数据类型中的任何一个被检索时,都表示为字符串。在更新这些数据类型时,必须用引号把值括起来。DB2 提供了一些内置函数来操作日期时间值。例如,您可以用 DAYOFWEEK 或 DAYNAME 函数确定日期值的星期号。您可以用 DAYS 函数计算两个日期间有多少天。DB2 还提供了特殊的寄存器,可用它们根据当天时钟的时间,生成当前日期、时间或时间戳记。例如,CURRENT DATE 返回一个表示系统当前日期的字符串。日期和时间值的格式取决于数据库的国家或地区代码,这些代码在创建数据库时指定。几种可用的格式是:ISO、USA、EUR 和 JIS。例如,如果您的数据库使用的是 USA 格式,那么日期值的格式为“MM/DD/YYYY”。创建应用程序时,可以通过使用 BIND 命令的 DATETIME 选项更改格式。

TIMESTAMP 数据类型只有一种格式。字符串表示为 YYYY-MM-DD-HH.MM.SS.NNNNNN。

数据链接型(Datalink)

DB2 提供了 DATALINK 数据类型来管理外部文件。DATALINK 列允许您存储对数据库外部文件的引用。这些文件可以驻留在同一个服务器或者驻留在远程服务器的文件系统中。DB2 提供了一些工具使应用程序可以安全地访问这些文件。

要往 DATALINK 列中插入值,必须使用内置函数 DLVALUE。DLVALUE 需要几个参数,这些参数告诉 DB2 文件名,以及文件存储在何处。为从 DATALINK 列检索数据,DB2 根据所需的信息提供了几个函数。

用户定义的数据类型

DB2 允许您定义适合自己的应用程序的数据类型。有三种用户定义的数据类型:

  • 用户定义的单值类型
    您可以在内置类型的基础上定义新的数据类型。这个新类型将具有该内置类型拥有的相同功能,但它确保只比较相同类型的值。例如,您可以在 DECIMAL(10,2) 的基础上定义一个加拿大元类型(CANDOL)和一个美元类型(USADOL)。这两种类型都基于同一种内置类型,但除非应用了转换函数,否则无法比较它们。

    下面是创建 CANDOL 和 USADOL UDT 的 CREATE TYPE 语句:

    
    CREATE DISTINCT TYPE CANDOL AS DECIMAL(10,2) WITH COMPARISONS
    CREATE DISTINCT TYPE USADOL AS DECIMAL(10,2) WITH COMPARISONS 
              
    

    DB2 自动生成函数来执行基本类型和单值类型之间的强制转换,还自动生成用于比较单值类型实例的比较操作符。下列语句显示了如何创建带有 CANDOL 类型列的表,以及如何使用 CANDAL 强制转换函数向表中插入数据。

    
    CREATE TABLE ITEMs (ITEMID CHAR(5), PRICE CANDOL )
    INSERT INTO ITEMs VALUES('ABC11',CANDOL(30.50) )  
              
    
    用户定义的结构化类型
    对这种类型的支持允许您创建由几个内置类型列组成的类型。然后,您可以在创建表时使用这个结构化类型。例如,您可以创建一种名为 address 的结构化类型,它包含表示街道号码、街道名、城市之类的数据。然后在定义其它表(如职工表或者供应商表)时使用这种类型,因为这两个表也需要同样的数据。另外,结构化类型还可以在层次结构中有子类型。这就允许属于某一层次结构的对象存储在数据库中。
  • 用户定义的引用类型
    在使用结构化类型时,您可以使用引用类型定义对另一个表中行的引用。这些引用看起来好象与引用约束相似,然而,它们不强制表间有关系。表中的引用允许您用不同的方法指定查询。

用户定义的结构化和引用类型是高级论题,这些信息只作为对这些类型的介绍。

DB2 扩展器(DB2 Extender)

DB2 扩展器支持复杂的、非传统的数据类型。它们与 DB2 服务器代码分开打包,必须安装在服务器上,并且必须安装在将使用那些数据类型的每个数据库中。IBM 和一些独立的软件供应商提供许多 DB2 扩展器。IBM 最早提供的四个扩展器用于存储音频、视频、图像和文本。例如,DB2 图像扩展器(DB2 Image Extender)可用于存储一个书的封面图像,而 DB2 文本扩展器(DB2 Text Extender)可用于存储书的正文。现在,还有其它几个扩展器可用,包括允许您在 DB2 数据库中管理 XML 文档的 XML 扩展器(XML Extender)。DB2 扩展器用用户定义的类型和用户定义的函数的功能实现。每个扩展器提供一个或多个 UDT、用于操作 UDT 的 UDF 和特定的应用程序编程接口(API),或许还提供其它工具。例如,DB2 图像扩展器包含:

  • DB2IMAGE UDT向 db2image 列插入数据或从该列检索数据的 UDF
  • 根据图像特征进行搜索的 API

在使用这些数据类型之前,必须把扩展器支持安装在数据库中。每个扩展器的安装过程定义了数据库中所需的 UDT 和 UDF。然后,您就可以在定义表时使用 UDT,在处理数据时使用 UDF。

什么是表?

所有的数据都存储在数据库的表中。一个表由不同数据类型的一列或多列组成。数据存储在行(或称为记录)中。表是使用 CREATE TABLE SQL 语句定义的。DB2 还提供了一个用来创建表的 GUI 工具,这个工具将根据您指定的信息创建一个表。它还将生成稍后可以在脚本或应用程序中使用的 CREATE TABLE SQL 语句。

一个数据库有一个表集,称为系统目录表(System Catalog Table),它保存关于数据库中所有对象的信息。数据库中定义的每个表在目录表 SYSCAT.TABLES 中都有相应的一行。数据库中每个表的每一列在 SYSCAT.COLUMNS 中都有相应的一行。您可以用 SELECT 语句象看数据库中的任何其它表一样看目录表。

创建一个表

CREATE TABLE SQL 语句用于在数据库中定义一个表。下面是创建一个简单的、名为 books 的表的示例,该表包含三列:


CREATE TABLE BOOKS ( BOOKID INTEGER, 
                     BOOKNAME VARCHAR(100), 
                     ISBN CHAR(10) )
          

您还可以使用 CREATE TABLE SQL 语句创建与数据库中另一个表或视图相似的表。


CREATE TABLE MYBOOKS LIKE BOOKS
          

这条语句创建了一个与原始表或视图具有相同列的表。新表的列具有与原始表或视图中的列相同的名称、数据类型和可以为空的属性。您还可以指定一些复制列缺省值和标识属性之类功能的选项。有许多选项可用于 CREATE TABLE 语句(它们将在下面部分出现,作为新概念被介绍)。CREATE TABLE SQL 语句的详细信息可以在 SQL Reference 中找到(请参阅参考资料)。

一旦创建了表,就有几种方法可向它植入数据。INSERT 语句允许您向表中插入一行或几行数据。DB2 还提供了一些实用程序插入来自文件的大量数据。IMPORT 实用程序使用 INSERT 语句插入行。它是为向数据库加载少量数据而设计的。LOAD 实用程序将行直接插入到数据库中的数据页,因此比 IMPORT 实用程序要快得多。它的目的是用于加载大量数据。

表存储在数据库中的什么地方?

表存储在数据库的表空间中。表空间拥有分配给它们的物理空间。在创建表之前必须先创建表空间。在创建表时,您可以让 DB2 把表放在缺省的表空间内,或者也可以指定表应该驻留在哪个表空间内。在这个 CREATE TABLE 语句中,books 表将放在 BOOKINFO 表空间内。


CREATE TABLE BOOKS ( BOOKID INTEGER, 
                     BOOKNAME VARCHAR(100), 
                     ISBN CHAR(10) ) 
             IN BOOKINFO
          

虽然我们不准备在这里详细讨论表空间,但理解正确定义表空间将会影响数据库的性能和可维护性这一点很重要。

更改表

您可以使用 ALTER TABLE SQL 语句更改表的某些特征。可以更改的一些特征是:

  • 添加一个或多个列添加或删除一个主键添加或删除一个或多个唯一性或引用约束添加或删除一个或多个检查约束
  • 更改 VARCHAR 列的长度

例如,下面的语句向 BOOKS 表添加一个列 BOOKTYPE:


ALTER TABLE BOOKS ADD BOOKTYPE CHAR(1)
          

表的某些特征不可以更改。例如,您不可以从表中除去列。另外,您不可以更改表驻留的表空间。要更改象这样的特征,必须保存表数据,删除表然后重新创建表。

删除表

DROP TABLE 语句将表从数据库中除去。数据和表定义被删除。如果为表定义了索引或者约束,它们也同时被删除。下面是从数据库中删除 BOOKS 表的 DROP TABLE 语句。


DROP TABLE BOOKS
NOT NULL、DEFAULT 和 GENERATED 列选项

表的列在 CREATE TABLE 语句中由列名称和数据类型定义。列可以指定一些额外选项来限制列中的数据。缺省情况下,列允许 NULL 值。如果您不想允许 NULL 值,可以为列指定 NOT NULL 关键字。您还可以使用 WITH DEFAULT 关键字和缺省值指定缺省值。下面的 CREATE TABLE 语句创建了一个表 BOOKS,在这个表中 BOOKID 列不允许 NULL 值,BOOKNAME 的缺省值为 'TBD'。


CREATE TABLE BOOKS ( BOOKID INTEGER NOT NULL, 
                     BOOKNAME VARCHAR(100) WITH DEFAULT 'TBD', 
                     ISBN CHAR(10) ) 
          

在 BOOKS 表中,BOOKID 是为每本书指定的唯一的号码。我们可以使用 GENERATED ALWAYS AS IDENTITY 子句指定 DB2 生成 BOOKID,而不必让应用程序生成标识符。


CREATE TABLE BOOKS ( BOOKID INTEGER NOT NULL GENERATED ALWAYS AS IDENTITY
                                             (START WITH 1, INCREMENT BY 1), 
                     BOOKNAME VARCHAR(100) WITH DEFAULT 'TBD', 
                     ISBN CHAR(10) ) 
          

GENERATED ALWAYS AS IDENTITY 导致生成一个 BOOKID。生成的第一个值将是 1,通过逐次加 1 将生成后面的值。您还可以使用 GENERATED ALWAYS 选项让 DB2 自动计算列的值。下面的示例定义了一个名为 AUTHORS 的表,该表用于计算小说和非小说书籍的数量。将通过把两个数量相加来计算 TOTALBOOKS 列。


CREATE TABLE AUTHORS (AUTHORID INTEGER NOT NULL PRIMARY KEY,
                      LNAME VARCHAR(100),
                      FNAME VARCHAR(100),
                      FICTIONBOOKS INTEGER,
                      NONFICTIONBOOKS INTEGER,
                      TOTALBOOKS INTEGER GENERATED ALWAYS AS (FICTIONBOOKS + NONFICTIONBOOKS) )

什么是约束?

DB2 提供了几种方法来控制什么数据可以存储在列中。这些功能被称为约束(constraint)规则(rule),数据库管理器强制一个数据列或一组列遵守这些约束或规则。DB2 提供了三种类型的约束:

  • 唯一性约束,用于确保列中的值是唯一的。引用完整性约束,用于定义表间的关系,并确保这些关系一直有效。
  • 表检查约束,用于验证列数据没有违反为列定义的规则。

唯一性约束

唯一性约束用于确保列中的值是唯一的。可以对一个或多个列定义唯一性约束。唯一性约束中包括的每个列都必须定义为 NOT NULL。唯一性约束可以定义为 PRIMARY KEY 或 UNIQUE 约束。这些可以在创建表时作为 CREATE TABLE SQL 语句的一部分定义,或者在创建表后使用 ALTER TABLE 语句添加。什么时候定义 PRIMARY KEY 或 UNIQUE 键?这取决于数据的属性。在前面的示例中,BOOKS 表有一个 BOOKID,它用于唯一地识别一本书。这个值还可以在包含与这本书相关的信息的其它表中使用。在这个例子中,您把 bookid 定义为主键。DB2 在一个表中只允许定义一个主键。ISBN 号列需要是唯一的,但它不是一个在数据库中会被引用的值。在这种情况下,ISBN 列可以定义为是唯一的。


CREATE TABLE BOOKS (BOOKID INTEGER NOT NULL PRIMARY KEY,
                    BOOKNAME VARCHAR(100),
                    ISBN CHAR(10) NOT NULL CONSTRAINT BOOKSISBN UNIQUE ) 
          

CONSTRAINT 关键字允许您为约束指定一个名称。在这个示例中,唯一性约束的名称是 BOOKSISBN。如果您想删除特定的约束,请在 ALTER TABLE 语句中使用这个名称。DB2 在一个表中只允许定义一个主键,但可以定义多个唯一性约束。无论何时您为列定义一个 PRIMARY 或 UNIQUE 键,DB2 都会创建一个唯一的索引以强制列的唯一性。DB2 不允许创建重复的唯一性约束或重复的索引。例如,针对 BOOKS 表的下面的语句将失败。


ALTER TABLE BOOKS ADD  CONSTRAINT UNIQUE (BOOKID)

引用完整性约束

引用完整性约束用于定义表间的关系。假设我们有一个表包含关于作者的信息,而另一个表列出了该作者写的书。在 BOOKS 表和 AUTHORS 表之间就有这样一种关系 — 每本书都有一个作者,而且该作者必须存在于作者表中。每个作者都有一个存储在 AUTHORID 列中的唯一的标识符。AUTHORID 在 BOOKS 表中被用于识别每本书的作者。要定义这种关系,请把 AUTHORS 表的 AUTHORID 列定义为主键,然后为 BOOKS 表定义一个外键,从而与 AUTHORS 表中的 AUTHORID 列建立关系。


CREATE TABLE AUTHORS (AUTHORID INTEGER NOT NULL PRIMARY KEY,
                      LNAME VARCHAR(100),
                      FNAME VARCHAR(100))
CREATE TABLE BOOKS (BOOKID INTEGER NOT NULL PRIMARY KEY,
                    BOOKNAME VARCHAR(100),
                    ISBN CHAR(10),
                    AUTHORID INTEGER REFERENCES AUTHORS) 
          

拥有与另一个表相关的主键的表被称为父表(parent table)。与父表相关的表被称为从属表(dependent table)。在我们的示例中所描述的关系中,AUTHOR 表是父表,BOOKS 表是从属表。您可以为一个父表定义多个从属表。您还可以定义同一个表中各行之间的关系。在这种情况下,父表和从属表是同一个表。如果为一组表定义了引用约束,当对这些表执行更新操作时,DB2 就会强制这些表遵守引用完整性规则。

  • DB2 确保只向定义了引用完整性约束的列插入有效数据。这意味着在父表中必须一直有这样一行,该行的键值等于您正要插入到从属表中的行的外键值。例如,如果一本新书要插入到 AUTHORID 为 437 的 BOOKS 表中,那么 AUTHORS 表中必须有 AUTHORID 为 437 的一行。当从父表中删除一行,而该行在从属表中有从属行时,DB2 也强制要遵守一些规则。DB2 采取的操作取决于为表定义的删除规则。可以指定四条规则:RESTRICT、NO ACTION、CASCADE 和 SET NULL。
    • 如果指定了 RESTRICT 或 NO ACTION,那么 DB2 不允许删除父行。必须首先删除从属表中的行才能删除父表中的行。这条规则是缺省值,所以当定义 AUTHORS 和 BOOKS 表时这条规则也适用于它们。如果指定了 CASCADE,那么从父表中删除行时还会自动删除所有从属表中的从属行。
    • 如果指定了 SET NULL,那么从父表中删除父行时从属行中的外键值被设置为空(如果可以为空的话)。
  • 更新父表中的键值时,可以指定两条规则:RESTRICT 和 NO ACTION。如果从属表中有从属行则 RESTRICT 不允许更新键值。如果在更新的最后,在从属表中有从属行,而且从属行没有父表中的父键,则 NO ACTION 将导致对父键值的更新操作被拒绝。

表检查约束

表检查约束被用于限制表的某一列中的值。DB2 将确保在插入和更新时不违反这条约束。假设我们向 BOOKS 表添加了一个有关书籍类型的列,该列允许类型的值为 'F'(小说)和 'N'(非小说)。我们可以添加一个列 BOOKTYPE,检查约束如下:


ALTER TABLE BOOKS ADD BOOKTYPE CHAR(1) CHECK (BOOKTYPE IN ('F','N') ) 
          

在创建表或者稍后使用 ALTER TABLE SQL 语句添加它们时可以定义检查约束。您可以通过删除,然后使用 ALTER TABLE SQL 语句重新创建检查约束来修改它们。

什么是视图

视图允许不同的用户或应用程序用不同的方法查看相同的数据。它不仅使得数据更容易访问,还可以用它来限制可以查看或更新哪些行和列。例如,假设一个公司有一个包含该公司职工信息的表。经理只需看关于他的职工的信息,而姓名地址录应用程序需要查看所有职工以及他们的地址和电话号码,但不需看他们的薪水。可以创建一个只显示一个部门内职工的视图。还可以创建另一个只显示名字、地址和电话号码的视图。对于用户来说,视图看起来就跟表一样。除视图定义之外,视图在数据库内并不占用空间。视图中显示的数据来自另一个表。您可以根据现有的一个表(或多个表)或者另一个视图或者它们的任意组合创建一个视图。在另一个视图的基础上定义的视图被称为嵌套视图。您可以用不同于基本表中相应列的列名定义视图。您还可以定义一些检查插入或更新的数据是否一直满足视图条件的视图。

数据库中定义的视图的列表存储在系统目录表 SYSIBM.SYSVIEWS 中,SYSIBM.SYSVIEWS 还有一个根据它创建的名为 SYSCAT.VIEWS 的视图。系统目录还有一个 SYSCAT.VIEWDEP,对于数据库中定义的每一个视图,SYSCAT.VIEWDEP 都有该视图的每个从属(视图或表)的一行。另外,每个视图都有 SYSIBM.SYSTABLES 中的一个条目和 SYSIBM.SYSCOLUMNS 中的一些条目,因为视图可以象表一样被使用。

创建一个视图

CREATE VIEW SQL 语句被用于定义视图。SELECT 语句用于指定将在视图中显示哪些行与列。例如,我们想创建一个只显示表中非小说类书籍的视图。


CREATE VIEW NONFICTIONBOOKS AS 
       SELECT * FROM BOOKS WHERE BOOKTYPE = 'N'
          

请注意,定义过这个视图后,SYSCAT.VIEWS、SYSCAT.VIEWDEP 和 SYSCAT.TABLES 中将有一个条目。要在视图中定义不同于基本表中那些列的列名称,可以在 CREATE VIEW 语句中指定它们。这条语句创建了一个 MYBOOKVIEW 视图,该视图包含两列:TITLE(代表 BOOKNAME 列)和 TYPE(代表 BOOKTYPE 列)。


CREATE VIEW MYBOOKVIEW (TITLE,TYPE) AS 
       SELECT BOOKNAME,BOOKTYPE FROM BOOKS 
          

DROP VIEW SQL 语句用于从数据库中删除视图。如果一个视图所基于的表或另一个视图被删除,那么视图依然在数据库中被定义,但变得不起作用。SYSCAT.VIEWS 的 VALID 列表明视图是有效('Y')还是无效('X')。甚至当重新创建基本表时,视图也必须被重新创建。要从数据库删除 NONFICTIONBOOKS 视图:


DROP VIEW NONFICTIONBOOKS
          

您无法修改视图。要更改视图定义,您必须删除视图然后重新创建它。提供的 ALTER VIEW 语句只用于修改引用类型,这里不准备讨论。

只读视图

创建一个视图时,它可能被定义为一个只读视图,或者一个可更新视图。视图的 SELECT 语句确定视图是只读的还是可更新的。一般情况下,如果视图中的行可以映射到基本表中的行,那么该视图就是可更新的。例如,就像前面示例中定义的那样,视图 NONFICTIONBOOKS 是可更新的,因为视图中的每一行都是基本表中的行。创建可更新视图的规则很复杂,它们取决于查询的定义。例如,使用 VALUES、DISTINCT 或 JOIN 功能的视图是不可更新的。通过查看 SYSCAT.VIEWS 的 READONLY 列很容易就能确定视图是不是可更新的:'Y' 表示只读,'N' 表示非只读。

DB2 SQL Reference 中说明了创建可更新视图的详细规则(请参阅参考资料)。

带检查选项的视图

先前定义的 NONFICTIONBOOKS 视图只包含 BOOKTYPE 为 'N' 的行。如果向这个视图插入一个 BOOKTYPE 为 'F' 的行,DB2 将把该行插入到基本表 BOOKS 中。但是,如果您随后从视图中选择它,通过该视图却看不到新插入的行。如果您不想允许用户插入视图范围以外的行,定义视图时您可以使用检查选项。使用 WITH CHECK OPTION 定义视图会告诉 DB2 检查使用视图的语句是否满足视图的条件。下面的语句用 WITH CHECK OPTION 定义了一个视图:


CREATE VIEW NONFICTIONBOOKS AS 
       SELECT * FROM BOOKS WHERE BOOKTYPE = 'N'
       WITH CHECK OPTION
          

这个视图仍限制用户只能看到非小说类的书,然而,它还限制不准插入 BOOKTYPE 列的值不为 'N' 的行,并限制不准把现有行中 BOOKTYPE 列的值更新为 'N' 以外的值。下列语句将不再被允许:


INSERT INTO NONFICTIONBOOKS VALUES (...,'F'); 
UPDATE NONFICTIONBOOKS SET BOOKTYPE = 'F' WHERE BOOKID = 111
          

定义嵌套视图时,检查选项可以用于限制操作。然而,您还可以指定其它选项来定义如何继承限制。检查选项可以定义为 CASCADED 或者 LOCAL。不指定关键字时,CASCADED 是缺省值。为说明 CASCADED 和 LOCAL 行为的不同,我们需要看几个可能的案例。当用 WITH CASCADED CHECK OPTION 创建视图时,所有针对该视图执行的语句都必须满足视图和所有底层视图的条件 — 即使那些视图不是用检查选项定义的也是如此。假设创建 NONFICTIONBOOKS 时没用检查选项,我们也可以使用 CASCADED 关键字在视图 NONFICTIONBOOKS 的基础上创建视图 NONFICTIONBOOKS1。


CREATE VIEW NONFICTIONBOOKS AS 
       SELECT * FROM BOOKS WHERE BOOKTYPE = 'N'
CREATE VIEW NONFICTIONBOOKS1 AS 
       SELECT * FROM NONFICTIONBOOKS WHERE BOOKID > 100
       WITH CASCADED CHECK OPTION
          

将不允许下列 INSERT 语句,因为它们不满足至少其中一个视图的条件。


INSERT INTO NONFICTIONBOOKS1 VALUES( 10,..,'N')
INSERT INTO NONFICTIONBOOKS1 VALUES(120,..,'F')
INSERT INTO NONFICTIONBOOKS1 VALUES( 10,..,'F')
          

但却会允许下面的 INSERT 语句,因为这两个视图的条件它都满足。


INSERT INTO NONFICTIONBOOKS1 VALUES(120,...,'N')
          

现在假设我们用 WITH LOCAL CHECK OPTION 在视图 NONFICTIONBOOKS 的基础上创建了视图 NONFICTIONBOOKS2。现在,针对视图执行的语句只需要满足指定了检查选项的视图的条件。


CREATE VIEW NONFICTIONBOOKS AS 
       SELECT * FROM BOOKS WHERE BOOKTYPE = 'N'
CREATE VIEW NONFICTIONBOOKS2 AS 
       SELECT * FROM NONFICTIONBOOKS WHERE BOOKID > 100
       WITH LOCAL CHECK OPTION
          

在这种情况下,将不允许下面的 INSERT 语句,因为它不满足 NONFICTIONBOOKS2 视图的 BOOKID > 100 这个条件。


INSERT INTO NONFICTIONBOOKS2 VALUES(10,..,'N')
INSERT INTO NONFICTIONBOOKS2 VALUES(10,..,'F')
          

但是,即使值 'N' 不满足 NONFICTIONBOOKS 视图的 BOOKTYPE = 'N' 这个条件,也会允许下面的 INSERT 语句。


INSERT INTO NONFICTIONBOOKS2 VALUES(120,..,'N')
INSERT INTO NONFICTIONBOOKS2 VALUES(120,..,'F')

什么是索引?

索引是表的一个或多个列的键值的有序列表。可能要创建索引的原因有两个:

  • 确保一个或多个列中值的唯一性。
  • 提高对表进行的查询的性能。当执行查询时想以更快的速度找到所需的列,或要以索引的顺序显示查询结果时,DB2 优化器选择使用索引。

索引可以定义为唯一的或非唯一的。非唯一的索引允许重复的键值。唯一的索引只允许列表中出现一个键值。唯一的索引允许显示单个 NULL。然而,第二个值会导致重复现象,因此不允许。索引是使用 CREATE INDEX SQL 语句创建的。为支持主键或唯一性约束,也可以隐式创建索引。当创建唯一索引时,检查键数据的唯一性,如果发现重复的键数据则该操作失效。

索引可以创建为升序、降序或双向。选择哪个选项取决于应用程序如何访问数据。

创建索引

在我们的示例中,BOOKID 列上有一个主键。通常大家是搜索书的标题,所以按 BOOKNAME 建索引比较合适。下面这条语句为 BOOKNAME 列创建了一个非唯一的升序索引。


CREATE INDEX IBOOKNAME ON BOOKS (BOOKNAME)
          

索引名 IBOOKNAME 被用于创建和删除索引。除此之外,在查询或更新表时不使用该名称。缺省情况下,索引按升序创建,但您也可以创建降序索引。您甚至可以在索引中为各个列指定不同的顺序。下面的语句按 AUTHORID 和 BOOKNAME 列定义了一个索引。在同一个 AUTHORID 中,AUTHORID 列的值按降序排序,而 BOOKNAME 列的值按升序排序。


CREATE INDEX I2BOOKNAME ON BOOKS (AUTHOID DESC, BOOKNAME ASC)
          

在数据库中创建索引时,按照指定的顺序存储键。索引通过要求数据处于指定的顺序帮助提高查询的性能。升序索引还被用于确定 MIN 列函数的结果,降序索引被用于确定 MAX 列函数的结果。如果应用程序还需要数据按与索引相反的顺序排序,那么 DB2 允许创建双向索引。双向索引使您不必创建逆向索引,而且它不需要优化器按逆向对数据排序。它还允许有效地恢复 MIN 和 MAX 函数值。要创建双向索引,请在 CREATE INDEX 语句中指定 ALLOW REVERSE SCANS 选项。


CREATE INDEX BIBOOKNAME ON BOOKS (BOOKNAME) ALLOW REVERSE SCANS
          

DB2 将不允许创建具有相同定义的索引。即使是隐式创建索引以支持主键或唯一性约束时这一点也适用。所以,既然 BOOKS 表已经有了一个按 BOOKID 列定义的主键,那么尝试按 BOOKID 列创建索引将失败。创建一个索引花费的时间比较长。DB2 必须读每一行来抽取键,对键排序,然后将列表写到数据库中。如果表比较大,那么将使用一个临时表空间对键进行排序。索引存储在表空间中。如果您的表驻留在数据库管理的表空间中,您就可以选择将索引分别放在分开的表空间中。在使用 INDEXES IN 子句创建表时必须定义这一点。索引的位置在创建表时被设置,除非删除并重新创建表,否则无法改变索引的位置。

当然,DB2 还提供了 DROP INDEX SQL 语句从数据库中除去索引。索引是无法修改的。如果需要更改索引,例如向键添加另一个列,您必须删除并重新创建该索引。

在索引中使用包含(include)列

在创建索引时,您可以选择包含额外的列数据,这些额外的列数据将与键存储在一起,但实际上它们不是键自身的一部分,所以不被排序。在索引中包含额外列的主要原因是为了提高某些查询的性能。DB2 将不需要访问数据页,因为索引页早已经提供了数据值。只可以为包含的列定义唯一索引。但在强制执行索引的唯一性时不考虑被包含的列。假设我们经常需要获得按 BOOKID 排序的书名列表。查询将如下所示:


SELECT BOOKID,BOOKNAME FROM BOOK ORDER BY BOOKID
          

下面的语句会创建一个可以提高性能的可能的索引:


CREATE UNIQUE INDEX IBOOKID ON BOOKS (BOOKID) INCLUDE(BOOKNAME)
          

结果,查询结果所需的所有数据都显示在索引中,不需要检索数据页。

那么,为什么不干脆在索引中包括所有的数据?首先,这需要数据库中的更多物理空间,因为本质上数据是在索引中复制的。其次,只要更新了数据的值,数据的所有副本都需要更新,在发生许多次更新的数据库中,这是一项很大的开销。

我应该创建什么索引?

下面是创建索引时的一些注意事项。

  • 由于索引是键值的永久列表,它们在数据库中需要空间。所以,创建许多索引就需要数据库中有更多的存储空间。所需的空间总量由键列的长度决定。DB2 提供了一个工具帮您估计索引的大小。索引是值的额外副本,所以当表中的数据被更新时,它们也一定被更新。如果表数据经常被更新,请考虑额外的索引会对更新性能产生什么样的影响。
  • 如果按适当的列定义索引,该索引将大大提高查询的性能。

DB2 提供了一个被称为索引建议器(Index Advisor)的工具帮助您确定要定义哪些索引。索引建议器允许您指定将对表执行的工作量,然后它将推荐要为表创建的索引。

总结

这篇教程讨论了 DB2 通用数据库中定义的数据类型、表、视图和索引的功能。它还说明了如何使用 CREATEALTERDROP 语句管理这些对象。DB2 提供了一组丰富而又灵活的数据类型。Data 类型分为内置数据类型和用户定义的数据类型。DB2 提供的内置数据类型有:

  • 数字型:INTEGER、BIGINT、SMALLINT、DECIMAL、REAL、DOUBLE 和 FLOAT字符串型:CHAR、VARCHAR、LONG VARCHAR、CLOB、GRAPHIC、VARGRAPHIC、LONG VARGRAPHIC、DBLOB 和 BLOB日期时间型:DATE、TIME 和 TIMESTAMP
  • 数据链接型:DATALINK

DB2 还提供了一些工具来创建高级数据类型。

  • 用户定义的单值类型用户定义的结构化类型
  • 用户定义的引用类型

DB2 扩展器是一个用户定义类型的应用程序。IBM 和其它软件供应商提供了各种 DB2 扩展器。一些可用的扩展器是 Text、Audio、Video、Image 和 XML。表包含数据库中的数据。表中的列是由数据类型定义的。可以为表定义一些约束来提供数据验证。DB2 提供了三种类型的约束:

  • 唯一性约束用于确保列中的值是唯一的。引用完整性约束,用于定义表间的关系,并确保这些关系一直有效。
  • 表检查约束,用于验证列数据是否违反为列定义的规则。

视图允许不同的用户或应用程序用不同的方法查看相同的数据。它不仅使数据访问变得更简单,还可以用它来限制可以查看或更新哪些行和列。使用 WITH CHECK OPTION 定义视图会告诉 DB2 检查对视图的更新是否满足视图的条件。即便是指定了嵌套视图,也可以强制进行数据验证。

索引是表中一个或多个列的键值的有序列表。创建索引是为确保一个或多个列中值的唯一性和/或提高对表的查询的性能。DB2 优化器在执行查询时选择使用索引,以便更快找到所需的列。DB2 提供了索引建议器来帮助确定为指定的工作量创建哪些索引

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多