关于NOORDER
条款,the documentation says:
“指定NOORDER
如果你不想要保证序号是对的请求顺序产生。”
的关键词是保证 。 NOORDER
不承诺随机性,这意味着NEXTVAL
可能会乱序产生数字。这在RAC环境中主要关注,其中每个节点都有一个序列号缓存;在这些情况下NOORDER
意味着我们不能从给定值的序列推断NEXTVAL
请求的序列,即我们不能使用这些数字按创建顺序对记录进行排序。
根据您的要求。
您的要求是矛盾的。随机性意味着不可预测性。唯一性意味着可预测性。
你不能用一个序列实现这一点,但你可以建立你喜欢这个自己的事情:
create table pseudo_sequence (
used varchar2(1) default 'N' not null
, id number not null
, next_val number not null
, primary key (used, id)
)
organization index
/
注意索引表只有语法。下一个技巧是随机填充表格。
insert into pseudo_sequence (id, next_val)
with nbr as (
select level + 99999 as nx
from dual
connect by level <= 900000
order by dbms_random.value
)
select rownum, nx from nbr
/
我们需要ID列来保留整个表的NEXT_VAL的随机分布;如果没有它,索引会强制执行一个命令,并且我们希望避免每次执行查询时进行排序。
下一步,我们建立一个查询来获取从表中的下一个值,并将其标记为使用:
create or replace function random_nextval
return number
is
pragma autonomous_transaction;
cursor ps is
select next_val
from pseudo_sequence
where used = 'N'
and rownum = 1
for update of used skip locked;
return_value number;
begin
open ps;
fetch ps into return_value;
update pseudo_sequence
set used = 'Y'
where current of ps;
close ps;
commit;
return return_value;
end;
/
,这里是它如何工作的:
SQL> select random_nextval from dual
2 connect by level <= 5
3/
RANDOM_NEXTVAL
--------------
216000
625803
806843
997165
989896
SQL> select * from pseudo_sequence where used='Y'
2/
U ID NEXT_VAL
- ---------- ----------
Y 1 216000
Y 2 625803
Y 3 806843
Y 4 997165
Y 5 989896
SQL> select random_nextval from dual
2 connect by level <= 5
3/
RANDOM_NEXTVAL
--------------
346547
911900
392290
712611
760088
SQL>
当然,我们可以认为这不是随机的,因为通过查看底层表可以预测下一个值,但也许它足够满足您的需求。我不会对多用户环境中的可伸缩性做出任何承诺,但考虑到您的数字空间仅有900,000个值,我认为这不是一个主要问题。
来源
2017-04-07 07:41:35
APC
我忘了提及我已经删除部分增量1之间的序列。 – ankit
创建序列otp_seq minvalue 100000 maxvalue 999999 nocycle noorder 仍然结果是有序的。 – ankit
好吧,*序列*产生*顺序* vaues,*随机*函数产生*随机*值。但是一个随机数永远不能保证是唯一的。要么创建一个随机数,并在循环中检查它是否已被使用,或者创建包含数字的表并随机选择其中的一个,然后删除它(或将其标记为已使用)。 – dnoeth