mysql练手数据_MySQL如何按表创建千万级的测试数据,进行数据库压力测试和练习...

前言

笔者采用Intellij IDEA内置的数据库模块进行操作,也推荐大家使用专业点的IDE来操作数据库,通过命令行是很痛苦的。但是您要用命令行来操作以下内容,也是可以的,我会尽量照顾到您的使用习惯,但是不保证代码都能执行无误。

在学习完数据库及SQL的知识之后,想必各位同学都对数据库的性能优化有很深的兴趣,但是性能优化都是基于TB级的数据进行的。

UrY7Bj.png 什么是TB级的数据

今天我就带着大家来利用MySQL循环和存储过程做一个对特定表的创建千万行数据的实例

假设我们目前有这样一张表:

IZv6Vf.png users表

这张表有7个Columns,对应7个常见的简单的用户属性

为了照顾性少数者人群,把gender设为可变字符型较合适

随机生成数据

大家可能知道MySQL里面自带一个随机数生成的函数RAND()

它能生成0-1的浮点数

mAn6ry.png RAND函数生成随机数的语法

VJjUZv.png 生成的结果

随机生成给定数目的字符串

zqMRBr.png 随机生成给定数目的字符串

这里的循环采用

WHILE循环,循环里面采用字符串拼接函数

CONCAT

可复制的代码见下:

CREATE DEFINER =`您的数据库名`@`您的主机地址` FUNCTION `rand_string`(n INT)

RETURNS VARCHAR(255)

CHARSET utf8

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() * 80), 1));

SET i = i + 1;

END WHILE;

RETURN return_str;

END;

iaYJJj.png 生成的字符串实例

用户名和密码都可以通过以上介绍的方式添加

邮箱的添加方式

可直接在insert的value对应字段写上concat(rand_string(5), '@qq.com')既可

随机生成DATE和DATETIME类型

7JbiUn.png 随机生成DATE类型实例

关于LPAD函数,具体做为月份和日期的补零作用!生效如下介绍

Returns the string str:str, left-padded with the string padstr to a length of len characters. If str is longer than len:N, the return value is shortened to len characters.

mysql> SELECT LPAD(‘hi’,4,’??’);

-> ‘??hi’

mysql> SELECT LPAD(‘hi’,1,’??’);

-> ‘h’

可复制代码见下:

CREATE DEFINER =`您的数据库名`@`您的主机地址` FUNCTION `randDate`()

RETURNS VARCHAR(255)

CHARSET utf8

BEGIN

DECLARE aDate CHAR(10) DEFAULT '';

SET aDate = CONCAT(1949 + FLOOR((RAND() * 68)), '-', LPAD(FLOOR(1 + (RAND() * 12)), 2, 0), '-',

LPAD(FLOOR(3 + (RAND() * 8)), 2, 0));

RETURN aDate;

END;

imQjQn.png 运行实例

viEzQr.png 随机生成DATE类型

关于DATETIME类型

在刚刚写好的randDate上进行改造,加上一下这句话就好了

CONCAT(LPAD(FLOOR(0 + (RAND() * 23)),2,0),':',LPAD(FLOOR(0 + (RAND() * 60)),2,0),':',LPAD(FLOOR(0 + (RAND() * 60)),2,0))

ZjUvAn.png 随机生成DATETIME类型的代码

可复制版本如下:

CREATE DEFINER =`您的数据库名`@`您的主机地址` FUNCTION `randDateTime`()

RETURNS VARCHAR(255)

CHARSET utf8

BEGIN

DECLARE aDateTime CHAR(19) DEFAULT '';

SET aDateTime = CONCAT(CONCAT(1949 + FLOOR((RAND() * 68)), '-', LPAD(FLOOR(1 + (RAND() * 12)), 2, 0), '-',

LPAD(FLOOR(3 + (RAND() * 8)), 2, 0)),

' ',

CONCAT(LPAD(FLOOR(0 + (RAND() * 23)), 2, 0), ':', LPAD(FLOOR(0 + (RAND() * 60)), 2, 0), ':',

LPAD(FLOOR(0 + (RAND() * 60)), 2, 0))

);

RETURN aDateTime;

END;

执行效果如下:

baMrEj.png 执行过程

fMZF3i.png 执行效果

如果是时间戳类型,TIMESTAMP,那就是存一个特定范围的随机数我不再多做演示

gender性别的存法

用我们最上面写的那个随机字符串的方法进行改造,把chars_str的default内容改成“男,女等等”就好了,为避免文章冗长,不再做演示

将数据循环插入

我们的整个最主要的方法就是基于MySQL的存储过程

我向来不爱先讲定义,我给大家以实例导入

bANNre.png 定义将数据循环的存储过程

上图是一个10W次的插入实例,亲测耗时非常久,如果需要在30s内结束的,建议改成1w条,也够测试了

这里需要注意的是DELIMITER//和DELIMITER;两句, DELIMITER是分割符的意思,因为MySQL默认以”;”为分隔 符,如果我们没有声明分割符,那么编译器会把存储过程当成SQL语句进行处理,则存储过程的编译过程会报错,所以要事先用DELIMITER关键字申明当 前段分隔符,这样MySQL才会将”;”当做存储过程中的代码,不会执行这些代码,用完了之后要把分隔符还原。

也就是说如果你在命令行里面执行创建存储过程的语句时,是会出错的,因为sql遇到分号就结束了

我这里采用Intellij IDEA内置的DataGrip Console里面执行的,不用定义DELIMITER,在END后面加上;就好了,也推荐大家使用IDE来操作数据库,通过命令行是很痛苦的

可复制代码如下:

DELIMITER //

CREATE PROCEDURE insertManyUser()

BEGIN

DECLARE num INT;

SET num = 1;

WHILE num < 1000000 DO

INSERT INTO users (username, email, password, birthday, gender, avatar)

VALUES (rand_string(15), concat(rand_string(5), '@qq.com'), rand_string(32),

randDate(), 'male', NULL);

SET num = num + 1;

END WHILE;

END;

//

定义好存储过程insertManyUser之后还没有完,我们需要CALL它才可以

CALL insertManyUser;

然后等着慢慢的创建过程,测试用数据就到手了

r2UbQj.png 最终生成的测试用数据

测试数据的处理

1.清空数据库

不可回滚式:

DELETE FROM users;

可回滚式:

TRUNCATE TABLE users;

有外键存在的话,TRUNCATE不可用

2.MySQL修改存储过程

ALTER PROCEDURE

更改用CREATE PROCEDURE 建立的预先指定的存储过程,其不会影响相关存储过程或存储功能。

MySQL存储过程的删除

删除一个存储过程比较简单,和删除表一样:

DROP PROCEDURE

从MySQL的表格中删除一个或多个存储过程。

4.如果您需要改变FUNCTION返回值类型

可查看这篇文章

您在生成测试数据的时候遇到什么问题,都可以在下面留言和我交流,共同成长。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值