事先申明下,我的DB环境是Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - 64bit Production,不保证在其它版本下也是同样的结果。
正文:
为了验证dbms_random.value是否包括边界值,我特意给下表填充了随机值,表结构是这样的:
CREATE TABLE tb_score ( id NUMBER not null primary key, studentid int not null, courseid int not null, score int not null )
大家只要关注courseid字段就好,其它与本次验证无关。
为了给此表充值(也就是装填数据,充值这个词用在这真是太好了),我使用了以下sql:
Insert into tb_score select rownum,dbms_random.value(0,100000),dbms_random.value(1,5),dbms_random.value(0,150) from dual connect by level<=10000 order by dbms_random.random
执行完别忘了commit一下。
用以上语句,我给tb_score表的courseid字段填充了1~5的随机值,那么填完的一万条数据里,courseid字段里会是1~4,还是1~5,还是其它情况呢?
我用下面sql语句查了查:
SQL> select count(*) from tb_score where courseid=1; COUNT(*) ---------- 1258 SQL> select count(*) from tb_score where courseid=2; COUNT(*) ---------- 2498 SQL> select count(*) from tb_score where courseid=3; COUNT(*) ---------- 2492 SQL> select count(*) from tb_score where courseid=4; COUNT(*) ---------- 2499 SQL> select count(*) from tb_score where courseid=5; COUNT(*) ---------- 1253
另外还用下面SQL看看有无例外情况:
SQL> select count(*) from tb_score where courseid>5 or courseid<1; COUNT(*) ---------- 0
现在可以得出结论了,Oracle的dbms_random.value(min,max)函数是完全包括上下限,也就是边界值。如模拟学生考分的随机数,就可以用dbms_random.value(0,100)来做,只要数据量够大,0和100的边界值是都会出现的。
同时我们也发现了,dbms_random.value(1,5)的数据分布并不均匀,其中边界值1和5的加起来才达到2,3,4相同的级别,也就是说oracle把随机数据分成了四份,处于中间的2,3,4各享一份,剩下一份由1,5均分!
不知道oracle内部为什么要这么做,产生这样不均匀的数据分布是会给使用者带来一些困扰的,对此不可不知。
2020年1月23日