oracle sequence sequence

A sequence definition


Sequence (SEQUENCE) is a sequence number generator that can automatically generate sequence numbers for rows in a table, producing a set of equally spaced values ​​(type numbers). Does not take up disk space, takes up memory.

Its main purpose is to generate a table's primary key value, which can be referenced in an insert statement, as well as to check the current value through a query, or to advance a sequence to the next value.


2. The syntax of the sequence

Creating sequences requires the CREATE SEQUENCE system privilege. The syntax for creating a sequence is as follows:

  CREATE SEQUENCE sequence name

  [INCREMENT BY n]

  [START WITH n]

  [{MAXVALUE/ MINVALUE n| NOMAXVALUE}]

  [{CYCLE|NOCYCLE}]

  [{CACHE n| NOCACHE}];

    in:

1) INCREMENT BY is used to define the step size of the sequence. If omitted, the default value is 1. If a negative value appears, the value of the Oracle sequence is decremented according to this step size.

2) START WITH defines the initial value of the sequence (ie, the first value generated), which defaults to 1.

3) MAXVALUE defines the maximum value that the sequence generator can generate. The option NOMAXVALUE is the default option, which means that there is no maximum value defined. At this time, for the increasing Oracle sequence, the maximum value that the system can generate is 10 to the 27th power; for the decreasing sequence, the maximum value is -1.

4) MINVALUE defines the minimum value that the sequence generator can produce. The option NOMAXVALUE is the default option, which means that there is no minimum value defined. At this time, for the descending sequence, the minimum value that the system can generate is ~10 to the 26th power; for the increasing sequence, the minimum value is 1.

5) CYCLE and NOCYCLE indicate whether to cycle when the value of the sequence generator reaches the limit value. CYCLE stands for cycle and NOCYCLE stands for no cycle. If looping, when the increasing sequence reaches the maximum, loop to the minimum; for the decreasing sequence when the minimum is reached, loop to the maximum. If you don't loop, after reaching the limit value and continuing to generate new values, an error will occur.

6) CACHE (buffer) defines the size of the memory block to store the sequence, the default is 20. NOCACHE means no memory buffering of sequences. Memory buffering of sequences can improve sequence performance.

When a large number of statements are requested, when applying for a sequence, in order to avoid the performance bottleneck caused by the sequence being implemented at the application layer. The Oracle sequence allows the sequence to be generated in advance by cache x and stored in the memory first. When a large number of application sequence statements occur, the sequence can be obtained directly from the fastest running memory. However, the number of caches cannot be set too large, because when the database is restarted, the memory information will be cleared, and the sequence stored in the memory will be lost. When the database is restarted again, the sequence will be stored from the largest sequence number in the last memory + 1 into the cache x. This situation can also cause sequence numbers to be discontinuous when the database is shut down.

7) NEXTVAL returns the next valid value in the sequence, which can be referenced by any user.

8) The current value of the sequence is stored in CURRVAL, NEXTVAL should be specified before CURRVAL, and both should be valid at the same time.

Three: Examples

create:  

Create Sequence Test_Sequence

        Increment by 1     ---步长

        Start with 1 --- start value

        Nomaxvalue --- default

        Nocycle --- No cycle

delete:

drop sequence Test_Sequence

Use sequence:

t1_seq.nextval

create table t1(id number,qq number,ww number);

insert into t1 values(t1_seq.nextval,1,1);

query all sequences

USER_SEQUENCES

USER_OBJECTS

Four: Discussion on the principle, advantages and disadvantages of using sequence as a primary key These days, my colleagues and I have been discussing the issue of primary key selection in table design. What are the advantages and disadvantages of using sequence as a primary key, especially in some transaction scenarios. How to use the created sequence value? In fact, what I want to say is that it may be just a very simple concept, it may be deeply understood, and there is still a lot of unknown knowledge. Of course, there may be some pits that are easy to ignore but may be critical, and only know when you touch it. . . The following is a summary of the summary. If there are any omissions, please enlighten the heroes who pass by. 


 

