背景:
作为Oracle Database DBA,经常需要构造数量级百万、千万、甚至更多的数据来进行脚本性能测试。如何快速产生这些数据呢?我们可以用Shell、Perl、AWK等编程实现,目前经过本人测试发现:相同的实现算法采用AWK效率更高,Perl次之,Shell过慢。
采用AWK实现的随机函数(保存在random_function.awk文件中):
#
# 产生各类型数据随机函数
# chm, 461810517@qq.com
# 2011/09/21
#
# 产生随机整数, 其值大于等于min, 小于等于max
function random_int(min, max) {
return int( rand()*(max-min+1) ) + min
}
# 产生随机浮点数, 其整数部分位数最大为precision, 小数部分位数最大为scale
function random_float(precision, scale) {
scale = 10^scale;
return int( rand()*(10^precision) ) + int( rand()*scale )/scale
}
# 产生长度为len的随机字符串
# opt为"lower"时, 产生由小写字母构成的随机字符串; opt为"upper"时, 产生由大写字母构成的随机字符串; opt为其它时, 产生大小写字母构成的随机字符串
function random_string(opt, len) {
if (!is_define_T) {
is_define_T = 1;
T_LEN_LOWER = split("a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z", T_LOWER, ",");
T_LEN_UPPER = split("A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z", T_UPPER, ",");
T_LEN_DEFAULT = split("a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z", T_DEFAULT, ",");
}
if (opt == "lower") {
return _random_string(len, T_LOWER, T_LEN_LOWER);
} else if (opt == "upper") {
return _random_string(len, T_UPPER, T_LEN_UPPER);
} else {
return _random_string(len, T_DEFAULT, T_LEN_DEFAULT);
}
}
# 产生长度为len, 由字母表alphabet中的字母构成的随机字符串
function _random_string(len, alphabet, alphabet_len, _result, _i) {
for (_i=0; _i<len; _i++) {
_result = _result alphabet[ random_int(1, alphabet_len) ];
}
return _result;
}
# 产生格式为format的随机日期时间值
# begin_time, end_time格式: YYYY MM DD HH MM SS[ DST]
# format: 日期时间格式, 如"%Y-%m-%d %H:%M:%S"
function random_time(begin_time, end_time, format) {
begin_time = mktime(begin_time);
end_time = mktime(end_time);
return strftime(format, begin_time + random_int(1, end_time-begin_time+1));
}
调用random_function.awk文件中函数的测试脚本,取名random_test.awk:
BEGIN {
# 设置AWK程序输出时各列的分隔符
OFS = "|";
srand();
COUNT = 100000000;
for (i=1; i<COUNT; i++) {
print random_int(10, 100), random_float(3, 2), random_string("upper", 10), random_time("2009 06 01 12 30 30", "2011 07 15 23 59 59", "%Y-%m-%d %H:%M:%S");
}
}
命令方式运行random_test.awk:
awk -f random_function.awk -f random_test.awk
注:通过这个命令,将会产生4列数据,分别是整型、浮点数、字符串、日期时间。
作为Oracle Database DBA,经常需要构造数量级百万、千万、甚至更多的数据来进行脚本性能测试。如何快速产生这些数据呢?我们可以用Shell、Perl、AWK等编程实现,目前经过本人测试发现:相同的实现算法采用AWK效率更高,Perl次之,Shell过慢。
采用AWK实现的随机函数(保存在random_function.awk文件中):
#
# 产生各类型数据随机函数
# chm, 461810517@qq.com
# 2011/09/21
#
# 产生随机整数, 其值大于等于min, 小于等于max
function random_int(min, max) {
return int( rand()*(max-min+1) ) + min
}
# 产生随机浮点数, 其整数部分位数最大为precision, 小数部分位数最大为scale
function random_float(precision, scale) {
scale = 10^scale;
return int( rand()*(10^precision) ) + int( rand()*scale )/scale
}
# 产生长度为len的随机字符串
# opt为"lower"时, 产生由小写字母构成的随机字符串; opt为"upper"时, 产生由大写字母构成的随机字符串; opt为其它时, 产生大小写字母构成的随机字符串
function random_string(opt, len) {
if (!is_define_T) {
is_define_T = 1;
T_LEN_LOWER = split("a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z", T_LOWER, ",");
T_LEN_UPPER = split("A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z", T_UPPER, ",");
T_LEN_DEFAULT = split("a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z", T_DEFAULT, ",");
}
if (opt == "lower") {
return _random_string(len, T_LOWER, T_LEN_LOWER);
} else if (opt == "upper") {
return _random_string(len, T_UPPER, T_LEN_UPPER);
} else {
return _random_string(len, T_DEFAULT, T_LEN_DEFAULT);
}
}
# 产生长度为len, 由字母表alphabet中的字母构成的随机字符串
function _random_string(len, alphabet, alphabet_len, _result, _i) {
for (_i=0; _i<len; _i++) {
_result = _result alphabet[ random_int(1, alphabet_len) ];
}
return _result;
}
# 产生格式为format的随机日期时间值
# begin_time, end_time格式: YYYY MM DD HH MM SS[ DST]
# format: 日期时间格式, 如"%Y-%m-%d %H:%M:%S"
function random_time(begin_time, end_time, format) {
begin_time = mktime(begin_time);
end_time = mktime(end_time);
return strftime(format, begin_time + random_int(1, end_time-begin_time+1));
}
调用random_function.awk文件中函数的测试脚本,取名random_test.awk:
BEGIN {
# 设置AWK程序输出时各列的分隔符
OFS = "|";
srand();
COUNT = 100000000;
for (i=1; i<COUNT; i++) {
print random_int(10, 100), random_float(3, 2), random_string("upper", 10), random_time("2009 06 01 12 30 30", "2011 07 15 23 59 59", "%Y-%m-%d %H:%M:%S");
}
}
命令方式运行random_test.awk:
awk -f random_function.awk -f random_test.awk
注:通过这个命令,将会产生4列数据,分别是整型、浮点数、字符串、日期时间。