设为首页 收藏本站
查看: 1089|回复: 0

[经验分享] DB2 函数快速构造测试数据

[复制链接]

尚未签到

发表于 2016-11-18 08:57:28 | 显示全部楼层 |阅读模式
  函数快速构造测试数据

【案例】使用DB2内置函数快速构造测试数据
无论您是在用原型证明某一概念,还是开发一个全新的应用程序,或者只是学习 SQL,您都需要在您的应用程序上运行测试数据。为了有效地测试应用程序的性能,您必须拥有足够的测试数据,以便暴露潜在的性能问题。只要可以得到,用实际数据来进行测试总是更可取一些。如果没有可用的实际数据,那么在许多情况下,也可以生成足够的假想数据。一般来说,从头开始构造大量数据是件很容易的工作,可以使用db2的SQL语句就可以完成。
【案例类别】测试数据、构造数据
【关键字】date create generate insert select
【问题现象】
无论您是在用原型证明某一概念,还是开发一个全新的应用程序,或者只是学习 SQL,都需要在应用程序上运行测试数据。为了有效地测试应用程序的性能,必须拥有足够的测试数据,以便暴露潜在的性能问题。只要可以得到,用实 际数据来进行测试总是更可取一些。如果没有可用的实际数据,那么在许多情况下,也可以生成足够的假想数据。一般来说,从头开始构造大量数据是件很容易的工 作,可以使用db2的SQL语句就可以完成
【问题分析】
Db2 OLAP(分析函数简介)
生成大量测试数据需要用到DB2的分析函数来进行有规则的构造数据。
RAND():rand函数用来生成一组随机数,介于0-1之间的的随即小数,例如:
Select rand() as NUM from syscat.tablespaces,输出如下:
NUM        
-----------
+1.53311722517624E-001
          +5.54695940834794E-001
          +1.42065802655213E-001
          +7.82508742428622E-001
  4 record(s) selected.
  RAND()函数应用:
使用RAND()生成随即数,例如”SELECT INT(RAND() * 50 + 1) AS NUM FROM SYSCAT.TABLESPACES”,生成50以内的随即数。结果如下:
  NUM        
-----------
         16
         19
         10
          8
  4 record(s) selected.
  ROW_NUMBER():Row_Number函数用于生成整数序列很方便。
ROW_NUMBER()函数应用:
使用ROW_NUMBER()函数生成递增序列,”SELECT ROW_NUMBER() OVER() AS SEQ FROM SYSBAT.TABLESPACES”,结果如下:
SEQ                 
--------------------
                   1
                   2
                   3
                   4
  4 record(s) selected.
  利用DB2内置函数生成辅助表:
为什么要生成辅助表呢?再构造负责的数据,或者是满足某种分布状态的数据,我们的构造语句会非常复杂,如果不使用辅助表(也就是临时表),下面我们看看我们需要那些辅助表:生成一个自增加序列表,如果想要使用子增加序列或者是生成主键就需要用到该辅助表,生成一个字母和数据映射的ASCII骂表,因为再处理字符串时,需要用数字来模拟生成字符串的序列,然后再通过db2的内置函数ASCII来转化为db2的字符串序列。构造生成一个与时间映射的辅助表。
  自增长序列表:
“CREATE TABLE SEQ_DATE (NUM INT NOT NULL,PRIMARY KEY (NUM))”
  “INSERT INTO SEQ_DATE SELECT ROW_NUMBER() OVER() FROM SYSCAT.COLUMNS T1 JOIN SYSCAT.COLUMNS T2 ON T1 != T2 FETCH FIRST N ROWS ONLY”
第一句为构建辅助表SQL,第二句为将数据插入到临时表中,其中N修改为自己想要插入的记录条数。
  ASCII码表:
