MySQL快速生成大量测试数据

155 篇文章 18 订阅

 1.建表

DROP TABLE IF EXISTS `sys_user`;
CREATE TABLE `sys_user` (
  `user_id` bigint(100) NOT NULL AUTO_INCREMENT,
  `username` varchar(100) DEFAULT NULL COMMENT '用户名',
  `password` varchar(100) DEFAULT NULL COMMENT '密码',
  `salt` varchar(100) DEFAULT NULL COMMENT '盐',
  `email` varchar(100) DEFAULT NULL COMMENT '邮箱',
  `mobile` varchar(100) DEFAULT NULL COMMENT '手机号',
  `status` varchar(100) DEFAULT NULL COMMENT '状态  0:禁用   1:正常',
  PRIMARY KEY (`user_id`)
) ENGINE=InnoDB AUTO_INCREMENT=112758 DEFAULT CHARSET=utf8 COMMENT='系统用户';
SET FOREIGN_KEY_CHECKS=1;

2.执行show variables like ‘log_bin_trust_function_creators’;设置为ON。开启状态。
set global log_bin_trust_function_creators=1;

在这里插入图片描述
3.创建函数

# 随机字符串
DELIMITER $$
CREATE FUNCTION random_string(n INT) RETURNS VARCHAR(255)
BEGIN
 DECLARE chars_str VARCHAR(100) DEFAULT 'abcdefghijklmnopqrstuvwxyzABCDEFJHIJKLMNOPQRSTUVWXYZ';
 DECLARE return_str VARCHAR(255) DEFAULT '';
 DECLARE i INT DEFAULT 0;
 WHILE i < n DO
 SET return_str =CONCAT(return_str,SUBSTRING(chars_str,FLOOR(1+RAND()*52),1));
 SET i = i + 1;
 END WHILE;
 RETURN return_str;
END $$

# 随机数字
DELIMITER $$
CREATE FUNCTION random_num( )
RETURNS INT(5)  
BEGIN   
 DECLARE i INT DEFAULT 0;  
 SET i = FLOOR(100+RAND()*10);  
RETURN i;  
 END $$

#执行存储过程,往sys_user表添加随机数据
DELIMITER $$
CREATE PROCEDURE insert_sys_user(IN START INT(10),IN max_num INT(10))  
BEGIN  
DECLARE i INT DEFAULT 0;   
 SET autocommit = 0;    
 REPEAT  
 SET i = i + 1;  
 INSERT INTO sys_user (user_id,username,password,salt,email,mobile,status) VALUES (START+i,random_string(10),random_string(6),random_string(10),random_string(20),random_string(16),random_string(12));  
 UNTIL i = max_num  
 END REPEAT;  
 COMMIT;  
 END $$
 

#执行存储过程,往sys_user表添加50万条数据
DELIMITER ;
CALL  insert_sys_user(100001,500000);

 删除:
使用DROP语句,语法如下:

 DROP {PROCEDURE | FUNCTION} [IF EXISTS] proc_name
 
DROP FUNCTION proc_countByName;
DROP FUNCTION IF EXISTS proc_countByName;

使用SHOW STATUS查看状态

SHOW STATUS查看存储过程和函数的状态,语法如下:

SHOW {PROCEDURE | FUNCTION} STATUS [LIKE 'parttern']

这个语句是MySQL的扩展,它返回子程序的特征,如数据库、名字、类型、创建者及创建和修改日期。如果没有指定样式,根据使用的语句,所有存储程序或存储函数的信息都被列出。PROCEDURE和FUNCTION分别表示查看存储过程和函数;LIKE语句表示匹配存储过程或函数名称。

示例:

SHOW PROCEDURE STATUS LIKE 'proc_%';
 

二、快速生成大量测试数据(100万、1000万、1亿)

