百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 编程网 > 正文

Oracle序列Sequence的基本使用 oracle中的序列是什么

yuyutoo 2024-10-22 18:41 3 浏览 0 评论

1. Sequence 定义

在Oracle中可以用SEQUENCE生成自增字段。Sequence序列是Oracle中用于生成数字序列的对象,可以创建一个唯一的数字作为主键。

2. 为什么要用 Sequence

你可能有疑问为什么要使用序列?

不能使用一个存储主键的表并每次递增吗?或者将列设置为AUTO INCREMENT?

如果使用一个表来储存主键值的话,也许需要这样做:

  1. 创建一个新表来储存单一值。
  2. 每次插入新值到你想要插入的表时,在新表中使用该值。
  3. 然后更新新表(将其加1)。
  4. 这些逻辑都可以加入进存储过程。

然而这种方法存在以下几个问题:

  1. 如果你的事务中途失败,可能会得到重复的数据(插入的数据有一个ID,但新表没有增加)。这可以通过先递增然后插入来部分避免,但它仍然有中途失败的风险。
  2. 更新表将对其进行锁定,这可能会导致多个事务或用户出现问题。如果有一个用户,这可能是可以的,但如果程序有两个或多个用户,那么这可能会导致问题。
  3. 创建和维护一个表以及执行此操作的代码是繁重的工作。

Sequence是一个更好的方法,原因如下:

  1. 创建更简单。
  2. 使用起来更简单。
  3. 没有死锁以及导致其他事务出现问题的风险。

3. 创建(CREATE)Sequence

CREATE SEQUENCE [schema_name.]{sequence_name}    -- schema_name为将存储序列的模式名,sequence_name 为自定义名称;
	START WITH      n    -- n 为序列的初始值,默认为1;
	INCREMENT BY    n    -- n 为序列步长(序列增加的幅度),默认为1,如果是负则按此步长递减;
	[MINVALUE n | NOMINVALUE ]    -- 如果序列递减,定义序列生成器能产生的最小值,默认为1
	[MAXVALUE n | NOMAXVALUE ]    -- 定义序列生成器能产生的最大值,默认无限制(1e28 - 1)
	[CACHE n | NOCACHE]    -- value 是存放序列的内存块大小,默认20。对序列进行内存缓存可以改善序列性能。
	[ORDER | NOORDER]    -- 表示序列号是按照请求的顺序生成的。如果使用时间戳的序列号会有用。
	[CYCLE | NOCYCLE]    -- 值达到限制值后是否循环,如果不循环,达到限制值后,继续产生新值会发生错误 ;

使用缓存创建序列的缺点是,如果发生系统故障,所有未使用的缓存序列值都将“丢失”。这会在指定的序列值中产生“间隙”。当系统恢复时,Oracle将从序列中停止的位置缓存新数字,忽略所谓的“丢失”序列值。要恢复丢失的序列值,您可以始终执行ALTER sequence命令,将计数器重置为正确的值。

4. 使用 Sequence

CURRVAL和NEXTVAL可以在以下几个地方使用:

  • INSERT语句的VALUES子句。
  • SELECT语句的SELECT列表
  • UPDATE语句的UPDATE子句

它们不能在以下地方使用:

  • CHECK约束的条件
  • 视图查询
  • 实体化视图查询
  • 子查询
  • 带有DISTINCT关键字、GROUP BY子句或ORDER BY子句的SELECT语句
  • 使用UNION、INTERSECT或MINUS运算符与另一个SELECT语句组合的SELECT语句
  • SELECT语句的WHERE子句
  • CREATE TABLE或ALTER TABLE语句中列的DEFAULT值

最后一点意味着您不能使用DEFAULT关键字的序列将列设置为自动递增。有一种方法可以创建自动递增列,那就是使用触发器和序列。

1)基本Oracle序列示例

以下语句创建一个名为id_seq的升序Sequence,从10开始,递增10,最小值为10,最大值为100。由于CYCLE选项,序列一旦达到100就返回10。

CREATE SEQUENCE id_seq
    INCREMENT BY 10
    START WITH 10
    MINVALUE 10
    MAXVALUE 100
    CYCLE
    CACHE 2;

使用NEXTVAL伪列获取序列的下一个值:

SELECT 
    id_seq.NEXTVAL 
FROM 
    dual;
以下是输出:
    NEXTVAL
----------
        10        

一旦通过NEXTVAL伪列获取序列号,就可以使用CURRVAL伪列重复访问它:

SELECT 
    id_seq.CURRVAL 
FROM 
    dual;
以下是输出:
    CURRVAL
----------
        10

注意!当调用NEXTVAL伪列时,它会为正在选择或插入的每一行数据返回一个新值。:

SELECT 
    id_seq.NEXTVAL 
FROM 
    dual;
以下是输出:
    NEXTVAL
----------
        20

但如果我使用几个NEXTVAL命令运行此查询的话:

SELECT id_seq.NEXTVAL AS nv1,
id_seq.NEXTVAL AS nv2,
id_seq.NEXTVAL AS nv3
FROM dual;
以下是输出:
       NV1         NV2         NV3