“CREATE TABLE ASCII_DATE (ASCII CHAR(1) NOT NULL, NUM INT NOT NULL)”
“INSERT INTO ASCII_DATE SELECT CHR(NUM) AS ASCII, NUM FROM SEQ_DATE WHERE NUM>=48 AND NUM <=122”,其中CHR函数表示将数据转化为ASCII码,而WHERE条件是指,指转换可视的ASCII码,这里可以根据需要将自己需要的ASCII添加的WHERE条件中,如下表中不包含回车和换行,如果想构造特殊的字符串(包含换行或者回车),可以将WHERE条件更改为WHERE NUM>=48 AND NUM <=122 OR NUM=10 OR NUM=13
使用SELECT * FROM ASCII_DATE查询表中数据,结果如下:
ASCII 十进制 ASCII 十进制 ASCII 十进制
0 48 D 68 ] 93
1 49 E 69 ^ 94
2 50 F 70 _ 95
3 51 G 71 ` 96
4 52 H 72 a 97
5 53 I 73 b 98
6 54 J 74 c 99
7 55 K 75 d 100
8 56 L 76 e 101
9 57 M 77 f 102
: 58 N 78 g 103
; 59 O 79 h 104
< 60 P 80 i 105
= 61 Q 81 j 106
> 62 R 82 k 107
? 63 S 83 l 108
@ 64 T 84 m 109
A 65 U 85 n 110
B 66 V 86 o 111
C 67 W 87 p 112
w 119 X 88 q 113
x 120 Y 89 r 114
y 121 Z 90 s 115
z 122 [ 91 t 116
v 118 \ 92 u 117
  这样在构造特定字符序列的时候就可以使用先生成数据,然后转换为ASCII,这样构造特定字符序列的问题就转化为了生成特定的数据的问题了。
  日期辅助表:

由于日期辅助表比较灵活,需要根据具体的应用场景来生成具体的辅助表,所以这里就举例说明,下面不再累述。
场景1:需要生成2010年3月份的某一天。
“CREATE TABLE TIME_SEQ (DATE_ CHAR(8) NOT NULL, NUM INT NOT NULL)”
“INSERT INTO TIME_SEQ SELECT DATE('03/01/2010') + (NUM - 1) DAYS AS DATE_1, NUM  FROM SEQ_DATE WHERE NUM>=1 AND NUM <=30”
生成的数据如下:
  DATE_1 NUM DATE_1 NUM
03/01/2010 1 03/16/2010 16
03/02/2010 2 03/17/2010 17
03/03/2010 3 03/18/2010 18
03/04/2010 4 03/19/2010 19
03/05/2010 5 03/20/2010 20
03/06/2010 6 03/21/2010 21
03/07/2010 7 03/22/2010 22
03/08/2010 8 03/23/2010 23
03/09/2010 9 03/24/2010 24
03/10/2010 10 03/25/2010 25
03/11/2010 11 03/26/2010 26
03/12/2010 12 03/27/2010 27
03/13/2010 13 03/28/2010 28
03/14/2010 14 03/29/2010 29
03/15/2010 15 03/30/2010 30
  同样生成日期的问题转换为了生成数据序列,数据序列是我们很好生成的。
  使用如下语句生成10000条3月份随即某一天的记录:
“SELECT DATE FROM TIME_SEQ AS S1, (SELECT INT(RAND() * 30 + 1) AS NUM FROM SYSCAT.COLUMNS T1 JOIN SYSCAT.COLUMNS T2 ON T1.COLNAME != T2.COLNAME FETCH FIRST 10000 ROWS ONLY) AS S2 WHERE S1.NUM=S2.NUM”
  构造辅助表是我们构造负责数据的基础,通过辅助表可以将复杂的数据生成规则转换成为生成简单的数据序列。掌握好这样原则,构造灵活好用的辅助表可以使你的数据分布达到你的要求。
  常用生成规则实例:
唯一主键:
唯一主键一般有俩中,一种是固定长度的随即数据序列,一种是变长的递增数字序列。
固定长度的数据序列(长度为5位的唯一序列):

“CREATE TABLE SIMAPLE_TABLE (KEY VARCHAR(5) NOT NULL, PRIMARY KEY (KEY))”
  “INSERT INTO SIMAPLE_TABLE SELECT
    RTRIM(CHAR(INT(RAND() * 10)))
||RTRIM(CHAR(INT(RAND() * 10)))
||RTRIM(CHAR(INT(RAND() * 10)))
||RTRIM(CHAR(INT(RAND() * 10)))
||RTRIM(CHAR(INT(RAND() * 10))) AS KEY FROM SYSCAT.COLUMNS T1 JOIN SYSCAT.COLUMNS T2 ON T1.COLNAME != T2.COLNAME FETCH FIRST 10000 ROWS ONLY”

其中用到的DB2的内置函数有RTRIM、CHAR、INT、RAND,RTRIM,RAND() * 10是产生一个0-10的随即浮点数,INT将浮点数转化为INT类型,将INT转化为字符串类型,将字符串使用RTRIM将右边的空格去掉。
  变长的递增数字序列:
  “CREATE TABLE UNIQUE_SEQ (KEY VARCHAR(30) NOT NULL, PRIMARY KEY (KEY))”
  “INSERT INTO UNIQUE_SEQ SELECT CHAR(ROW_NUMBER() OVER()) AS KEY FROM SYSCAT.COLUMNS T1 JOIN SYSCAT.COLUMNS T2 ON T1.COLNAME != T2.COLNAME FETCH FIRST 10000 ROWS ONLY”
  其中用到的db2内置函数有ROW_NUMBER() 、OVER(),ROW_NUMBER()函数是对结果集行数的统计函数,而OVER()是配合ROW_NUMBER()函数,以使ROW_NUMBER()能够按照某种分布或是排序来统计。
  随即字符串:

“CREATE TABLE STRING_DATE(STRING VARCHAR(5) NOT NULL)”
  “INSERT INTO STRING_DATE
SELECT CHR(INT(RAND() * 75 + 48))
||CHR(INT(RAND() * 75 + 48))
||CHR(INT(RAND() * 75 + 48))
||CHR(INT(RAND() * 75 + 48))
||CHR(INT(RAND() * 75 + 48)) AS STRING
FROM SYSCAT.COLUMNS T1 JOIN SYSCAT.COLUMNS T2 ON T1.COLNAME != T2.COLNAME”
  其中用的DB2内置函数有CHR、||,CHR函数是将INT转换为ASCII,而表达式INT(RAND() * 75 + 48)是生成48~122的INT整数,ASCII可视部分都在这个范围之内。||是DB2中的字符串连接。
  【问题解决】
可见使用DB2内置函数来生成测试数据是很轻松的,效率高,而且学习成本比较低,对于构造简单数据规则的数据比较有效。

项目具体实例:
构造USER表的数据:
  数据规则:userid从1递增,手机号码从13900000001递增。
  数据数量:10000条
  用时:在毫秒级别内
  “INSERT INTO USER (USERID, PASSWD, CREATETIME, REGISTERTYPE, USERSTATE, MOBILE, USERSIGN) SELECT CHAR(ROW_NUMBER() OVER()) AS USERID, 'QTkU2ow3COlC9WDFf7J1JQ==' AS PASSWD, '20100327012752' AS CREATETIME, 3 AS REGISTERTYPE, 0 AS USERSTATE, '+86'||CHAR(13900000000 + ROW_NUMBER() OVER()) AS MOBILE, '1' AS USERSIGN FROM SYSCAT.COLUMNS T1 JOIN SYSCAT.COLUMNS T2 ON T1.COLNAME != T2.COLNAME FETCH FIRST 10000 ROWS ONLY”

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-301920-1-1.html 上篇帖子: DB2数据源在Spring环境中的配置 下篇帖子: DB2导出表结构语句
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表