这种做法生成的测试数据相对比较符合实际,注册时间和最后登录时间都既有一定的时间顺序,又有在时间区间内有随机生成,代码都有注释,这里就不多说了,代码如下:

    #建测试表
    drop table if exists t;
    CREATE TABLE t (
                    id int NOT NULL AUTO_INCREMENT PRIMARY KEY comment '自增主键',
                    dept tinyint not null comment '部门id',
                    age tinyint not null comment '年龄',
                    name varchar(30) comment '用户名称',
                    create_time datetime not null comment '注册时间',
                    last_login_time datetime comment '最后登录时间'
                   ) comment '测试表';
     
    #手工插入第一条测试数据,后面数据会根据这条数据作为基础生成
    insert into t values(1,1, 25, 'user_1', '2018-01-01 00:00:00', '2018-03-01 12:00:00');
    #初始化序列变量
    set @i=1;
     
     
    #==================此处拷贝反复执行,直接符合预想的数据量===================
    #执行20次即2的20次方=1048576 条记录
    #执行23次即2的23次方=8388608 条记录
    #执行24次即2的24次方=16777216 条记录
    #......
    insert into t(dept, age, name, create_time, last_login_time)
    select left(rand()*10,1) as dept,               #随机生成1~10的整数
           FLOOR(20+RAND() *(50 - 20 + 1)) as age,  #随机生成20~50的整数
            concat('user_',@i:=@i+1),               #按序列生成不同的name
            date_add(create_time,interval +@i*cast(rand()*100 as signed) SECOND), #生成有时间大顺序随机注册时间
            date_add(date_add(create_time,interval +@i*cast(rand()*100 as signed) SECOND), interval + cast(rand()*1000000 as signed) SECOND) #生成有时间大顺序的随机的最后登录时间
    from t;
    select count(1) from t;
    #==================此处结束反复执行=====================
     
     
    #创建索引(视情况执行)
    create index idx_dept on t(dept);
    create index idx_create_time on t(create_time);
    create index idx_last_login_time on t(last_login_time);

上面也可以改写成存储过程,但这也不是每天执行就懒得改了,就这样吧,怎么简单怎么做。
 

三、

 新建一个表格名为(dept)

CREATE TABLE dept( /*部门表*/
deptno MEDIUMINT   UNSIGNED  NOT NULL  DEFAULT 0,
dname VARCHAR(20)  NOT NULL  DEFAULT "",
loc VARCHAR(13) NOT NULL DEFAULT ""
) ;


在建一个表名为emp表

#创建表EMP雇员
CREATE TABLE emp
(empno  MEDIUMINT UNSIGNED  NOT NULL  DEFAULT 0, /*编号*/
ename VARCHAR(20) NOT NULL DEFAULT "", /*名字*/
job VARCHAR(9) NOT NULL DEFAULT "",/*工作*/
mgr MEDIUMINT UNSIGNED NOT NULL DEFAULT 0,/*上级编号*/
hiredate DATE NOT NULL,/*入职时间*/
sal DECIMAL(7,2)  NOT NULL,/*薪水*/
comm DECIMAL(7,2) NOT NULL,/*红利*/
deptno MEDIUMINT UNSIGNED NOT NULL DEFAULT 0 /*部门编号*/
) ;


在创建一个工资级别表salgrade

#工资级别表
CREATE TABLE salgrade
(
grade MEDIUMINT UNSIGNED NOT NULL DEFAULT 0,
losal DECIMAL(17,2)  NOT NULL,
hisal DECIMAL(17,2)  NOT NULL
);


然后像工资级别表插入数据

#测试数据
INSERT INTO salgrade VALUES (1,700,1200);
INSERT INTO salgrade VALUES (2,1201,1400);
INSERT INTO salgrade VALUES (3,1401,2000);
INSERT INTO salgrade VALUES (4,2001,3000);
INSERT INTO salgrade VALUES (5,3001,9999);


delimiter $$命令结束标志。
二.创建一个函数

#创建一个函数,名字 rand_string,可以随机返回我指定的个数字符串
create function rand_string(n INT)
returns varchar(255) #该函数会返回一个字符串
begin
#定义了一个变量 chars_str, 类型  varchar(100)
#默认给 chars_str 初始值   'abcdefghijklmnopqrstuvwxyzABCDEFJHIJKLMNOPQRSTUVWXYZ'
 declare chars_str varchar(100) default
   'abcdefghijklmnopqrstuvwxyzABCDEFJHIJKLMNOPQRSTUVWXYZ';
 declare return_str varchar(255) default '';
 declare i int default 0;
 while i < n
 do
    # concat 函数 : 连接函数mysql函数
   set return_str =concat(return_str,substring(chars_str,floor(1+rand()*52),1));
   set i = i + 1;
   end while;
  return return_str;
  end $$

