关于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 个值,我认为这不是主要问题。