如何利用存储过程生成大批量测试数据

270 阅读4分钟

前言

想的再多,不如行动起来,大家好,我是啊Q,让我们徜徉在知识的海洋里吧。

一起“开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第19天, 点击查看活动详情


在上一篇《查询计划》我们使用了一个示例:假设我们有一个包含上亿条记录的图书馆书籍表,其中包含书籍的标题、作者、出版社、ISBN号等信息。我们想要查询标题以“三体”开头的所有书籍。以此示例我们分析了如何根据查询计划来分析我们的sql语句。 那么可能有小伙伴说,无证据无真相。那么今天我们就说说如何利用mysql的存储过程快速的创建大批量数据(ps:上一篇提到的是1亿,这里由于时间和机器的限制,所以我采取了生成一千万条数据以作为演示)。

步骤:

思路

  • 1.首先明确需求:创建一个包含以下字段(id,ISBN,作者,标题,出版社)的图书(book)表。
  • 其中id可以创建成自增主键。
  • ISBN我们就以11位不重复的【0-9】的随机数。
  • 作者我们从给定的 “张三,李四,王五”三位作者随机选定。
  • 标题 是我们的重点,因此我们尽量使其更加的随机,尽量不重复又能随机。那么我们的方案是:从给定的字符串“三体高性能并发编程三生三世和平复仇者海贼王火影”生成随机的随机长度的字符串。
  • 出版社我们从给定的:“电子工业出版社”,“机械工程出版社”两者中随机选择一个。

创建表

我们首先需要创建一个包含(id,ISBN,作者,标题,出版社)的图书(book)表。以下给出DDL语句。

drop table if exists book;

CREATE TABLE book(

  id int NOT NULL AUTO_INCREMENT PRIMARY KEY comment '主键', 

  ibsn tinyint not null comment 'IBSN',

  author varchar(30) comment '作者',

  title varchar(30) not null comment '标题', 

  press varchar(30) comment '出版社'

) comment '图书表';

创建一个随机字符串生成函数

该函数的参数:

  • n int : 生成给定长度为n的字符串
  • chars_str VARCHAR(255) : 给出随机字符串,生成的字符串字符来自于该字符串。
CREATE FUNCTION randStr(n INT, chars_str VARCHAR(255)) RETURNS VARCHAR(255) NO SQL
BEGIN
    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() * CHAR_LENGTH(chars_str)), 1));
        SET i = i + 1;
    END WHILE;
    RETURN return_str;
END;

测试:

#创建一个长度为10的随机字符串字符串
SELECT randStr(10, '三体我爱你'); 

创建存储过程

DELIMITER $$
CREATE PROCEDURE generate_book_data()
BEGIN
    DECLARE i INT DEFAULT 1;
    DECLARE ibsn BIGINT;
    DECLARE author VARCHAR(30);
    DECLARE title VARCHAR(30);
    DECLARE press VARCHAR(30);
    # 像执行多少就该这个数据就可以了
    WHILE i <= 10000000 DO
      	# 生成9位数的随机码
        SET ibsn = LPAD(FLOOR(RAND() * 100000000000), 11, '0');
      	# 从三个作者中选着一个
        SET author = CASE FLOOR(RAND() * 3) 
            WHEN 0 THEN '张三'
            WHEN 1 THEN '李四'
            ELSE '王五'
        END;
      	# 从“三体高性能并发编程三生三世和平复仇者海贼王火影”中随机生成字符串作为书名
        SET title = CONCAT(
            (SELECT SUBSTRING(randStr(FLOOR(RAND() * 6 + 1), '三体高性能并发编程三生三世和平复仇者海贼王火影'), 1, FLOOR(RAND() * 6 + 1))),
            '',
            (SELECT SUBSTRING(randStr(FLOOR(RAND() * 6 + 1), '三体高性能并发编程三生三世和平复仇者海贼王火影'), 1, FLOOR(RAND() * 6 + 1)))
        );
      	# 从 “电子工业出版社”,“机械工程出版社”两个出版社中随机选择一个
        SET press = CASE FLOOR(RAND() * 2)
            WHEN 0 THEN '电子工业出版社'
            ELSE '机械工程出版社'
        END;
        INSERT INTO book (ibsn, author, title, press) VALUES (ibsn, author, title, press);
        SET i = i + 1;
    END WHILE;
END $$
DELIMITER ;

下面就是我们生成的表的数据(ps:我生成一千万条数据大概花了1小时的时间)

ps:这里多出的数据是我开时测试生成未删除的数据。

删除存储过程

DROP PROCEDURE IF EXISTS generate_book_data;

释意

  • LPAD(): LPAD()是MySQL中的一个字符串函数,它的作用是在一个字符串左侧填充指定的字符,以达到指定的长度。例如,LPAD('123', 5, '0')的结果为'00123'。LPAD()函数的语法如下:LPAD(str, length, padstr)。其中,str为需要填充的字符串,length为填充后的长度,padstr为填充的字符。
  • RAND(): RAND()是MySQL中的一个数学函数,用于生成一个在0和1之间的随机数。例如,SELECT RAND()可以得到0.123456789这样的一个随机数。如果希望得到指定范围内的随机数,可以使用如下公式:RAND() * (max - min) + min,其中max和min分别为指定的最大值和最小值。
  • FLOOR(): FLOOR()是MySQL中的一个数学函数,用于向下取整。例如,FLOOR(3.1415)的结果为3。FLOOR()函数的语法如下:FLOOR(x),其中x为需要取整的数。
  • SUBSTRING(): SUBSTRING()是MySQL中的一个字符串函数,用于截取指定字符串的一部分。例如,SUBSTRING('Hello World', 2, 5)的结果为'ello '. SUBSTRING()函数的语法如下:SUBSTRING(str, start, length),其中str为需要截取的字符串,start为起始位置,length为截取的长度。
  • CONCAT(): CONCAT()是MySQL中的一个字符串函数,用于将多个字符串连接成一个字符串。例如,CONCAT('Hello', ' ', 'World')的结果为'Hello World'。CONCAT()函数的语法如下:CONCAT(str1, str2, ...),其中str1、str2等为需要连接的字符串。