//简单解释一下这段代码的意思:

自定义函数目的:返回一个指定长度的随机字符串。
chars_str:初始化长度为52位字符。
Mysql定义变量和我们平时使用的C或者Java不一样,因为人家毕竟也算一门语言,所以风格自然也有所变化。
对于一个变量的使用需要先用declarer声明一个变量

declare chars_str varchar(100) default

    1

然后就是一个while函数循环,通过concat()函数的拼接,返回一个指定长度n的串串。

接着继续创建一个自定义函数:

#这里我们又自定了一个函数,返回一个随机的部门号
create function rand_num( )
returns int(5)
begin
declare i int default 0;
set i = floor(10+rand()*500);
return i;
end $$

 #创建一个存储过程, 可以添加雇员
create procedure insert_emp(in start int(10),in max_num int(10))
begin
declare i int default 0;
#set autocommit =0 把autocommit设置成0
 #autocommit = 0 含义: 不要自动提交
 set autocommit = 0; #默认不提交sql语句
 repeat
 set i = i + 1;
 #通过前面写的函数随机产生字符串和部门编号,然后加入到emp表
 insert into emp values ((start+i) ,rand_string(6),'SALESMAN',0001,curdate(),2000,400,rand_num());
  until i = max_num
 end repeat;
 #commit整体提交所有sql语句,提高效率
   commit;
 end $$


执行:

call insert_emp(100001,8000000)$$

大约需要6-10分钟能执行完

四、快速生成批量测试数据