1. First of all, seq.nextval mainly has the following two usage scenarios:
(1). If the sequence is only required for INSERT in a transaction, and the sequence is not required in other places, then only the INSERT ... VALUES (seq. nextval ...) statement can be used.
(2). If after INSERT a table in a transaction, the ID value of the primary key at the time of insertion is also required to be inserted into other tables as a foreign key, then it is necessary to use select seq.nextval from dual to obtain available in advance before INSERT the first table The ID is saved to a variable for later use.

2、其次可以简单说下调用序列的原理,只有理解了序列的原理,才能有助于我们知道如何正确使用序列。
使用序列时Oracle内部大体是按照如下步骤进行:
(1). 一个序列会被定义到Oracle内部的一张数据字典表(seq$)的一行。
(2). 第一次使用序列,序列的起始值会加上缓存大小,然后更新回行。
(3). Oracle内部会自动跟踪内存中的两个值,当前值和目标值。
(4). 每次有回话调用seq.nextval,Oracle会递增当前值,然后检查是否超过了目标值,再返回结果。
(5). 如果当前值和目标值相同,Oracle会更新数据字典表中的行,为目标值加上缓存大小,同时内存中产生了一个新的目标值。
例如create sequence seq cache 20;这样一序列。名称为seq的序列,缓存大小是20,默认初始值是1,步长默认是1。

当使用了一次seq.nextval后,可以看HIGHWATER字段值为21,即目标值1+缓存大小20=21。

当执行20次后,seq.nextval值变为21,此时HIGHWATER字段值是41,即目标值21+缓存大小20=41。

也就是每调用seq.nextval值20次,会更新一次seq$表,那么问题来了,如果cache值较小,且序列使用的频率较高,那么会对seq$表有频繁的更新操作,日志量会增加,尤其在RAC下,更新该行的时候,该数据块会在节点间不停的传送,就会产生可能的争用,这种问题会被放大。因此为了减少这种情况,我们可以将cache缓存值设置大一些,例如1000,减少对字典表的更新。
序列还有一个问题,就是cache缓存是实例级的,对于RAC,比如第一个节点使用序列时会分配1-20,第二个节点会被分配21-40,Oracle保证不会重复,但若节点crash了,比如节点1坏了,那么序列就会出现断号,节点1再次使用时,只会从41-60,由于我们用主键只为了标示唯一,不关心段号,也不关心产生的顺序,所以这些可以忽略。
 
:最近在讨论某系统和一个外系统做全局事务的事情,本想用这个主键作为两系统传输的一部分,用于控制全局事务,且用其作为判断交易先后顺序的依据,这是不太符合要求的,因为是RAC,序列是基于实例级cache,那么如果不能保证某一类型的交易总在一个节点上执行,那么不同次交易产生的主键序列值可能不是递增的,例如节点1处理一次交易,产生序列是1,节点2处理一次交易,产生序列是21,此时节点1再处理一次交易,产生序列是2;除非设置序列为order,但这样在RAC就有可能产生资源争用的问题,因为为了保证多节点间每次产生的序列值是递增的,每次产生就需要多节点间判断当前值后,才能知道下一个值是多少,而且会有额外的锁,保证同一时间只有一个节点在做这个操作,当然究竟是否会产生资源争用,还是要依据实际的业务并发量,或者压力测试才能证明,这里只是说可能会这样的问题,不是一定会,否则Oracle就不会有提供这种order的创建属性,凡事不绝对。

3、结合(1)的场景,
(1). 如果一个事务中只是INSERT时需要序列,其他地方不会需要这个序列,那么只需要在INSERT ... VALUES (seq.nextval ...)语句中使用即可。
> 这个场景下,如果序列cache设置为1000,调用100次nextval几乎没有影响。
(2). 如果一个事务中INSERT一张表后,还需要插入时的主键ID值,作为外键插入其他表,那么就需要在INSERT第一张表前使用select seq.nextval from dual提前获取可用的ID保存到一个变量中,为后面使用。
> 这个场景,就有些说的了。如果是同一事务中需要用到之前的序列值,那么就需要提前用select seq.nextval from dual保存到变量中,(当然,如果是用PLSQL语句,则可以不用提前保存变量这步,但咱们的应用中不适用,就不多说了)。



    




Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325723741&siteId=291194637