OceanBase V4.2解析:如何用迭代器 Generator快速生成任意数据
前言
OceanBase 4.2 版本新增了迭代器 generator 函数。尽管这一功能在数据库领域中已属于通用能力,postgresql 也提供了类似的函数,然而,与MySQL和Oracle数据库在默认情况下是需要用户额外编写函数来实现的。OceanBase 4.2 的这一更新也是满足更多用户的需求。
迭代器具有自我多次运行的能力,通过generator函数,用户可以快速地生成任意所需数据。以下是关于generator函数在OceanBase中的具体应用案例。
随机0至99的字符
select floor((RAND())*100) from table(generator(10)) ;
随机生成10到19的随机
select floor((RAND()+1)*10) from table(generator(10)) ;
随机生成小数据点后2位,前面整数是0
SELECT ROUND(RAND(), 2) from table(generator(10)) ;
随机生成小数据点后4位,前面整数是2位
SELECT ROUND(RAND()*100, 4) from table(generator(10)) ;
生成1994年1月15日往前的日期时间,
随机增加数据
select date_add('1994-01-15' , interval floor((RAND()+1)*20) day ) from table(generator(10)) ;
生成1994年1月15日往前的随机日期时间,
递减数据1
select date_sub('1994-01-15' , interval floor((RAND())*10) day ) from table(generator(10)) ;
生成时间,1994年1月15做基准,随机按月递减
select date_sub('1994-01-15' , interval floor((RAND())*10) month ) from table(generator(10)) ;
生成时间,1994年1月15做基准,随机按年递减
select date_sub('1994-01-15' , interval floor((RAND())*10) year ) from table(generator(10)) ;
生成时间,1994年1月15做基准,随机按年、月、日 递减
select date_sub(date_sub(date_sub('1994-01-15' , interval floor((RAND())*10) year ),interval floor((RAND())*10) month),interval floor((RAND())*10) day) from table(generator(10)) ;
生成顺序序列
CREATE SEQUENCE seq1 START WITH 1 INCREMENT BY 1;
select seq1.nextval from table(generator(10)) ;
生成长度为100的随机字符串
select RANDSTR(100, RANDOM()) from table(generator(10)) ;
生成定算的随机 固定数组变量
假设列表选项有MAIL、TRUCK、AIR、FOB、REG AIR,只想生成数组变量这些相关的东西。
Postgresql很简单就可以做到,它具备变量数组的表达,例如(array['MAIL', 'TRUCK', 'RAIL', 'FOB', 'SHIP', 'REG AIR'])[列表]。
我找了OceanBase的官方相关文档,目前数组变量固定输出的函数,但是达到同样的目标可以用以下较灵活的方法制造数据
select
CASE
WHEN concat("test",floor((RAND())*6)) ='test0' THEN 'MAIL'
WHEN concat("test",floor((RAND())*6)) ='test1' THEN 'TRUCK'
WHEN concat("test",floor((RAND())*6)) ='test2' THEN 'AIR'
WHEN concat("test",floor((RAND())*6)) ='test3' THEN 'RAIL'
WHEN concat("test",floor((RAND())*6)) ='test4' THEN 'FOB'
WHEN concat("test",floor((RAND())*6)) ='test5' THEN 'SHIP'
WHEN concat("test",floor((RAND())*6)) ='test0' THEN 'MAIL'
WHEN concat("test",floor((RAND())*6)) ='test1' THEN 'TRUCK'
WHEN concat("test",floor((RAND())*6)) ='test2' THEN 'AIR'
WHEN concat("test",floor((RAND())*6)) ='test3' THEN 'RAIL'
WHEN concat("test",floor((RAND())*6)) ='test4' THEN 'FOB'
WHEN concat("test",floor((RAND())*6)) ='test5' THEN 'SHIP'
ELSE 'REG AIR'
END
from table(generator(10)) ;
案例tpc-h基准中的 lineitem表
insert /*+ ENABLE_PARALLEL_DML PARALLEL(4) */ into lineitem
select seq2.nextval,
floor((RAND()+1)*1000000),
floor((RAND()+1)*10000),
floor((RAND()+1)*100),
floor((RAND()+1)*10000),
floor((RAND()+1)*1000000),
floor((RAND()+1)*1000),
floor((RAND()+1)*1000),
'F',
'F',
date_add('1994-01-15' , interval floor((RAND()+1)*10) day ),
date_add('1994-09-25' , interval floor((RAND()+1)*7) day ),
date_add('1995-05-15' , interval floor((RAND()+1)*2) year ),
RANDSTR(20, RANDOM()),
CASE
WHEN concat("test",floor((RAND())*6)) ='test0' THEN 'MAIL'
WHEN concat("test",floor((RAND())*6)) ='test1' THEN 'TRUCK'
WHEN concat("test",floor((RAND())*6)) ='test2' THEN 'AIR'
WHEN concat("test",floor((RAND())*6)) ='test3' THEN 'RAIL'
WHEN concat("test",floor((RAND())*6)) ='test4' THEN 'FOB'
WHEN concat("test",floor((RAND())*6)) ='test5' THEN 'SHIP'
WHEN concat("test",floor((RAND())*6)) ='test0' THEN 'MAIL'
WHEN concat("test",floor((RAND())*6)) ='test1' THEN 'TRUCK'
WHEN concat("test",floor((RAND())*6)) ='test2' THEN 'AIR'
WHEN concat("test",floor((RAND())*6)) ='test3' THEN 'RAIL'
WHEN concat("test",floor((RAND())*6)) ='test4' THEN 'FOB'
WHEN concat("test",floor((RAND())*6)) ='test5' THEN 'SHIP'
ELSE 'REG AIR'
END as shipmode,
RANDSTR(25, RANDOM())
from table(generator(10)) ;