----------  ----------  ----------
        30          30          30

这表明NEXTVAL只为此记录调用过一次,并且每次的值都是相同的。

2) 在表列中使用 Sequence 的例子

在Oracle12c之前,只能在插入时将序列与表列间接关联。

首先,创建一个名为tasks的新表:

CREATE TABLE tasks(
    id NUMBER PRIMARY KEY,
    title VARCHAR2(255) NOT NULL
);

其次,为tasks表的id列创建一个序列:

CREATE SEQUENCE task_id_seq;

第三,在任务表中插入数据:

INSERT INTO tasks(id, title)
VALUES(task_id_seq.NEXTVAL, 'Create Sequence in Oracle');

INSERT INTO tasks(id, title)
VALUES(task_id_seq.NEXTVAL, 'Examine Sequence Values');

最后,从任务表中查询数据:

SELECT  
    id, title
FROM
    tasks;

添加图片注释,不超过 140 字(可选)

在本例中,tasks表与task_id_seq序列没有直接关联。

3)通过标识列使用序列的例子

在Oracle12c中,您可以通过标识列将序列与表列相关联。

首先,用id列的identity列创建tasks表。

CREATE TABLE tasks(
    id NUMBER GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
    title VARCHAR2(255) NOT NULL
);

Oracle创建了一个与 tasks表 的 id列 关联的序列。

由于Oracle自动为 id列 生成序列,因此在您的Oracle实例中,序列的名称可能不同。

Oracle创建序列-标识列

添加图片注释,不超过 140 字(可选)

Oracle使用 sys.idnseq$ 来存储表和序列之间的链接。

此查询返回任务表和 ISEQ$_74366序列 的关联:

SELECT 
    a.name AS table_name,
    b.name AS sequence_name
FROM   
    sys.idnseq$ c
    JOIN obj$ a ON c.obj# = a.obj#
    JOIN obj$ b ON c.seqobj# = b.obj#
WHERE 
    a.name = 'TASKS';  

第二,在任务表中插入一些行:

INSERT INTO tasks(title)
VALUES('Learn Oracle identity column in 12c');

INSERT INTO tasks(title)
VALUES('Verify contents of the tasks table');

最后,从任务表中查询数据:

SELECT
    id, title
FROM
    tasks;

添加图片注释,不超过 140 字(可选)

5. 删除(DROP)Sequence

要删除序列,它必须在您的模式中,或者您必须具有drop ANY sequence权限才能删除其他模式中的序列。

DROP SEQUENCE seq_name;

6. 更改(Alter)Sequence

创建序列后,可以更改序列的大多数特性。唯一不能更改的是序列的起始编号和序列的当前值。要更改的话需要删除并重新创建序列。

ALTER SEQUENCE seq02
INCREMENT BY 20
MAXVALUE 100000
CYCLE;

7. Sequence 原理

Oracle用Sequence来按需提供(几乎)无限的数字序列,这些序列保证是唯一的。最简单的方法就是保持一个全局可见的计数器,并在每次查询sequence_name.nextval的值时递增。

但Oracle必须跟踪提供的最后一个数字,以避免两次提供相同数字的风险——这对数据库系统来说很容易:只需将最新的数字保存在表中即可。然而,如果每次有人需要下一个号码时都必须更新一个表格,这流程会非常缓慢。这时应该使用一个自主事务,这样就不需要等待第一个会话提交其当前事务,然后才能生成下一个数字。因此,Oracle使用递归的、自主的事务来处理表更新,并且它通过在内存中计数并记住下一次需要更新表的时机来避免每次调用nextval都更新表。

自制”序列的一种常见策略是,在一个表中包含(序列名,最近使用的序列号)的列,然后编写一个函数,从表中选择相关行进行更新,增加编号,更新表,并将编号提供给最终用户,这正是Oracle内在的机制。

您可以通过查询视图 user_sequences 来查看序列的数据库映像。假设我刚刚创建了一个名为s1的序列,图3.1是一个查询创建序列后立即给出的结果,和一次调用获取 s1.nextval 后得到的结果:

select
        min_value, max_value, 
        increment_by, cache_size, last_number, 
        cycle_flag, order_flag
from 
        user_sequences
where 
        sequence_name = 'S1'
/

图7.1

如果你有DBA权限,你可以进一步找到序列的 object_id,然后查询视图所基于的字典表(seq$)。以下运行了两次查询,一次在第一次调用 s1.nextval 之前,另一次是刚刚调用 s1 之后:

select 
        minvalue, maxvalue, increment$, cache, highwater, cycle#, order$ 
from 
        seq$ 
where
        obj# = 124874
;

图7.2

如果你的账户已被授权,可以通过动态性能视图 v$_sequences 查看内存中的信息:

select
        min_value, max_value,
        increment_by, cache_size, highwater,
        cycle_flag, order_flag, nextvalue
from
        v$_sequences
where
        object# = 124874
/

第一次调用s1.nextval之后,我只查询了一次视图(在第一次调用nextval时,序列才会出现在视图中):

图7.3

动态性能视图的列 nextvalue 保存了下次用户调用 s1.nextval 时将提供的值。

