方法一 字符串连接,缺点:量大了后性能直线下降
FUNCTION chinese_string(length IN NUMBER) RETURN VARCHAR2 is
random_string VARCHAR2 := '';
characters VARCHAR2(100) := '哈啊发多少啊阿埃挨哎唉哀皑癌蔼矮艾碍爱隘鞍氨安俺按暗岸胺案肮昂盎凹敖熬翱袄傲奥懊澳芭捌扒叭吧笆八疤巴拔跋靶把耙坝霸罢爸白柏百摆';
BEGIN
FOR i IN 1..length LOOP
random_string := random_string || SUBSTR(characters, value(1,58), 1);
END LOOP;
RETURN random_string;
end;
方法二 – 数组方式
create or replace type arrays is varray(6200) of varchar2(1);
create table table1 (
arr arrays
);
insert into table1 values(arrays('好','搭','啊', '阿', '埃', '挨', '哎', '唉', '哀', '皑', '癌', '蔼', '矮', '艾', '碍', '爱', '隘', '鞍', '氨', '安', '俺', '按', '暗', '岸', '胺', '案', '肮', '昂', '盎', '凹', '敖', '熬', '翱', '袄', '傲', '奥', '懊', '澳', '芭', '捌', '扒', '叭', '吧', '笆', '八', '疤', '巴', '拔', '跋', '靶', '把', '耙', '坝', '霸', '罢', '爸', '白', '柏', '百', '摆'))
FUNCTION chinese_string1(length IN NUMBER) RETURN VARCHAR2 is
ss varchar2 :='';
str varchar2 ;
begin
for i in 1..length loop
select arr(mod(rand(),6272)+1) into str from table1;
ss := ss|| str;
end loop;
return ss;
end
方法三 – 集合方式
FUNCTION chinese_string2(length IN NUMBER) RETURN VARCHAR2 is
TYPE t_varr IS VARRAY(58) OF VARCHAR2(1);
arr t_varr;
ss varchar2 :='';
v_chars VARCHAR2(58) := '啊阿埃挨哎唉哀皑癌蔼矮艾碍爱隘鞍氨安俺按暗岸胺案肮昂盎凹敖熬翱袄傲奥懊澳芭捌扒叭吧笆八疤巴拔跋靶把耙坝霸罢爸白柏百摆';
BEGIN
arr.EXTEND(58);
for i in 1..58 loop
arr(i):= substr(v_chars, i, 1);
end loop;
FOR i IN 1..length LOOP
ss := ss || arr(mod(rand(),57)+1);
END LOOP;
return ss;
END;
方法四 – 汉字表方式 ,缺点:所有汉字都是唯一,在随机中无法重复,且汉字量有限
CREATE TABLE chinese_characters_table (
chinese_char VARCHAR2(1)
);
declare
v_chars varchar2(58) := '啊阿埃挨哎唉哀皑癌蔼矮艾碍爱隘鞍氨安俺按暗岸胺案肮昂盎凹敖熬翱袄傲奥懊澳芭捌扒叭吧笆八疤巴拔跋靶把耙坝霸罢爸白柏百摆';
begin
-- 使用for循环逐个插入字符
for i in 1..length(v_chars) loop
insert into chinese_characters_table (chinese_char) values (substr(v_chars, i, 1));
end loop;
end;
FUNCTION chinese_string3(length IN NUMBER) RETURN VARCHAR2 is
declare ss varchar;
begin
-- select listagg(chinese_char ,'') within group( order by chinese_char) into ss from chinese_characters_table where rownum<=10 ORDER BY random.value(1,58);
select listagg(chinese_char ,'') within group( order by chinese_char) into ss FROM
(SELECT chinese_char FROM chinese_characters_table ORDER BY random.value(1,58))
WHERE ROWNUM <= length;
return ss;
end;
压力测试
// 单节点测试
SELECT chinese_string(600000) -- 1000: 76ms 6000: 455ms 100:8ms 原始 6w:5s 60w:120s
SELECT chinese_string1(600000) --1000: 18ms 6000: 110ms 100:2ms 数组 6w: 1.9s 60w:110s
SELECT chinese_string2(600000) --1000: 503ms 6000: 510ms 100:504ms 集合 6w :1.1s 60w: 73s
SELECT chinese_string3(6000) -- 1000: 8ms 6000: 24ms 100:7ms 汉字码表
-- 单次压力测试
begin
for i in 1..60000 loop
send_msg(chinese_string(mod(rand(),99)+1)); -- 原始方式
end loop;
end; -- 1000:3.7s 6000: 22s 6w:228s
begin
for i in 1..60000 loop
send_msg(chinese_string1(mod(rand(),99)+1)); -- 方案1 数组方式实现
end loop;
end;
/ -- 1000:1.4s 6000:5.5s 6w:54s
begin
for i in 1..60000 loop
send_msg(chinese_string2(mod(rand(),99)+1)); -- 方案2 集合方式实现
end loop;
end; -- 1000:502s
begin
for i in 1..6000 loop
send_msg(chinese_string3(mod(rand(),99)+1)); -- 方案3 汉字码表实现
end loop;
end; -- 1000:6.3s 6000: 38s
总结
数组在访问元素时,时间复杂度和空间复杂都是O(1),经过对比测试验证用数组造随机汉字就是最快的方式。