-- 创建一个临时内存表
set global log_bin_trust_function_creators=1;
DROP TABLE IF EXISTS `vote_recordss_memory`;
CREATE TABLE `vote_recordss_memory` (
    `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
    `user_id` varchar(20) NOT NULL DEFAULT '',
    `vote_num` int(10) unsigned NOT NULL DEFAULT '0',
    `group_id` int(10) unsigned NOT NULL DEFAULT '0',
    `status` tinyint(2) unsigned NOT NULL DEFAULT '1',
    `create_time` datetime NOT NULL DEFAULT '1971-01-01 01:01:01',
    PRIMARY KEY (`id`),
    KEY `index_user_id` (`user_id`) USING HASH
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
-- 创建一个普通表,用作模拟大数据的测试用例
DROP TABLE IF EXISTS `vote_records`;
CREATE TABLE `vote_records` (
    `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
    `user_id` varchar(20) NOT NULL DEFAULT '' COMMENT '用户Id',
    `vote_num` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '投票数',
    `group_id` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '用户组id 0-未激活用户 1-普通用户 2-vip用户 3-管理员用户',
    `status` tinyint(2) unsigned NOT NULL DEFAULT '1' COMMENT '状态 1-正常 2-已删除',
    `create_time` datetime  NOT NULL DEFAULT '1971-01-01 01:01:01' COMMENT '创建时间',
    PRIMARY KEY (`id`),
    KEY `index_user_id` (`user_id`) USING HASH COMMENT '用户ID哈希索引'
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='投票记录表';

-- 为了数据的随机性和真实性,我们需要创建一个可生成长度为n的随机字符串的函数。
-- 创建生成长度为n的随机字符串的函数
DELIMITER // -- 修改MySQL delimiter:'//'
DROP FUNCTION IF EXISTS `rand_strings` //
SET NAMES utf8 //
CREATE FUNCTION `rand_strings` (n INT) RETURNS VARCHAR(255) CHARSET 'utf8'
BEGIN 
    DECLARE char_str varchar(100) DEFAULT 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
    DECLARE return_str varchar(255) DEFAULT '';
    DECLARE i INT DEFAULT 0;
    WHILE i < n DO
        SET return_str = concat(return_str, substring(char_str, FLOOR(1 + RAND()*62), 1));
        SET i = i+1;
    END WHILE;
    RETURN return_str;
END //

 

-- 为了操作方便,我们再创建一个插入数据的存储过程
-- 创建插入数据的存储过程
DROP PROCEDURE IF EXISTS `insert_vote_recordss_memory` //
CREATE PROCEDURE `insert_vote_recordss_memory`(IN n INT)
BEGIN
    DECLARE i INT DEFAULT 1;
    DECLARE vote_num INT DEFAULT 0;
    DECLARE group_id INT DEFAULT 0;
    DECLARE status TINYINT DEFAULT 1;
    WHILE i < n DO
        SET vote_num = FLOOR(1 + RAND() * 10000);
        SET group_id = FLOOR(0 + RAND()*3);
        SET status = FLOOR(1 + RAND()*2);
        INSERT INTO `vote_recordss_memory` VALUES (NULL, rand_strings(20), vote_num, group_id, status, NOW());
        SET i = i + 1;
    END WHILE;
END //
DELIMITER ;  -- 改回默认的 MySQL delimiter:';'
-- 开始执行存储过程,等待生成数据(100W条)
-- 调用存储过程 生成100W条数据
CALL insert_vote_recordss_memory(10000000);
-- 查询内存表已生成记录(为了下步测试,目前仅生成了x条)
SELECT count(*) FROM `vote_recordss_memory`;
-- 把数据从内存表插入到普通表中(100w条数据ys就插入完了)
INSERT INTO vote_records SELECT * FROM `vote_recordss_memory`;
-- 查询普通表已的生成记录
SELECT count(*) FROM `vote_records`;
# 实时监控mysql的工具
https://blog.csdn.net/u013820054/article/details/54022456
---------+-------mysql-status-------+-----threads-----+-----slow-----+---bytes---+---------locks----------
time     |   QPS  TPS  ins  upd  del| run  con cre cac| sql  tmp Dtmp| recv  send| lockI lockW openT openF
---------+--------------------------+-----------------+--------------+-----------+------------------------
23:15:03 |     0 3738 3738    0    0|   3    3   0   0|   0    1    0|   0K    8K|     1     0   121    27
23:15:04 |     0 3781 3781    0    0|   3    3   0   0|   0    1    0|   0K    8K|     1     0   121    27
23:15:05 |     0 3733 3733    0    0|   3    3   0   0|   0    1    0|   0K    8K|     1     0   121    27
23:15:06 |     0 3737 3737    0    0|   3    3   0   0|   0    1    0|   0K    8K|     1     0   121    27
23:15:07 |     0 3576 3576    0    0|   3    3   0   0|   0    1    0|   0K    8K|     1     0   121    27
23:15:08 |     0 3589 3589    0    0|   2    3   1   1|   1    1    0|   0K    8K|     1     0   121    27
23:15:09 |     0 3548 3548    0    0|   2    3   0   1|   0    1    0|   0K    8K|     1     0   121    27
23:15:10 |     0 3791 3791    0    0|   2    3   0   1|   0    1    0|   0K    8K|     1     0   121    27
23:15:11 |     0 3861 3861    0    0|   2    3   0   1|   0    1    0|   0K    8K|     1     0   121    27
23:15:12 |     0 3892 3892    0    0|   2    3   0   1|   0    1    0|   0K    8K|     1     0   121    27
23:15:13 |     0 3857 3857    0    0|   2    3   0   1|   0    1    0|   0K    8K|     1     0   121    27
23:15:14 |     0 3900 3900    0    0|   2    3   0   1|   0    1    0|   0K    8K|     1     0   121    27
23:15:15 |     0 3701 3701    0    0|   2    3   0   1|   0    1    0|   0K    8K|     1     0   121    27
23:15:16 |     0 3856 3856    0    0|   2    3   0   1|   0    1    0|   0K    8K|     1     0   121    27
23:15:17 |     0 3166 3166    0    0|   2    3   0   1|   0    1    0|   0K    8K|     1     0   121    27
23:15:18 |     0 3865 3865    0    0|   2    3   0   1|   0    1    0|   0K    8K|     1     0   121    27
23:15:19 |     1 3853 3853    0    0|   3    3   0   1|   0    1    0|   0K    8K|     1     0   121    27
23:15:20 |     0 2864 2864    0    0|   2    3   0   1|   0    1    0|   0K    8K|     1     0   121    27
23:15:21 |     0 2927 2927    0    0|   2    3   0   1|   0    1    0|   0K    8K|     1     0   121    27
23:15:22 |     0 3820 3820    0    0|   2    3   0   1|   0    1    0|   0K    8K|     1     0   121    27

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值