过去的许多应用程序都需要能够生成序号(例如获取下一个可用的帐号)。问题是该工作通常是通过用单个控制表存储这些数字,然后用可重复读(Repeatable Read)的 SELECT MAX 在随后的 INSERT 中检索并使用该数字来完成的。常常有多个事务需要使用该表,而这就导致了应用程序中无法解决的单点竞争。这是由于每次只有一个事务可以检索下一值,因为事务必须锁定该表以使数字增量。请参阅图 1。
在过去多年中曾经尝试过许多创造性的解决方案,例如使用行级的锁定,但是这些技术产生的系统开销加上成千上万个并发事务间的冲突仍然会导致性能瓶颈。如果用于数据共享的环境中,其中将有多个成员使用该表,那么它也会导致单点故障并且产生巨大的锁定开销。
|
|
因而在较晚的版本 6 中就出现了 Identity 列,用以解决前面提到的问题。如果一个表指派了 Identity 列,那么当向该表插入一行时,将根据 Identity 列的定义(START WITH 和 INCREMENT BY 值)来填充它。虽然使用 Identity 列要远胜于使用单个控制表,但是 Identity 列在使用方面却非常有限并且存在管理问题。
在版本 8 之前,Identity 列还带来了一些问题,例如:
- 如何获得 Identity 列的值来填充 RI 有关的表?
- 如何在插入之前获取值?
- 如何重新设置或更改 Identity 列的值?
这还仅仅只是一部分问题。许多公司围绕这些问题开发了一种方法,他们从表中删除 Identity 列然后创建一个只含 Identity 列及其生成值的表。因此,上述问题,例如重新开始 Identity 列的值或填充 RI 有关的表,都可以通过使 Identity 列与表分离而得到解决。该技术仍然允许由 DB2 来填充 Identity 列的值,并且减少了许多限制。但还是必须要对该表进行填充、访问和维护,并且它无法解决 Identity 列的所有问题以及无法完全开发与由 DB2 执行数字生成相关的潜在性能。图 2 是一个展示如何使用该技术的例子。
版本 8 已经缓解了上述 Identity 列的部分问题,例如使用 SELECT 功能中的新的 INSERT 进行插入之前可以获得 Identity 列的值。下面这个例子展示了如何在插入时使用该功能来获取 Identity 列的值。
(假定所创建的表以自动生成的 ACCT_ID 为 Identity 列)
例 1
SELECT ACCT_ID
FROM FINAL TABLE
(INSERT INTO UID1.ACCOUNT (NAME, TYPE, BALANCE)
VALUES ('Master Card', 'Credit', 50000) )
版本 8 中还可以更改其他一些值,例如:
CACHE/NO CACHE
CYCLE/NO CYCLE
MINVALUE
MAXVALUE
INCREMENT BY
RESTART WITH
这些执行更改的功能,特别是 RESTART WITH,给 Identity 列的使用带来了更大的灵活性。然而,这些功能是定义在单个表上的,这一本质使它们仍然受到了一些限制,而且应用程序对它们的利用也仍然有限。此外,这些更改还将导致表空间被置于 REORG 暂挂状态,从而导致表无法获得表空间。
|
|
在首次宣布 Sequence 对象时,我认为它们只是为了将应用程序从其他数据库移植到 DB2 而向 DB2 添加的另一功能。但是我越是深入地研究它们,就越是开始喜欢这些新的对象了,因为它们消除了我们对于 Identity 列的许多限制,而且它们还具有许多独特且有用的功能。它还向我们提供了数字生成的另一备选方法。
Sequence 对象是用户定义的对象,用以根据其创建规范生成数值序列。 它们提供一个由 DB2 生成的增量计数器,并且与 Identity 列十分相似。可将 Identity 列当作一种特殊的 Sequence 对象;但是,sequence 列与表是分开的。
Sequence 对象值可因为各种理由而用于应用程序中。这样做有一些好处,例如:
- 无需等待值的增加;
- 独立的连续数字生成对象(不与表关联);
- 递增或递减地生成数字;
- 用于从其他数据库移植应用程序;
- 可以生成键,用以跨多个表(RI 或相关的应用程序)协调各键。
序列名由两部分组成:128 字节的模式名和 128 字节的标识符。它们是通过新的 CREATE SEQUENCE 语句创建的,并且其所有属性完全都是由用户定义的(您也可以使用默认值)。Sequence 对象中的值可以是任何数字数据类型。初值是用 START WITH 值定义的,而增量则是由 INCREMENT BY(递增的或递减的)定义的。可以缓存这些值或按请求次序来生成。
下面这个例子展示了一个 Sequence 对象的创建及其简单用法。
CREATE SEQUENCE ACCOUNT_SEQ
AS INTEGER
START WITH 1
INCREMENT BY 10
CYCLE
CACHE 20
正如您所看到的,Sequence 对象的使用方法与许多人对于 Identity 列的使用比较相似。但是这更为有效,而且 Sequence 对象有一些极佳的使用优点。例如可以使用 NEXT VALUE FOR 和 PREVIOUS VALUE FOR。NEXTVALUE FOR 将为 Sequence 对象生成并返回下一值。而 PREVIOUS VALUE FOR 将为 Sequence 对象生成并返回前一值。这些语句可用于下列地方:
- SELECT 和 SELECT INTO 语句;
- INSERT 语句里面的 fullselect 的 SELECT 从句;
- UPDATE 语句里面的 SET 从句(搜索或定位);
- SET 主变量;
- VALUES 或 VALUES INTO;
- CREATE PROCEDURE、FUNCTION、TRIGGER。
下面的例子(右边的表 2)展示了这些语句的用法:
假定 ACCT_SEQ 为 START WITH 10 INCREMENT BY 10
正如您所看到的,使用 Sequence 对象代替 Identity 列有许多好处。下面是两者的一个简单比较。
Sequence 对象与 Identity 列 | |
Sequence 对象 | Identity 列(带有 V8 功能) |
单独的 Sequence 对象是在用户请求时创建的 | 由 DB2 生成/维护和填充的内部 Sequence 对象 |
可用于它们所选择的任何目的,并且存在有多个 | 与特定的表相关联,并且只能有一个 |
循环(CYCLE)将回绕和重复,并且无需进行惟一性考虑 | 如果惟一索引在 Identity 列上并且创建了复制,那么循环(CYCLE)可能会产生问题 |
当用于填充表时,后来可被更新 | 如果是 GENERATED ALWAYS,就无法被更新 |
可以更改(ALTER)Sequence 对象的属性。 还可以进行注释(COMMENT)以及授予/撤销(GRANT/REVOKE)权限 |
只能更改表(ALTER TABLE)(如果向已填充的表添加 Identity 列,将被置于 REORG 暂挂状态) |
可被删除 | 不能从表中删除* |
支持 NEXT VALUE FOR EXPRESSION 和 PREVIOUS VALUE FOR EXPRESSION | 必须使用 ID_VAL_LOCAL 并且只返回用户提交(commit)范围内的最后值 |
* 如果今后设计中使用 Sequence 对象比使用 Identity 列更好,那么在选择 Identity 列时就要考虑仔细。如果它们是在已填充的表上定义的并且需要被删除,那么必须删除表然后重新创建。这对于高效环境中的大型表可能是一个大问题。 |
Identity 列和 Sequence 对象在我们的设计中都占有一席之地。鉴于它们都可以达到相同的目的 —— 生成序号,所以应该由您来选择哪一个更适合您。这将取决于您对生成的数字所需的灵活性,以及应用程序将如何使用这些数字。
相关推荐
### DB2数据库对象基础知识 #### 一、数据库对象概述 在DB2中,数据库对象是构建数据库的基础单元,它们能够帮助我们有效地组织、管理和访问数据。通过数据定义语言(DDL)可以实现对这些对象的创建、修改和删除...
Sequence是独立于表的数据库对象,可以在多个表中重用,而Identity是表的一个属性,仅限于指定的表。Identity列通常与表的特定列关联,自动为新插入的行生成唯一值。 在Oracle中,Identity功能相对较新,与Sequence...
DB2中支持自动生成ID列的功能,即序列号(SEQUENCE),而在GreenPlum/PostgreSQL中,可以通过序列(SEQUENCE)或IDENTITY属性来实现类似功能。在转换时,需要确保自增ID列的定义正确无误。 ###### 2.2.5 特殊对象 -...
至于DB2自动生成流水号,可以利用`IDENTITY`属性或者`SEQUENCE`对象。`IDENTITY`常用于单表主键自增,如: ```sql CREATE TABLE YourTable ( Id INT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, ... ); ``` `...
- **标识列(Identity Columns)**和**序列对象(Sequence Objects)**:用于生成唯一值,保证数据的唯一性和完整性。 通过上述知识点,我们可以看出DB2 Express-C快速入门书籍为初学者提供了一个全面的入门指南。...
在 DB2 中没有对应的数据库对象,只能通过在某一列上实现 Oracle 中相应的 Sequence 功能。 八、SQL 语句 在 Oracle 中,左联接是通过在等号左边用“(+)”符号来实现,而在 DB2 中左联接是通过“LEFT OUTER JOIN”...
### DB2 数据库对象与编程方法详解 #### 一、DB2 数据库对象概述 DB2 是 IBM 开发的一款高性能关系型数据库管理系统(RDBMS),广泛应用于企业和组织的数据管理领域。掌握 DB2 的核心概念和技术对于成为一名优秀的 ...
1. 首先,导入必要的依赖,如Hibernate的核心库、DB2的JDBC驱动、JUnit库等。 2. 在测试类上使用`@RunWith(SpringRunner.class)`注解,以启用Spring Boot的测试支持。 3. 使用`@DataJpaTest`或`@SpringBootTest`注解...
为满足题目要求,需要使用 DB2 中的 SEQUENCE 对象。SEQUENCE 是一种自动递增或递减的数据库对象,通常用于为主键或其他唯一标识符提供连续的值。在这种情况下,程序员可以通过创建一个 SEQUENCE 对象,并设置起始值...
序列对象(Sequence Object)用于生成序列号,与提高查询性能不直接相关。 序列的使用时机: 序列(Sequence)在DB2中用于生成数值,这些数值不是关联到任何特定的列或表。序列特别适合在需要自动增加序号的场景中...
通过此认证可以证明持证人具备管理 DB2 数据库的能力,包括但不限于查询优化、数据库对象管理、安全性配置等方面的专业技能。 #### 二、知识点详细解析 ##### 1. 查询优化中的 Materialized Query Table (MQT) **...
- **Database path:** 数据库存储路径(/db2data/aaicdb/db2inst1/NODE0000/SQL00) - **Input database alias:** 数据库别名(AAICDB) - **Locks held:** 当前持有的锁总数(32个) - **Applications ...
7. **创建序列**:序列是自增的数字序列,创建序列的语法是`CREATESEQUENCE SEQUENCE_NAME STARTWITH START_NUMBER INCREMENTBY VALUE1 NOMAXVALUE NOCYCLE CACHE MAXIMUMNUMBEROFSEQUENCEVALUES`,可以设置起始值、...
- **序列**:用于生成唯一标识符,例如 `CREATE SEQUENCE seq_sno START WITH 1 INCREMENT BY 1` **八、存储过程及触发器** - **存储过程**:一组预编译的 SQL 语句,可封装为一个可重复使用的单元。创建存储过程...
DB2通过`VALUES NEXT VALUE FOR sequence_name`获取下一个序列值,而在Oracle中,我们需要使用`SELECT sequence_name.NEXTVAL FROM DUAL`。这种差异可能导致在迁移过程中需要修改应用代码来适应Oracle的语法。 2. ...
CREATE SEQUENCE myseq START WITH 1 INCREMENT BY 1 NO CYCLES; ``` 序列值的获取和使用可以通过`NEXTVAL`和`PREVVAL`函数: ```sql INSERT INTO t1 VALUES (nextval for myseq, ...); SELECT prevval for myseq ...
- **Increment**:依赖数据库的自动增长功能,如Oracle和DB2的Sequence,适合单一数据库环境。 **缓存管理** - **一级缓存**:Session内部的缓存,自动管理,每次操作对象都会放入一级缓存。更新或删除对象后,...