三个视图中都有一个“highwater”值(在图7.1视图user_sequences中称为“last_number”)。当对s1.nextval 的调用返回 highwater 中显示的值(highwater和nextvalue相同)时,进行调用的会话将执行并提交递归事务,将增量值添加到当前 highwater 并更新 seq$ 表。

“缓存”不是传统意义上的缓存,它只是一对数字(无论您设置的序列缓存大小有多大):当前值和提升highwater 后的值。为序列设置大型缓存不会造成资源损失,所以在大多数情况下,您应该尽可能使用大的cache。

相关推荐

Mysql和Oracle实现序列自增(oracle创建序列的sql)

Mysql和Oracle实现序列自增/*ORACLE设置自增序列oracle本身不支持如mysql的AUTO_INCREMENT自增方式,我们可以用序列加触发器的形式实现,假如有一个表T_WORKM...

关于Oracle数据库12c 新特性总结(oracle数据库19c与12c)

概述今天主要简单介绍一下Oracle12c的一些新特性,仅供参考。参考:http://docs.oracle.com/database/121/NEWFT/chapter12102.htm#NEWFT...

MySQL CREATE TABLE 简单设计模板交流

推荐用MySQL8.0(2018/4/19发布,开发者说同比5.7快2倍)或同类型以上版本....

mysql学习9:创建数据库(mysql5.5创建数据库)

前言:我也是在学习过程中,不对的地方请谅解showdatabases;#查看数据库表createdatabasename...

MySQL面试题-CREATE TABLE AS 与CREATE TABLE LIKE的区别

执行"CREATETABLE新表ASSELECT*FROM原表;"后,新表与原表的字段一致,但主键、索引不会复制到新表,会把原表的表记录复制到新表。...

Nike Dunk High Volt 和 Bright Spruce 预计将于 12 月推出

在街上看到的PandaDunk的超载可能让一些球鞋迷们望而却步,但Dunk的浪潮仍然强劲,看不到尽头。我们看到的很多版本都是为女性和儿童制作的,这种新配色为后者引入了一种令人耳目一新的新选择,而...

美国多功能舰载雷达及美国海军舰载多功能雷达系统技术介绍

多功能雷达AN/SPY-1的特性和技术能力,该雷达已经在美国海军服役了30多年,其修改-AN/SPY-1A、AN/SPY-1B(V)、AN/SPY-1D、AN/SPY-1D(V),以及雷神...

汽车音响怎么玩,安装技术知识(汽车音响怎么玩,安装技术知识视频)

全面分析汽车音响使用或安装技术常识一:主机是大多数人最熟习的音响器材,有关主机的各种性能及规格,也是耳熟能详的事,以下是一些在使用或安装时,比较需要注意的事项:LOUDNESS:几年前的主机,此按...

【推荐】ProAc Response系列扬声器逐个看

有考牌(公认好声音)扬声器之称ProAcTablette小音箱,相信不少音响发烧友都曾经,或者现在依然持有,正当大家逐渐掌握Tablette的摆位设定与器材配搭之后,下一步就会考虑升级至表现更全...

#本站首晒# 漂洋过海来看你 — BLACK&DECKER 百得 BDH2000L无绳吸尘器 开箱

作者:初吻给了烟sco混迹张大妈时日不短了,手没少剁。家里有了汪星人,吸尘器使用频率相当高,偶尔零星打扫用卧式的实在麻烦(汪星人:你这分明是找借口,我掉毛是满屋子都有,铲屎君都是用卧式满屋子吸的,你...

专题|一个品牌一件产品(英国篇)之Quested(罗杰之声)

Quested(罗杰之声)代表产品:Q212FS品牌介绍Quested(罗杰之声)是录音监听领域的传奇品牌,由英国录音师RogerQuested于1985年创立。在成立Quested之前,Roger...

常用半导体中英对照表(建议收藏)(半导体英文术语)

作为一个源自国外的技术,半导体产业涉及许多英文术语。加之从业者很多都有海外经历或习惯于用英文表达相关技术和工艺节点,这就导致许多英文术语翻译成中文后,仍有不少人照应不上或不知如何翻译。为此,我们整理了...

Fyne Audio F502SP 2.5音路低音反射式落地音箱评测

FyneAudio的F500系列,有新成员了!不过,新成员不是新的款式,却是根据原有款式提出特别版。特别版产品在原有型号后标注了SP字样,意思是SpecialProduction。Fyne一共推出...

有哪些免费的内存数据库(In-Memory Database)

以下是一些常见的免费的内存数据库:1.Redis:Redis是一个开源的内存数据库,它支持多种数据结构,如字符串、哈希表、列表、集合和有序集合。Redis提供了快速的读写操作,并且支持持久化数据到磁...

RazorSQL Mac版(SQL数据库查询工具)

RazorSQLMac特别版是一款看似简单实则功能非常出色的SQL数据库查询、编辑、浏览和管理工具。RazorSQLformac特别版可以帮你管理多个数据库,支持主流的30多种数据库,包括Ca...

取消回复欢迎 发表评论: