HSQLDB 用户指南


HSQLDB 用户指南 English Doc Version : 2005/5/29 Chinese Doc Version: 2005/7/7 Java@ bbs.xjtu.edu.cn HSQLDB——轻量级纯 Java 关系型数据库 翻译说明: Hsqldb是一个优秀的轻量级开源的纯Java SQL数据库,为了方便Hsqldb在国内推广我 们将 2005/05/16 发布的用户指南翻译成中文,不过我们建议有能力的读者阅读英文原文。 大家可以从Hsqldb官方网站(http://hsqldb.sourceforge.net)获取到Hsqldb的发布包、源代码 和文档。 版权声明 所有权利归本文档的作者(李博 role0523@163.com)所有。本版本可以自由传播,但必 须保证全文的完整(不能进行增添、修改、删除)。不得利用本文档做有偿性的商业活动。 HSQLDB 用户指南 i HSQLDB——轻量级纯 Java 关系型数据库 前言....................................................................................................................................................... III 第 1 章 运行和使用 HSQLDB..............................................................................................................1 1.1 简介................................................................................................................................................1 1.2 运行工具........................................................................................................................................1 1.3 运行 HSQLDB .................................................................................................................................2 1.4 SERVER 模式...................................................................................................................................2 1.4.1 Hsqldb Server ......................................................................................................................3 1.4.2 Hsqldb Web Server .............................................................................................................3 1.4.3 Hsqldb Servlet......................................................................................................................3 1.4.4 In-Process(Standalone)模式..............................................................................................4 1.4.5 Memory-Only 数据库 ...........................................................................................................5 1.5 一般操作 .......................................................................................................................................5 1.5.1 关闭数据库 ...........................................................................................................................5 1.5.2 在一个 JVM 里使用多数据库 .............................................................................................6 1.5.2 创建新数据库 .......................................................................................................................6 1.6 使用数据库引擎 ...........................................................................................................................6 1.6.1 不同类型的表........................................................................................................................6 1.6.2 约束和索引 ...........................................................................................................................7 1.6.3 SQL 支持...............................................................................................................................8 1.6.4 JDBC 支持 ............................................................................................................................8 第 2 章 SQL 问题...................................................................................................................................9 2.1 本章目的........................................................................................................................................9 2.2 对 SQL 标准的支持......................................................................................................................9 2.3 约束和索引 ...................................................................................................................................9 2.3.1 主键约束...............................................................................................................................9 2.3.2 唯一性约束.........................................................................................................................10 2.3.3 唯一性索引.........................................................................................................................10 2.3.4 外键.....................................................................................................................................10 2.3.5 索引和查询速度................................................................................................................. 11 2.3.6 Where 条件或者连接.........................................................................................................12 2.3.7 子查询和连接.....................................................................................................................13 2.4 类型和算术操作 .........................................................................................................................13 2.4.1 整型类型.............................................................................................................................13 2.4.2 其他数据类型.....................................................................................................................14 2.4.3 二进制和 Boolean 类型......................................................................................................15 2.4.4 Java 对象的存储和操作 .....................................................................................................15 2.4.5 类型的大小、精度和范围.................................................................................................16 2.5 序列和标识 .................................................................................................................................16 2.5.1 标识自动增长列.................................................................................................................16 2.5.2 序列.....................................................................................................................................17 2.5.3 事务的问题.........................................................................................................................17 2.5.4 新特性和变化......................................................................................................................18 HSQLDB 用户指南 ii 前言 前言 如果大家在阅读过程中发现我们在翻译存在异议,李博role0523@163.com (常用) role0523@gmail.com,或各章作者联系。 HSQLDB 用户指南 iii 运行和使用 Hsqldb 第 1 章 运行和使用 Hsqldb 本章由李博翻译, 1.1 简介 hsqldb.jar 包位于/lib 目录下,它包含了一些组件和程序。每个程序需要不同的命令来运行。 Hsqldb.jar 包中有下列这些组件: • HSQLDB RDBMS • HSQLDB JDBC Driver • Database Manager (Swing and AWT versions) • Transfer Tool (AWT version) ) • Query Tool (AWT) • Sql Tool (command line) 其中、HSQLDB RDBMS 和 JDBCDriver 提供了 HSQLDB 的核心功能。其余的组件都是 通用的数据库工具。这些通用工具可以使用在任何带有 DEC 驱动的数据库上。 1.2 运行工具 Hsqldb 提供的所有工具都能以 java class 归档文件(也就是 jar)的标准方式运行。在下面运 行 AWT 版本的 DatabaseManager 的例子中,hsqldb.jar 位于相对于当前路径的../lib 下面。 java -cp ../lib/hsqldb.jar org.hsqldb.util.DatabaseManager 如果 hsqldb.jar 位于当前路径中,运行 DatabaseManager 的命令就应该改成: java -cp hsqldb.jar org.hsqldb.util.DatabaseManager Hsqldb 提供的主要的工具类 • org.hsqldb.util.DatabaseManager • org.hsqldb.util.DatabaseManagerSwing • org.hsqldb.util.Transfer • org.hsqldb.util.QueryTool • org.hsqldb.util.SqlTool 其中像 DatabaseManager 或 Sql Tool 这样的工具,可以或者只能用命令行参数来运行。 你可以在命令行后面加上参数-?来查看这些工具可用的参数列表。Database Manager 和 Transfer Tool 具有图形用户接口,可以进行方便的交互式操作。 HSQLDB 用户指南 1 运行和使用 Hsqldb 1.3 运行 Hsqldb HSQLDB 可以采用几种不同的方式运行。一般可以分为 Serer 模式和 In-Process(进程内 模式,也称之为 Standalone(独立)模式)。对于每种模式,Jar 中都有相应的子程序来运行 HSQLDB。 每个 HSQLDB 数据库包含了 2 到 5 个命名相同但扩展名不同的文件,这些文件位于同一 个目录下。例如,名位“test”的数据库包含了以下几个文件: • test.properties • test.script • test.log • test.data • test.backup properties 文件描述了数据库的基本配置。 script 文件记录了表和其它数据库对象的定义, 此外还有 non-cached(无缓冲)表的数据。log 文件记录了数据库最近所做的更新。data 文件包含了 cached(缓冲)表的数据,而 backup 文件是将 data 文件压缩备份,它包含 了 data 文件上次的最终状态数据。所有这些文件都是必不可少的,千万不可擅自删除。但 如果你的数据库没有缓冲表(cached table),test.data 和 test.backup 文件是不会存在。此外, HSQLDB 数据库可以链接到磁盘上任何地方任何格式的文本文件,比如 CSV 列表。 “test”数据库在操作的时候, “test.log”文件是用来记录数据库的变动,它在 HSQLDB 正常 关闭的时候会被移除掉。否则(在非正常退出的时候),它将用来在下次启动 HSQLDB 时重复“test.log”中记录的更新操作. “test.lck”文件也可以用来记录数据库是否被打开,它在 HSQLDB 正常退出的时候会被移除。有些情况下,HSQLDB 会生成 test.data.old ”文件, 但随后会被删除掉。 注意 当 HSQLDB 引擎关闭数据库的时候,它会产生扩展名为.new 的临时文件,然后会把这些 文件重命名为上面所列出的文件的名称。 1.4 Server 模式 Server 模式提供了最大的可访问性(accessibility)。这种模式下,数据库引擎在 JVM 里 运行,监听来自同一台机器上或网络中其他计算机程序的连接。几个不同的程序可以连接 到服务器并且取回和更新信息。应用程序(客户端)通过 HSQLDB 的 JDBC Driver 连接 服务器。在大多数的服务器模式中,服务器可以在运行的时候被指定为最多 10 个数据库 服务。 服务器模式可以预设置属性和命令行参数,详见“高级主题”一章。根据客户端和服务器之 间通信协议的不同,Server 模式可以分为以下三种: HSQLDB 用户指南 2 运行和使用 Hsqldb 1.4.1 Hsqldb Server 这种模式是首选的也是最快的。它采用 HSQLDB 专有的通信协议。启动服务器的命令和 上面所述的运行工具命令类似。下例中启动服务器的命令启动了带有一个(默认为一个数 据库)数据库的服务器,这个数据库是一个名为"mydb.*"文件。 java -cp ../lib/hsqldb.jar org.hsqldb.Server -database.0 mydb -dbname.0 xdb 命令行参数-?可以用来查看该命令的参数列表。 1.4.2 Hsqldb Web Server 这种模式只能用在通过 HTTP 协议访问数据库服务器主机时。采用这种模式唯一的原因是 客户端或服务器端的防火墙对数据库对网络连接强加了限制。其他情况下,这种模式不推 荐被使用。HSQLDB Web Server 器是可以允许 JDBC 客户端通过 HTTP 连接的特殊的 Web Server。从 1.7.2 版本开始,这种模式也支持事务处理。 运行 web 服务器的时候,只要将上例命令行中的主类(main class)替换称下面的类: org.hsqldb.WebServer 命令行参数-?可以用来查看该命令的参数列表。 1.4.3 Hsqldb Servlet 这种模式和 Web Server 一样都采用 HTTP 协议,当如 Tomcat 或 Resin 等 servlet 引擎(或 应用服务器)提供数据库的访问时,可以使用这种模式。但是 Servlet 模式不能脱离 servlet 引擎独立启动。为了提供数据库的连接,必须将 HSQLDB.jar 中的 hsqlServlet 类放置在应 用服务器的相应位置。这种模式下的数据库采用应用服务器指定的属性,可以参考 hsqlServlet.java 的源文件查看详细信息。 Web Server 和 Servlet 模式都只能在客户端通过 JDBC 驱动来访问。两者都不提供数据库 的 web 前台终端(front end)。Servlet 模式只能启动一个单独的数据库。 请注意做为应用程序服务器的数据库引擎通常不使用这种模式。 连接到以 Server 模式运行的数据库 当 HSQLDB 服务器运行时,客户端程序就可以通过 hsqldb.jar 中带有的 HSQLDB JDBC Driver 连接数据库。如何连接服务器的详细说明可以参见 jdbcConnection 的 Java 文档(位 于 HSQLDB 发布包/doc/src 目录中)。下面是一个简单的例子,它采用 hsqldb 协议连接到 本机的默认的 9001 端口。 HSQLDB 用户指南 3 运行和使用 Hsqldb Example 1.1. Java code to connect to the local Server above try { Class.forName("org.hsqldb.jdbcDriver" ); } catch (Exception e) { System.out.println("ERROR: failed to load HSQLDB JDBC driver."); e.printStackTrace(); return; } Connection c = DriverManager.getConnection("jdbc:hsqldb:hsql://localhost/xdb", "sa", ""); 有些情况下,你也可以使用下面的代码来获取驱动(driver). Class.forName("org.hsqldb.jdbcDriver").newInstance(); 可以注意到,在上面的连接 URL 中,没有提到数据库文件,因为这些在服务器运行时,数 据库文件就已经被指定为 dbname.0 的值了。对于不止有一个数据库的服务器实例连接 URL 也可以阅读“高级主题”一章。 安全因素的考虑 HSQLDB 作为服务器运行的时候,网络访问应该受到充分的保护。源 IP 地址可能会因为 TCP 过滤、防火墙程序或者独立的防火墙的使用,而受到限制。如果数据通信要穿越一个 不受保护的网络(比如 Internet 时),数据流应该被加密(比如采用 VPN,SSh 隧道或者 TLS)。只有安全的密码才可以使用——最重要的是,应该将为系统默认用户设置的空字符 串密码修改为安全密码。如果你想公开自己的数据的话,那么完全开放的网络连接应该限 制为只有通过只读的帐号来访问这些公开的数据。(比如,对于非机密数据或非特权用户可 以考虑使用这种连接方式)。这些考虑因素也适用于采用 HTTP 协议运行 HSQLDB 服务器 的情况下。 1.4.4 In-Process(Standalone)模式 这种模式下,数据库引擎作为应用程序的一部分在同一个 JVM 中运行。对于一些应用程序 来说, 这种模式因为数据不用转换和通过网络的传送而使得速度更快一些。其主要的缺点 就是默认的不能从应用程序外连接到数据库。所以当应用程序正在运行的时候,你不能使 用类似于 Database Manager 的外部工具来查看数据库的内容。在 1.8.0 版本中,你可以 从同一个 JVM 的一个线程里面来运行一个服务器实例作为您的应用程序,从而可以提供外 部连接来访问你的 In-Process 数据库。 在一个应用程序里,推荐的使用 In-Process 模式方式是:开发的时候为数据库使用一个 HSQLDB 服务器实例,然后在部属的时候转换到 In-Process 内模式。 HSQLDB 用户指南 4 运行和使用 Hsqldb 一个 In-Process 模式数据库是从 JDBC 语句开始启动的,在连接 URL 中带有指定的数据 库文件路径作为 JDBC 的一部分。例如,假如数据库名称为 testdb,它的数据库文件位于 与确定的运行应用程序命令相同的目录下,下面的代码可以用来连接数据库的: Connection c = DriverManager.getConnection("jdbc:hsqldb:file:testdb", "sa", ""); 数据库文件的路径格式在 Linux 主机和 Windows 主机上都被指定采用前斜线(”/”)。所以 相对路径或者是相对于相同分区下相同目录路径的表达方式是一致的。例如,在 Linux 系 统中你的数据库文件路径为/opt/db/testdb,你可以在 Windows 的 C:分区下,创建一个相 同的目录结构,然后你可以在 Linux 和 Window 下采用相同的 URL: Connection c = DriverManager.getConnection("jdbc:hsqldb:file:/opt/db/testdb", "sa", ""); 使用相对路径的时候,这些路径表示的是相对于用于启动 JVM 的 shell 命令的执行路径。 你可以参考 jdbcConnection 的 Java 文档来获得更多详细信息。 1.4.5 Memory-Only 数据库 HSQLDB 还可以用这种方式运行——数据库不是持久化的而是全部在随机访问的内存中。 因为没有任何信息写在磁盘上,所以这种模式只能用于应用数据的内部处理上,比如在 applet 或其他的一些特殊的应用程序中。这种模式通过 mem:协议的方式来指定: Connection c = DriverManager.getConnection("jdbc:hsqldb:mem:aname", "sa", ""); 你也可以在 server.properties 中指定相同的 URL 来运行一个 Memory-Only(仅处于内存 中)服务器实例。这种用法不太通用,它被限制仅在使用数据库服务器来交换两个客户端 的数据或者是非持久化数据的特殊应用程序中使用。 1.5 一般操作 1.5.1 关闭数据库 以不同模式运行的所有数据库都可以通过以 SQL 语句发出的 SHUTDOWN 命令来关闭。 从 1.7.2 版本以来,当上次对数据库的连接通过 JDBC 被显式关闭之后,in-process 模式 的数据库还是不会被关闭,除非使用 SHUTDOWN 命令。当 SHUTDOWN 命令发出,所 有的活动事务(active transactions)都会被回滚(rolled back)。关闭数据库的一种特殊 形式是通过 SHUTDOWN COMPACT 命令。该命令重写.data 文件,这个文件包含了存储 在 CACHED 表中的信息,该命令并对该文件的大小进行精简(compact)。这个命令应该被 定时执行,特别是在 cached 表中执行了许多插入,更新和删除操作的时候。数据库结构 的变换,比如删除、更改表或者索引,会产生大量未使用的空间,不扩可以通过此命令进 行空间的回收利用。 HSQLDB 用户指南 5 运行和使用 Hsqldb 1.5.2 在一个 JVM 里使用多数据库 在上述的例子中,每个服务器只能有一个数据库工作以及仅能创建一个 In-Memory 数据 库。不过,从 1.8.0 版本以来,HSQLDB 能够以多个服务器模式为多个数据库工作,它允 许对 In-Process 数据库和 memory-only 数据库进行并发访问。 这些性能在“高级主题”一 章进行了叙述。 1.5.2 创建新数据库 当一个服务器实例启动或者建立一个 in-process 数据库连接的时候,如果指定的路径没有 数据库存在,那么就会创建一个新的空的数据库。 这个特点的副作用就是让那些新用户产生疑惑——在指定连接已存在的数据库路径的时 候,如果出现了什么错误的话,就会建立一个指向新数据库的连接。为了解决这个问题, 你可以指定一个连接属性 ifexists=true 只允许和已存在的数据库建立连接而避免创建新的 数据库,如果数据库不存在的话,getConnection()方法将会抛出异常。 1.6 使用数据库引擎 一旦以任何模式建立了和数据库的连接,就可以使用 JDBC 方法和数据库交互。对于 jdbcConnection , jdbcDriver, jdbcDatabaseMetadata, jdbcResultSet , jdbcStatement, 和 jdbcPreparedStatement 的 JavaDoc 列出了所有支持的 JDBC 方法以及对 HSQLDB 的详 细说明信息。JDBC 方法大体上可以分为:与连接相关的方法,元数据方法,数据库访问 方法三种。数据库访问方法使用 SQL 命令来在数据库上执行操作,返回的结果既可以是 Java 原始数据类型,又可以是 java.sql.ResultSet 类的实例。 你可以使用 Database Manager 或者其他 Java 数据库访问工具来查看数据库的内同,并 可以用 SQL 命令来更新数据库。这些程序使用内部 JDBC 向数据库引擎提供你的命令, 并用自然语言的格式来显示结果。 HSQLDB 中使用的 SQL 方言(dialect)与 SQL92 和 SQL200n 标准比较接近,到目前位 置 HSQLDB 在小型数据库引擎中已经有可能这两个标准。“SQL 语法”一章列出了所有的 SQL 命令。 1.6.1 不同类型的表 HSQLDB 支持临时表和三种持久化表。 TEMP(临时)表是不写入磁盘,它仅仅只维持一个Connection对象的生命周期。每一个 TEMP表仅仅对创建它的Connection来说是可见的,其他和数据库并发的连接是无法访问 TEMP表的。从1.8.0版本开始,在SQL标准里,TEMP表的定义和GLOBAL TEMPORARY HSQLDB 用户指南 6 运行和使用 Hsqldb 类型是一致的。表的定义是持久的但是每个新的连接只能看到它自己的表,而这些表刚开始 是空的。当连接提交以后,临时表里的内容默认的被清空。如果临时表的定义语句里边包括 ON COMMIT PRESERVE ROWS,那么当连接提交发生时,临时表的内容将被保存。 三种类型的持久化表一次是 MEMORY(内存)表,CACHED(缓存)表和 TEXT(文本 符)表。 Memory 表是 CREATE TABLE 命令创建的默认的表类型。Memory 表数据全部驻留在内 存中,但是对于表结构或内容的修改都被写入到.script 文件中。script 文件在下 次数据库打开的时候被 MEMORY 读取,里边的所有内容在 MEMORY 表中重新创建。所 以跟 TEMP 表不同, MEMORY 表被默认为是持久的。 CACHED 表是在使用 CREATE CACHED TABLE 命令的时候生成的。它只有索引或部分 数据是驻留在内存中的,所以可以允许生成容量为几百兆的表空间。CACHED 表的另外一 个优点,即使它存储了大量的数据,数据库引擎只需花费很短的时间就可以启动。它的不 足是在速度上有所降低。如果你的数据集相对小的时候,尽量不要使用 CACHED 表。在 小容量和大容量表共存的实际应用中,最好对哪些小容量的表使用默认的 MEMORY 表。 TEXT 表是在 1.7.0 版本中新增加的内容,它使用 CSV(逗号分割数值)或其他分隔符的 文本文件作为数据源。你可以指定一个已有的 CSV 文件(比如其它数据库或程序的数据) 作为 TEXT 表的数据源,你也可以指定一个空文件用数据库引擎来填充数据。TEXT 表的 内存利用效率比较高,因为它只缓存部分文本数据和所有的索引。TEXT 表的数据源如果 需要的话,可以重新分配给不同的文件。创建一个 TEXT 表所需的两个命令的详细资料请 查看 TEXT 表一章。 在 Memory-Only 数据库里,MEMORY 表和 CACHED 表的声明都看视作为非持久化的内 存表的声明。这种模式中是不允许声明 TEXT 表的 1.6.2 约束和索引 HSQLDB 支持 PRIMARY KEY, NOT NULL, UNIQUE, CHECK 和 FOREIGN KEY(依次译 作主键、非空、唯一性、检查、外键)约束。此外,它还支持唯一性索引或普通索引。这 些支持相当广泛,覆盖了多字段约束和索引,再加外键的级联更新和删除。 HSQLDB 在内部创建索引来支持主键约束、唯一性约束和外键约束:为每一个主键约束或 唯一性约束创建一个唯一的索引,为每个外键约束创建一个普通的索引。因为这些原因, 你不应该在受这些约束的同一字段集内创建重复的用户自定义索引。这将会导致不必要的 的内存和速度开支。你可以查看“SQL 问题”一章的讨论来获得更多的信息。 索引对于提高查询速度是至关重要的,当使用连接到多个表的查询时,对于每一个表的每 一个连接字段必须有一个索引。当使用范围或等式从句(比如:SELECT ... WHERE a >10 AND b = 0)时,需要为在条件中使用的列创建索引。但是索引在 ORDER BY 从句或某些 LIKE 条件中是没有任何作用的。 HSQLDB 用户指南 7 运行和使用 Hsqldb 通常,HSQLDB 具有每秒处理查询并返回超过 100,000 行的能力,如果需要的话,任何 花费数秒以上的查询应该被检查,并且应该对表中相应的列添加索引。 1.6.3 SQL 支持 HSQLDB 支持的 SQL 语法基本上是由 SQL 标准(92 和 200n)规定的。但 HSQLDB 也 不是支持标准的所有特性,还有一些自己特有的扩展,在 1.8.0 版本中,数据库引擎的性 能比老版本能更好的遵循标准,其主要的改变有: • 修正了在连接、唯一性约束或是在查询条件中的空列值的处理。 • 修正了采用连接和左外连接 select 的处理。 • 修正了包含在表达式中或包含表达参数的聚集函数的处理。 HSQLDB所支持的命令都列举在“SQL语法”一章。你可查看由Bruce Momjian写的 PostgreSQL: Introduction and Concepts一章,它是一部不错的SQL基本指南,在网上你 可以下载到它。书中所讲到的大多数SQL都可以用到HSQLDB中。但是在数据库引擎支持 的关键字(ALL, ANY, OUTER, OID's等)和使用不同的关键字上(IDENTITY/ SERIAL, LIMIT, TRIGGER, SEQUENCE等)存在着一些差异。 1.6.4 JDBC 支持 在 1.7.2 版本中,对于 JDBC2 的支持已经取得了重大的进展,而且现在已经开始支持 JDBC3 的部分特征。相关的类都已经文档化了,你可以查看 org.hsqldb.jdbcXXXX 类的 JavaDoc 获得帮助。 HSQLDB 用户指南 8 SQL 问题 第 2 章 SQL 问题 本章由李博、石建华翻译, 2.1 本章目的 在本章中就在 HSQLDB 主页论坛或邮件列表中多次出现的问题进行解答,如果你打算在应 用程序中使用 HSQLDB 的话,你最好阅读一下本章。 2.2 对 SQL 标准的支持 1.8.0 版本的 HSQLDB 支持 SQL92、99 和 2003 标准规定的 SQL 方言。这意味着 HSQLDB 中支持的标准特性(例如左外连接)的语法是有标准文本规定的。许多 SQL92、99 甚至更 高级的特征在 HSQLDB 中得到了支持,并且对 SQL2003 标准的大多数以及一些可选的特性 进行支持。然而,对于某些标准的特性没有支持,所以 HSQLDB 就没有做出支持各个级别 所有的标准特性的声明。 “SQL 语法”一章列出了 HSQLDB 所支持的所有的关键字和语法。当书写有关 HDBSQL 或者转换现有的有关 HSQLDB 的 SQL DDL(数据定义语言)和 DML(数据操作语言)语 句的时候,你应该查阅一下 HSQLDB 所支持的语法,并对 SQL 语句作出相应的修改。 SQL 标准中保留的关键字是不能作为表明或字段名使用的。例如,“POSITION”被作为与 Java 中的 String.indexOf()作用类似的函数加以保留。HSQLDB 目前对使用它并不支持其用 法或者能够区分清楚的关键字进行限制。例如,“ANY”和“BEGIN”是 HSQLDB 目前没 有支持的两个关键字,所以你也可使用它们两个来作为表或者列的名称。不过你应该避免使 用在 HSQLDB 将来版本中可能支持或者拒绝作为表定义或查询的保留字。全部 SQL 保留字 列表请参看 org.hsqldb.Token 类。 HSQLDB 也支持一些 SQL 标准之外的关键字和表达式作为性能的增强。像 as SELECT TOP 5 FROM .., SELECT LIMIT 0 10 FROM ... 或者 DROP TABLE mytable IF EXISTS 这样的表达 式都是 HSQLDB 增强性能所支持。 所有被双引号标注的关键字可以被用做数据库对象。 2.3 约束和索引 2.3.1 主键约束 在 1.7.0 版本之前,一个 CONSTRAINT PRIMARY KEY(名为 name 的主键约束) HSQLDB 用户指南 9 SQL 问题 被在内部翻译成一个唯一的索引,另外,一个隐藏列被添加到具有额外唯一索引的表上。从 1.7.0 开始,单一列主键和多列主键(single-column and multi-column PRIMARY KEY)约束都得 到支持。它们由主键列指定的唯一索引支持,而没有额外的隐藏列来维护它们的索引。 2.3.2 唯一性约束 根据 SQL 标准,一个单一列上的唯一性约束表示不允许存在两个相同的值(空值出外),也 就是说这样的列中可以一个或更多值为空(NULL)的行而不违反唯一性约束。 多个列(c1, c2, c3, ..)的唯一性约束表示这些列中的任何两个值的集合都不相等(除非至少其 中有一个为空)。每一个单一列内部可以有重复的值。下面这里满足两列上的唯一性约束。 例 2.1. 满足 2 列唯一性约束的列值 1, 2 2, 1 2, 2 NULL, 1 NULL, 1 1, NULL NULL, NULL NULL, NULL 自从 1.7.2 版本以来,对于空值的唯一性约束和索引的处理已经向遵循 SQL 标准过渡。唯一 性约束列的值全为空的行通常都可以被添加到表中,所以对于唯一性约束的列来说,如果其 中的一个行的值为空,那么多个行就可以具有相同这样的值。 2.3.3 唯一性索引 在 1.8.0 中,用户定义的唯一性索引仍然可以进行声明,但是它已经不被赞成使用了,你应 该使用一个唯一性约束来替代唯一性索引。 像在早期版本的 HSQLDB 中一样,名为的唯一性约束通常在内部创建列的索引,所 以它实际上和已经废除的唯一性索引声明具有相同的效果。 2.3.4 外键 HSQLDB 从 1.7.0 版开始具有单一列外键和多列外键。一个外键也可以被指定引用一个没有 命名目标列的目标表。在这种情况下,目标表的主键列被用作引用列。任何外键中的一对引 用和被引用的列应该具有相同的数据库类型。当声明了一个外键时,主键表被引用的列必须 HSQLDB 用户指南 10 SQL 问题 具有一个唯一性约束(或主键),而在引用列里会自动创建一个非唯一性索引。例如: CREATE TABLE child(c1 INTEGER, c2 VARCHAR, FOREIGN KEY (c1, c2) REFERENCES parent(p1, p2)); parent 表中的 (p1,p2) 列一定存在一个唯一性约束。child 表中的(c1,c2)列会自动生成一个非 唯一性索引。p1 和 c1 列一定具有相同的类型(INTEGER),p2 和 c2 列一定具有相同的类 型(VARCHAR)。 2.3.5 索引和查询速度 HSQLDB 没有使用索引来改善查询结果的分类,但是索引在提高查询速度上起着至关重要 的作用。如果一个表没有使用索引,进行类似于 DELETE 这样的查询操作的时候,表中所 有的行记录都要被检查一遍。WHERE 从句中的列有一个索引的话,那么查询操作就可能直 接从第一个候选列开始,从而减少了要检查的列的数量。 索引在多个表之间进行连接操作的时候显得更重要。在 SELECT ... FROM t1 JOIN t2 ON t1.c1 = t2.c2 执行的时候,对 t1 中的行一个接一个的进行操作,来查找 t2 中没有与之匹配的 行。如果没有 t2.c2 没有任何索引的话,那么,对于 t1 的每一行来说,要必须检查 t2 的所有 行。然而有一个索引的话,在很短的时间内就能找到匹配的行。如果,查询(query)在 t1 上 还有一个条件(例如,SELECT ... FROM t1 JOIN t2 ON t1.c1 = t2.c2 WHERE t1.c3 = 4),那 么在 t1.c3 上创建一个索引的话,将会消除一个接一个的检查所有行的需要,并且将没返回 一行的查询时间降低到 1 个毫秒以下。所以,如果 t1 和 t2 各有 10000 行记录,那么没有索 引的查询将会检查 100,000,000 各行的结合。如果在 t2.c2 上创建一个索引的话,查询时间将 会降低到只对 10000 行进行检查和对索引的查找。在 t2.c2 上有一个附加索引的话,只需要 检查 4 行就可以得到第一个符合条件的结果行。 对于主键和唯一列,将对自动生成索引,否则,你应该是用 CREATE INDEX 命令行来定义 索引。 注意:在 HSQLDB 中,多列(multiple columns)上的一个唯一性索引可以在内部用作列表 第一列上的非唯一性列。例如,ONSTRAINT name1 UNIQUE (c1, c2, c3);表示这是 CREATE INDEX name2 ON atable(c1)等价的表示方式,所以你只要列表第一列中一个的话,就不需要 指定一个额外的索引。 在 1.8.0 版本中,一个多列的索引将会加速包含所有列的连接和值的查询。你不需要在这些 列上声明任何附加的单独的索引,除非你仅对这些列子集进行查询。例如,在三个列上拥有 主键约束或唯一性约束或只一个普通的索引的表的行记录,在三个列的值都在 WHERE 从 句中指定了时候,查询就会比较高效。例如,SELECT ... FROM t1 WHERE t1.c1 = 4 AND t1.c2 = 6 AND t1.c3 = 8 将会使用 t1(c1,c2,c3)上的索引(如果存在的话)。 作为多键索引改进的结果,和以前想比,索引或约束声明列的顺序带给查询速度的影响大大 减少。如果包含多较多不同值的列第一次出现,查询速度将会有一点提高。 HSQLDB 用户指南 11 SQL 问题 一个多列索引不会加快仅对第二列或第三列查询的速度。第一列必须在 JOIN .. ON 或者 WHERE 条件中指出。 查询速度很大程序上取决于 JOIN .. ON 或者 FROM 从句中表的顺序。例如,下面的第二 个查询在大的表中会更快一些(假如 TB.COL3 上有索引的话)。因为,如果下面的查询被用 到第一表中(以及 TB.COL3 上有索引)的话,TB.COL3 可以很快的估计出来: (TB 是一个很大的表,但符合 TB.COL3=4 条件的仅仅只有几行记录) SELECT * FROM TA JOIN TB ON TA.COL1 = TB.COL2 AND TB.COL3 = 4; SELECT * FROM TB JOIN TA ON TA.COL1 = TB.COL2 AND TB.COL3 = 4; 基本规则是将这样表放在首位:其中的一个列上具有一个缩小的条件(narrowing condition)。 1.7.3 版本的 HSQLDB 具有为视图或用在查询中的子选择(subselect)创建自动的,快速的 (on-the-fly)索引的特征。当一个索引被连接到一个表或一个视图的时候,会被添加到一个不 同于所连接的视图里。 2.3.6 Where 条件或者连接 使用 WHERE 条件连接表可能会降低执行速度。例如下面的查询通常会比较慢,甚至有索 引的时候: SELECT ... FROM TA, TB, TC WHERE TC.COL3 = TA.COL1 AND TC.COL3=TB.COL2 AND TC.COL4 = 1 上面的查询暗示 TA.COL1 = TB.COL2但是却没有显式地设置条件。如果 TA 和 TB 每个都含有 100 行的记录,那么即使在被连接的列上建有索引的是,也有 10000 个组合 combinations) 被连接到 TC 来满足这些列的条件。使用 JOIN 关键词,条件 TA.COL1 = TB.COL2将必须被显 示声明,它将会使 TA 和 TB 行在被 TC 连接前降低它们的结合(combinations)次数,这样 将会使对大表查询的执行大大加快: SELECT ... FROM TA JOIN TB ON TA.COL1 = TB.COL2 JOIN TC ON TB.COL2 = TC.COL3 WHERE TC.COL4 = 1 如果连接种表的顺序改变了的话,那么下面查询的执行速度会被大大加快,所以使用了 TC.COL1 = 1 以及将列的行的较小集合连接在一起: SELECT ... FROM TC JOIN TB ON TC.COL3 = TB.COL2 JOIN TA ON TC.COL3 = TA.COL1 WHERE TC.COL4 = 1 在上述的例子中,数据库引擎将 TC.COL4 = 1 自动应用到 TC,仅仅连接了行的集合来使这 个条件也满足其他的表。TC.COL4, TB.COL2 和 TA.COL1 上的索引如果存在的话将会被使用, 进而加速查询。 HSQLDB 用户指南 12 SQL 问题 2.3.7 子查询和连接 使用连接及为获得最大性能而设置表的顺序适用于所有的环节,例如,下面的第二个查询通 常情况下比第一个更快,因为 TA.COL1 和 TB.COL3 有索引的缘故。 例 2.2. 查询比较 SELECT ... FROM TA WHERE TA.COL1 = (SELECT MAX(TB.COL2) FROM TB WHERE TB.COL3 = 4) SELECT ... FROM (SELECT MAX(TB.COL2) C1 FROM TB WHERE TB.COL3 = 4) T2 JOIN TA ON TA.COL1 = T2.C1 第二个查询将 MAX(TB.COL2)转变成一个单行的表,但后将它连接到 TA。因为 TA.COL1 上存在索引,所以这个查询的速度会非常快。第一个查询将会测试 TA 中的每一行记录,重 复的对 MAX(TB.COL2)进行估算。 2.4 类型和算术操作 HSQLDB 支持的所有类型的数据库表都可以被索引,也可以进行比较。所有的类型都可以 用 CONVERT()库函数进行显示转换,但是在大多数情况下它们可以被自动的转换。不推荐 在 LONGVARBINARY, LONGVARCHAR 和 OTHER 列使用索引,因为这些索引可能在将 来的版本中是不允许的。 早期版本的 HSQLDB 在算术操作的处理上有些不足。例如,不可能把 10/2.5 插入到任何 DOUBLE 或者 DECIMAL 列。在 1.7.0 版本中,遵循下列规则的全操作(full operations)是可 能的: TINYINT, SMALLINT, INTEGER, BIGINT, NUMBER 和 DECIMAL(没有小数点)是 HSQLDB 支持的整值类型,它们在 Java 中被映射成 byte, short, int, long 和 BigDecimal。SQL 类型规定了最大值和最小值,这些值可以存在于(be held)每一个类型的一个域(field)里 面。例如,TINYINT 的值范围是从-128 到 +127,虽然实际用于处理 TINYINT 类型的 Java 类型是 java.lang.Integer。 REAL, FLOAT, DOUBLE 在 Java 中都被映射成 double。 DECIMAL 和 NUMERIC 被映射成 java.math.BigDecimal,它们可以有很多的位数。 2.4.1 整型类型 TINYINT, SMALLINT, INTEGER, BIGINT, NUMBER 和 DECIMAL(不带小数点)在内部都 是完全可以互换的,不存在数据窄化(narrowing)的情况。根据不同的操作数类型,返回的操 HSQLDB 用户指南 13 SQL 问题 作结果是以任何相关的 Java 类型(Integer, Long or BigDecimal)存在于 JDBC 结果集中的。 只 要返回值可以被结果类型所表示,ResultSet.getXXXX()方法就能够用来获取数据同时返回值 也可以被结果类型描述。这个类型是基于查询的,而不是实际返回的列。当返回一行的相同 查询因往数据库的表中添加了更多数据之后返回多行记录的时候,返回的类型不发生变化。 如果 SELECT 语句涉及到一个单列或者一个函数的话,那么返回类型就是所对应的列或者 函数的返回类型。例如: CREATE TABLE t(a INTEGER, b BIGINT); SELECT MAX(a), MAX(b) FROM t; 将会返回一个结果集,其第一列的类型是 java.lang.Integer,第二列的类型是 java.lang.Long。 然而, SELECT MAX(a) + 0, MAX(b) + 0 FROM t; 将返回 java.lang.Long 和 BigDecimal 的值, 它是作为所有返回值的统一类型的提升生成 的。 在表达式中的中间整形数值的大小上,没有内建的限制。因此,你应该检查结果集列的类型, 选择一个合适的 getXXXX()方法来获取该值。另外你也可以使用 getObject()方法,然后,将 结果转换成 java.lang.Number,在结果上使用 intValue() 或 longValue()方法。 当表达式的结果存在在数据库表的一个列中,它必须适合目标列,否则,会返回一个错误。 例如,当计算 1234567890123456789012 / 12345687901234567890 时,结果可以被存储在任 何类型的列中,甚至是个 TINY 列,因为它是一个很小的值。 2.4.2 其他数据类型 在 SQL 语句中,除非带有额外的说明,带有小数点的数字都被当作 DECIMAL 处理。因此 0.2 被认为是 DECIMAL 类型的值,而 0.2E0 则被看作 DOUBLE 类型。 当对某个值使用 PreparedStatement.setDouble()或 setFloat()方法时,该值就被自动默认为 DOUBLE 类型处理。 当表达式的一部分是 REAL、FLOAT 或者 DOUBLE(所有同义的类型)类型时,那么结果 类型则是 DOUBLE。 此外,当 DOUBLE 类型不存在时,如果表达式的一部分是 DECIMAL 或 NUMERIC 类型时, 结果类型就是 DECIMAL。结果可以按照需要的类型从 ResultSet 中取出,同时也可以被再 定义。这就意味着如果一个 DECIMAL 值的范围在 Double.MIN_VALUE- Double_MAX_VALUE 之间,那么它就可以被转换成 DOUBLE 类型。和整形数值相似,当 表达式结果存入表的列中时,它的类型必须符合该列的类型,否则将有错误出现。 HSQLDB 用户指南 14 SQL 问题 进行除法运算时,DOUBLE 和 DECIMAL 类型间的区别就显得很重要的。当操作数类型是 DECIMAL,结果是一个带有取值范围(小数点右边的位数)的数据,那么就取两个操作数 中范围中较大的。如果是 DOUBLE 类型,那么范围则是运算的精确结果。例如,10.0/8.0 (DECIMAL)等于 1.2,但是 10.0E0/8.0E0(DOUBLE)等于 1.25。如果不是除法运算, DECIMAL 类型能精确的描述算法;如果两个相乘,那么范围就是两个数范围的和。 REAL、FLOAT 和 DOUBLE 类型数值都被当作 java.long.Double 对象存入数据库中。同时也 可以存储和支持一些特殊值如 NaN 和正负无穷。这些值可以通过 JDBC PreparedStatement 方法提交给数据库,并且可以以结果集对象返回。 2.4.3 二进制和 Boolean 类型 从 1.7.2 开始,BIT 通常也可以看作 BOOLEAN 的化身。BOOLEAN 列的主要描述是’true’ 或’false’,通过 JDBC 使用时,可以被看作 boolean 或者 String 类型。BOOLEAN 列的类型 还可以使用任何数字类型的值进行初始化。这样的情况下,0 将被转化成 false,其他非 0 值 将被转换成 true。 从 1.7.3 开始,BOOLEAN 类型除了支持 TRUE 和 FALSE 类型以外,也提供了对 UNDEFINED 状态的支持,从而与 SQL 标准取得了一致。NULL 值被当作没定义类型处理。这一改进影 响了那些包含 NOT IN 的查询。这样的查询语句,请参看测试文本文件 TestSelfNot.txt。 2.4.4 Java 对象的存储和操作 从 1.7.2 开始,对 Java 对象的存储和操作的支持有了很大的提高,通过使用任一个改变了的 PreparedStatement.setObject()方法,任一个序列化的 JAVA 对象都可以被直接的插入到 OTHER 类型的列中。 为了比较参照,在索引里边,任何两个 Java 对象都被看作是相等,除非他们中的一个是 NULL。在 OTHER 类型的列中,你不能搜索一个指定的对象或者进行连接操作。 请注意,HSQLDB 不是一个对象-关系数据库。Java 对象只是在内部存储,除了在 OTHER 类型列之间分配或测试是否为 NULL 之外,不能对他们进行其他的操作。测试例如 WHERE object1=object2,或者 WHERE ojbect1=?并不能得到你预期的结果。任何非空的对象都能满 足这样的测试。但是 WHERE object1 IS NOT NULL 就能很好的执行。 正规列的数据被分配给 Java 对象列(例如该列被分配整型或字符串时的 SQL 语句如 UPDATE mytable SET objectcol = intcol WHERE…)时并不会返回错误,但在将来,这样的 做法时很不赞成的。因此请使用 OTHER 类型列来存贮对象而不是其他类型的数据。 HSQLDB 用户指南 15 SQL 问题 2.4.5 类型的大小、精度和范围 在 1.7.2 版本以前,所有表中对一个列的大小、精度或范围的限制的类型定义是可有可无的。 在 1.8.0 版本中,这样的限定必须和 SQL 标准一致。例如 INTEGER(8)这样的形式将不能 被接受。除非设置了数据库的属性,这个限定仍然是可有可无的。SET PROPERTY”sql.enforce_strict_size” TRUE 语句将为 CHARACTER 或 VARCHAR 列强制设置 大小,并且当插入或更新一个 CHARACTER 列时填充字符串。精度和范围限制也被强加给 DECIMAL 和 NUMERIC 类型。TIMESTAMP 只能使用 0 或 6 这样的精度。 如你所料,将一个值转换成一个限定的 CHARACTER 类型将导致切割或填充。因此象 CAST(mycol AS VARCHAR(2))=’xy’这样的测试语句结果得到以 xy 开头的值。这和 SUBSTRING(mycol FROM 1 FOR 2)=’xy’是相同的。 2.5 序列和标识 SEQUENCE 关键字作为 SQL200n 标准语法的子集被引入到 1.7.2 版本中。相应的,IDENTITY 列的 SQL200n 语法也被引进。 2.5.1 标识自动增长列 每个表都可以有一个自动增长列,众所周知的就是 IDENTITY 列。一个 IDENTITY 列总是 被当作表的主键处理(因此,多列主键不可能有一个 IDENTITY 列)。作为一个捷径,已经 为 CREATE TABLE (IDENTITY,…)提供了支持。 从1.7.2版本开始,SQL标准语法默认的支持指定初始值。支持的形式是: ( INTEGER GENERATED BY DEFAULT AS IDENTITY(START WITH n, [INCREMENT BY m])PRIMARY KEY, ...).。同时也对BIGINT特性列提供了支持。因此,一个IDENTITY列和 一个自动顺序的产生默认值的INTEGER或者BIGINT列很相似。 当使用INSERT INTO …语句向表中添加一个新列时;你可以在IDENTITY列中 使用NULL值,这样将为列产生一个自动生成的值。IDENTITY()函数返回通过连接插入 到IDENTITY列中的最后一个值。使用CALL IDENTITY()这个SQL语句取得这个值。如 果想在子表中使用这个值,你可以使用语句INSERT INTO VALUES(..., IDENTITY(),...);。在任何附加的更新或插入语句在数据库中执行前,调用IDENTITY()函 数的类型必须被确定。 接下来要使用的的IDENTITY值可以通过语句ALTER TABLE ALTER COLUMN RESTART WITH ;来设置。 HSQLDB 用户指南 16 SQL 问题 2.5.2 序列 SQL200n语法和用法和现有的大多数据库引擎所支持的是有区别的。Sequences通过命令 CREATE SEQUENCE创建并且他们的当前值可以通过命令ALTER SEQUENCE在任何时候 进行修改。一个sequence的下一个值是通过NEXT VALUE FOR 表达式取得。这个表 达式可以用来插入或者更新表的行,你也可以在select语句中使用它。例如,如果想计算在 一个Sequence序列中SELECT返回的行,可以使用: 例2.3 计算选择操作以后返回的行 SELECT NEXT VALUE FOR mysequence, col1, col2 FROM mytable WHERE ... 请注意,顺序的语义并不合SQL200n定义的完全相同。例如,如果你在相同的列插入操作中 两次使用相同的序列,你将会得到两个不同的值,而不是标准所说的同一个值。 你可以通过查询SYSTEM SEQUENCES表得到下一个值,这个值将从任何定义的序列中返 回。SEQUENCE_NAME列保存了名称,NEXT_VALUE列保存了下一个被返回的值。 2.5.3 事务的问题 HSQLDB在READ_UNCOMMITTED级别上支持事务,就象0级别上的事务隔离。这就意味 着在一个事务的生命周期内,其他数据库的连接可以看到这个事务对数据的改变。总的来说, 对事务的支持还是不错的。象如果数据库突然关闭而事务被提交这样的BUG已经被修复了。 然而,对于多个连接同时使用事务连接到数据库这样的问题就比较麻烦了。 如果两个事务修改同一行,而两个事务提交时没有异常出现。这样的情况可以通过设计应用 程序数据的一致性不依赖通过事务对数据修改的独占性这样的数据库而避免。你可以通过设 置一个数据库属性,从而在这样的情况发生时会产生一个异常:SELECT NEXT VALUE FOR mysequence, col1, col2 FROM mytable WHERE ... 当一个ALTER TABLE…INSERT COLUMN或者DROP COLUMN命令导致数表的结构变化 时,当前的会话被提交。如果一个未授权的事务此时通过另一个连接改变表中的数据,那么 这个事务在ALTER TABLE命令前不应被回滚。这一点同样也适用于ADD INDEX 或ADD CONSTRAINT命令。只有在其他连接没有使用事务时,才推荐使用ALTER等这样的命令。 在CHECKPOINT命令运行以后,未授权事务才能继续运行、提交或回滚。然而,如果数据 库并没有使用SHUTDOWN命令正常的关闭的话,任何事务在数据库关闭时仍被看作是未授 权的,将被看作下次启动数据库以后的事务(在CHECKPOINT的状态)的一部分。无论程 序中没有未授权的事务,还是知道事务不会因为持续过长时间而发生的非正常关闭影响数 据,都推荐使用CHECKPOINT。 HSQLDB 用户指南 17 SQL 问题 2.5.4 新特性和变化 在最新的1.8.0版本中增加了许多更好的对SQL的支持。这些都在SQL语法这一章和文 件../changelog_1_7_2.txt中列出了。象POSITION(),SUBSTRING(), NULLIF(), COALESCE(), CASE ... WHEN .. ELSE, ANY, ALL这样的表达式和函数也在其中。另外一些改进虽然在文 档中不是很明显,但能使数据库性能比以前版本有很大的改进。这其中最重要的就是能在连 接(join)和外连接(OUTER joins)中处理NULL值。你应该对使用新版本数据库引擎的应 用程序进行测试,确定这些程序不再使用旧版本的那些错误的特性。在将来的版本中,数据 库引擎仍将朝着完全支持SQL标准的方向改进,因此最好不要依赖当前版本中任何的非标准 特性。 HSQLDB 用户指南 18
还剩21页未读

继续阅读

下载pdf到电脑,查找使用更方便

pdf的实际排版效果,会与网站的显示效果略有不同!!

需要 5 金币 [ 分享pdf获得金币 ] 0 人已下载

下载pdf

pdf贡献者

zhaolaiwei

贡献于2012-05-30

下载需要 5 金币 [金币充值 ]
亲,您也可以通过 分享原创pdf 来获得金币奖励!
下载pdf