MySQL批量插入测试数据的几种方式

专栏持续更新中:MySQL详解

前言

在开发过程中我们不管是用来测试性能还是在生产环境中页面展示好看一点, 又或者学习验证某一知识点经常需要一些测试数据, 这个时候如果手敲的话, 十行二十行还好, 多了就很死亡了, 接下来介绍两种常用的MySQL测试数据批量生成方式

  • 存储方式+函数
  • Navicat的数据生成

一、表

准备了两张表

  • 角色表:

    • id: 自增长
    • role_name: 随机字符串, 不允许重复
    • orders: 1-1000任意数字
  • 用户表:

    • id: 自增长
    • username: 随机字符串, 不允许重复
    • password: 随机字符串, 允许重复
    • role_id: 1-10w之间的任意数字
  • 建表语句:

sql 复制代码
CREATE TABLE `user` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `username` varchar(255) DEFAULT NULL COMMENT '用户名',
  `role_id` int(11) DEFAULT NULL COMMENT '角色id',
  `password` varchar(255) DEFAULT NULL COMMENT '密码',
  `salt` varchar(255) DEFAULT NULL COMMENT '盐',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

CREATE TABLE `role` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `role_name` varchar(255) DEFAULT NULL COMMENT '角色名',
  `orders` int(11) DEFAULT NULL COMMENT '排序权重\r\n',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

二、使用函数生成

通过存储过程快速插入, 通过函数保证数据不重复

设置允许创建函数

查看 MySQL是否允许创建函数

sql 复制代码
SHOW VARIABLES LIKE 'log_bin_trust_function_creators';

结果如图所示, 我们使用以下命令将创建函数功能打开(global-所有session都生效)

ini 复制代码
SET GLOBAL log_bin_trust_function_creators=1; 

这个时候再一次查询就会显示已打开

产生随机字符串

sql 复制代码
-- 随机产生字符串
DELIMITER $$
CREATE FUNCTION rand_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 $$

-- 假如要删除
-- drop function rand_string;

产生随机数字

sql 复制代码
-- 用于随机产生区间数字
DELIMITER $$
CREATE FUNCTION rand_num (from_num INT ,to_num INT) RETURNS INT(11)
BEGIN   
 DECLARE i INT DEFAULT 0;  
 SET i = FLOOR(from_num +RAND()*(to_num -from_num+1));
RETURN i;  
END$$

-- 假如要删除
-- drop function rand_num;

三、创建存储过程

插入角色表

sql 复制代码
-- 插入角色数据
DELIMITER $$
CREATE PROCEDURE insert_role(max_num INT)
BEGIN  
	DECLARE i INT DEFAULT 0;   
	SET autocommit = 0;    
	REPEAT  
		SET i = i + 1;  
		INSERT INTO role ( role_name,orders ) VALUES (rand_string(8),rand_num(1,5000)); 
		UNTIL i = max_num  
	END REPEAT;  
	COMMIT;  
END$$
 
-- 删除
-- DELIMITER ;
-- drop PROCEDURE insert_role;

插入用户表

sql 复制代码
-- 插入用户数据
DELIMITER $$
CREATE PROCEDURE  insert_user(START INT, max_num INT)
BEGIN  
	DECLARE i INT DEFAULT 0;   
	SET autocommit = 0;    
	REPEAT  
		SET i = i + 1;  
		INSERT INTO user (username, role_id, password, salt ) VALUES (rand_string(8) ,rand_num(1,100000), rand_string(10), rand_string(10));  
		UNTIL i = max_num  
	END REPEAT;  
	COMMIT;  
END$$
 
-- 删除
-- DELIMITER ;
-- drop PROCEDURE insert_user;

四、执行存储过程

scss 复制代码
-- 执行存储过程,往dept表添加10万条数据
CALL insert_role(100000); 

-- 执行存储过程,往emp表添加100万条数据,编号从100000开始
CALL insert_user(100000,1100000); 

小结

执行用时 10w数据差不多半分钟, 100w数据超过了20分钟, 同时 user的存储还卡死很久...

最后都成功新增, 但是自动递增值和行数不一致, 这个我也不知道因为啥...

数据展示

  • role表
  • user表

接下来我们使用 Navicat的数据生成

直接下一步, 然后选择对应的两张表生成行数和对应的生成规则, 基于之前的执行速度, 这次 role生成 1w数据, user生成 10w数据

对于字符串类型的字段, 我们可以设置他的随机数据生成器, 根据需要进行选择

例如角色名称, 选择了 职位名称 还可以进行是否包含 null 的选择等

但是如果是 姓名 那么就会让你选择是否唯一

数字的话会让你选择范围, 默认值等

等确定好了, 我们就可以点击右下角进行生成随机测试数据

通过结果可以看到生成十一万测试数据一共用时十一秒, 比第一种方法速度快很多, 推荐使用

相关推荐
秋天的一阵风1 分钟前
🔥 Network 里那坨 "data:" 我真看吐了,自制开源 Chrome 插件,AI 流式调试直接开挂
前端·人工智能·后端
ssshooter16 分钟前
为什么明明只有一个 12px 的小元素,父容器却有 63px 高?
前端·javascript·面试
IT_陈寒24 分钟前
Python的GIL让我深夜加班,这破锁到底怎么折腾的
前端·人工智能·后端
淡海水30 分钟前
15-07-YooAsset面试篇-Unity性能优化与内存管理
java·unity·面试·性能优化·c#·游戏引擎
snow@li37 分钟前
Java:跨平台原理与JDK、JRE、JVM全景深度解析
java·开发语言·jvm
覆东流41 分钟前
2.Java程序基础
java·开发语言·后端
snow@li1 小时前
SpringBoot:全套生命周期全景详解/应用级+Bean级
java·spring boot·rpc
ttwuai1 小时前
Go 后台定时任务启停不生效怎么办?先查调度同步链路
开发语言·后端·golang
love_muming1 小时前
二叉树操作全解析:从递归到层序遍历
java·数据结构·算法·二叉树
小的~~1 小时前
ThreadLocal 、InheritableThreadLocal 与 TransmittableThreadLocal 的进阶指南
java·开发语言