当我们在做一些性能或者特性测试对时候,往往需要生产大批量的数据进行测试。我们可以通过编写例如 bash、python 脚本等方式来实现,但是这种效率并不是很高。本文将利用 MySQL 的内存表及存储过程来高效的创建测试数据。
# 一、创建数据表
CREATE TABLE `contacts` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`f_name` varchar(20) NOT NULL,
`l_name` varchar(20) NOT NULL,
`phone_number` varchar(20) NOT NULL,
`create_time` datetime NOT NULL,
PRIMARY KEY (`id`)
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4;
# 二、 创建内存表
CREATE TABLE `contacts_memory` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`f_name` varchar(20) NOT NULL,
`l_name` varchar(20) NOT NULL,
`phone_number` varchar(20) NOT NULL,
`create_time` datetime NOT NULL,
PRIMARY KEY (`id`)
) ENGINE = MEMORY DEFAULT CHARSET = utf8mb4;
之所以使用 memory 存储引擎是因为其基于内存,速度快。利用存储引擎可以快速的往 MySQL 插入数据,增加生成数据的速度。
# 三、 存储过程
# 1. 创建随机字符串
CREATE DEFINER=`root`@`%` FUNCTION `rand_string`(n INT) RETURNS varchar(255) CHARSET utf8mb4
DETERMINISTIC
BEGIN
DECLARE chars_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(chars_str, FLOOR(1 + RAND() * 62), 1));
SET i = i + 1;
END WHILE;
RETURN return_str;
END
# 2.创建随机时间
CREATE DEFINER=`root`@`%` FUNCTION `rand_datatime`(start_datetime DATETIME,end_datetime DATETIME) RETURNS datetime
DETERMINISTIC
BEGIN
DECLARE sub INT DEFAULT 0;
DECLARE ret DATETIME;
SET sub = ABS(UNIX_TIMESTAMP(end_datetime) - UNIX_TIMESTAMP(start_datetime));
SET ret = DATE_ADD(start_datetime, INTERVAL FLOOR(1 + RAND() * (sub + 1)) SECOND);
RETURN ret;
END
Returns a random floating-point value v in the range 0 <= v < 1.0. To obtain a random integer R in the range i <= R < j, use the expression FLOOR(i + RAND() * (j − i))
因为 MYSQL RAND() 函数生成的随机数的返回是 0 <= v < 1.0 因此产生 i <= R <= j 需要使用 FLOOR(i + RAND() * (j − i + 1))
# 3. 生成测试数据存储过程
CREATE DEFINER=`root`@`%` PROCEDURE `add_contacts`(IN n int)
BEGIN
DECLARE i INT DEFAULT 1;
WHILE (i <= n) DO
INSERT INTO contacts_memory (f_name, l_name, phone_number, create_time) VALUES (rand_string(4), rand_string(8), FLOOR(RAND() * 10000000000000), rand_datatime("2019-12-01 00:00:00", '2020-01-31 23:59:59'));
SET i = i + 1;
END WHILE;
END
# 四、 调用存储过程生成测试数据
CALL add_contacts(1000000)
参数决定了需要生成多少条记录,当生成的记录过多时,可能会提示当前内存已满。
1114 - The table 'contacts_memory' is full, Time: 361.549000s
可以通过修改 max_heap_table_size
变量来控制内存表允许使用的变量大小。注意修改后只对之后创建的表,或者执行 ALTER TABLE 操作的表有效。
This variable sets the maximum size to which user-created MEMORY tables are permitted to grow. The value of the variable is used to calculate MEMORY table MAX_ROWS values. Setting this variable has no effect on any existing MEMORY table, unless the table is re-created with a statement such as CREATE TABLE or altered with ALTER TABLE or TRUNCATE TABLE. A server restart also sets the maximum size of existing MEMORY tables to the global max_heap_table_size value.
-- 查看当前内存表大小限制
SHOW variables like 'max_heap_table_size'
-- 重新设置当前内存表大小为 1GB
SET max_heap_table_size = 1024 * 1024 * 1024 * 1;
# 五、 将数据从内存表插入普通表
INSERT INTO contacts SELECT * FROM contacts_memory